等待元素更改其值(文本)

时间:2014-11-25 12:01:35

标签: javascript angularjs protractor

我在第三天和Protractor一起工作时,我总是在等待加载页面和显示元素方面遇到金砖墙。特别是这个测试案例变得丑陋,我想解决问题而不必依赖睡眠。

我目前“在AngularJS之外”

it('it should reflect in both the field and the title when the personnel name is changed', function() {
  var inputField, personnelHeader, personnelName;
  personnelName = element(By.css(".overlay.editnameoverlay")).click();
  personnelHeader = element(By.id("personnel_name_header"));
  inputField = element(By.css("input[name='newvalue']"));
  inputField.clear();
  inputField.sendKeys("Test 123");
  element(By.css("input[name='ok_button']")).click();
  // browser.driver.sleep(2000); This test only works with this sleep added
  browser.wait(function() {
    console.log("Waiting for header to change...");
    return personnelHeader.getText().then(function(text) {
      return text === "Test 123";
    });
  }, 5000);
  return expect(personnelHeader.getText()).toBe(personnelName.getText());
});

因此,此处的测试会更改输入字段中的名称。提交它并等待更改反映在模态的标题中。问题是如果没有browser.driver.sleep(2000),我会收到一条错误

Stacktrace:
     StaleElementReferenceError: stale element reference: element is not attached to the page document

在这种特殊情况下如何解决这个问题?

2 个答案:

答案 0 :(得分:12)

来自Expect Conditions的文档:

var EC = protractor.ExpectedConditions;
// Waits for the element with id 'abc' to contain the text 'foo'.
browser.wait(EC.textToBePresentInElement($('#abc'), 'foo'), 5000);

答案 1 :(得分:7)

当您使用量角器测试非角度页面时,您自己就是在等待元素准备好进行交互。

StaleElementReferenceError可能是最无用的硒错误,它发生在元素从DOM中删除但仍然以某种方式缓存时,我也suffered这个问题在使用Protractor启动时甚至是{{3}应该自动重试量角器侧。

我的解决方案是始终使用tried to convince waitReady()明确等待元素出现在页面上,browser.wait表示元素就绪,即:等待元素为准备互动:

    expect($('#login_field').waitReady()).toBeTruthy();

首先在代码中集成此代码段:custom function

不仅自定义waitReady()等待该元素,而且它还会吞下任何无关的无用的webdriver错误,如StaleElementReferenceError,只会重试直到找到该元素,否则它将超时。

因此waitReady()每个元素在互动之前,即在clear()sendKeys()click()之前......

// TODO: Move to Page Objects module
var personnelNameElm = $(".overlay.editnameoverlay");
var personnelHeaderElm = $("#personnel_name_header");
var inputFieldElm = $("input[name='newvalue']");
var okBtnElm = $("input[name='ok_button']");

it('it should reflect in both the field and the title when the ' +
    'personnel name is changed', function() {

  expect(personnelNameElm.waitReady()).toBeTruthy();
  personnelNameElm.click();
  expect(inputFieldElm.waitReady()).toBeTruthy();
  inputFieldElm.clear().sendKeys("Test 123");
  expect(okBtnElm.waitReady()).toBeTruthy();
  okBtnElm.click();

  browser.wait(function() {
    console.log("Waiting for header to change...");
    // Using waitReady() before getText() avoids Stale element errors
    return personnelHeaderElm.waitReady().then(function() {
      return personnelHeaderElm.getText().then(function(text) {
        return text === "Test 123";
      });
    });
  }, 5000);

  expect(personnelHeaderElm.getText()).toEqual(personnelNameElm.getText());
});