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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27126215/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 06:59:13  来源:igfitidea点击:

Wait for element to change its value(text)

javascriptangularjsprotractor

提问by CodePrimate

I'm on my third day working with Protractor and I'm constantly hitting bric walls in regards to waiting around for pages to load and elements to appear. This test case in particular has grown ugly and I would like to solve the issues without having to rely on sleeps.

我正在使用 Protractor 工作的第三天,我经常在等待页面加载和元素出现方面遇到困难。特别是这个测试用例变得丑陋,我想解决问题而不必依赖睡眠。

I am currently "outside of the land of AngularJS"

我目前“在 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());
});

So the test here changes the name in an input field. submits it and waits for the changes to become reflected in the header of the modal. The problem is that without the browser.driver.sleep(2000) I get an error saying

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

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

How do I go about solving this in this particular case?

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

回答by LeeGee

From the documentation for 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);

回答by Leo Gallucci

When you use Protractor to test for non-angular pages you're on your own regarding waiting for elements to be ready for interaction.

当您使用 Protractor 测试非角度页面时,您需要自己等待元素准备好进行交互。

StaleElementReferenceErroris probably the most useless selenium error, it happens when the element got removed from the DOM but is still cached somehow, I also sufferedthis problem when started with Protractor and even tried to convinceit should be automatically retried Protractor-side.

StaleElementReferenceError可能是最无用的 selenium 错误,它发生在元素从 DOM 中删除但仍以某种方式缓存时,我在开始使用量角器时也遇到了这个问题,甚至试图说服它应该在量角器端自动重试。

The solution for me is to always explicitly wait for an element to appear on the page using a custom functionwaitReady()that browser.waitfor elements ready, i.e: waits for the element to be ready for interaction:

对我来说,解决办法是始终明确等因素的页面上使用出现的自定义功能,waitReady()browser.wait对于元素就绪,即:为元素等待准备进行交互:

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

First integrate this snippet in your code: https://gist.github.com/elgalu/2939aad2b2e31418c1bb

首先将此代码段集成到您的代码中:https: //gist.github.com/elgalu/2939aad2b2e31418c1bb

Not only the custom waitReady()waits for the element but it also swallows any unrelated useless webdriver error like StaleElementReferenceErrorand will simply retry up until finding the element or it will timeout.

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

So waitReady()each element before interacting, i.e. before clear()or sendKeys()or click()...

所以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());
});