javascript - Selenium-webdriver JS - 如何等到元素可见

标签 javascript selenium selenium-webdriver xpath webdriver

使用 selenium-webdriver ( api docs here ),您如何等待元素可见?

我有以下功能,是一组自制测试助手的一部分,第一个有效但第二个失败(例如,它超时等待并且元素可见,即使它存在 - 已确认通过第一个有效的功能 - 并且是可见的 - 正如所有可以想象的页面 html/css/js 的测试和检查所证实的那样。

他们在这里:

/**
 * Wait for an element to exist
 * 
 * @param  {object} locator
 * @param  {int} timeout (ms)
 * 
 * @return {Promise<element>}
 */
// !! THIS WORKS OK
exports.waitForElement = function (locator, timeout) {
  var waitTimeout = timeout || DEFAULT_TIMEOUT;

  return this.wait(until.elementLocated(locator), waitTimeout)
    .then(() => {

        return this.findElement(locator);
      });
};


/**
 * Wait for an element to exist and then wait for it to be visible
 *
 * IMPORTANT: this is probable what you want to use instead of
 *   waitForVisibleElement most of the time.
 * 
 * @param  {hash} locator
 * @param  {number} timeout
 * 
 * @return {Promise<element>}
 */
// !! THIS FAILS TO WORK AS EXPECTED
exports.waitForVisibleElement = function (locator, timeout) {
  var waitTimeout = timeout || DEFAULT_TIMEOUT;

  return this.waitForElement(locator, waitTimeout) 
    .then(el => {
      console.log('--- element found:', el);
      return this.wait(until.elementIsVisible(el), waitTimeout)

        .then(() => {
          console.log('--- element visible!');
          // this is to make sure we are returning the same kind of
          // promise as waitForElement
          return this.findElement(locator);
        });

    });
};

...我在多个上下文中进行了测试,所以除了 waitForVisibleElement 中的代码之外没有其他问题的原因,但我似乎找不到它不起作用的任何原因!


作为澄清,该代码的 this 最终成为 webdriver 实例(new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build( )) 在 augment 方法 monkeypatches 给定的 webdriver 对象之后...可能是一个有问题的设计模式,但这里没有我的问题的原因:)


更新:显然这只发生在 XPath 定位器上,比如 { xpath: '//*[contains(text(), "first name")]' } ...并不是说它现在更有意义了。此外,Firefox 也一样,所以它不是奇怪的 chrome-webdriver 东西......

最佳答案

这很可能是 Promise 问题。 试试这个:

exports.waitForElement = function (locator, timeout) {
  var timeout = timeout || DEFAULT_TIMEOUT;
  return this.wait(until.elementLocated(locator), timeout);
};

exports.waitForVisibleElement = function (locator, timeout) {
  var timeout = timeout || DEFAULT_TIMEOUT;
  var element = this.wait(until.elementLocated(locator), timeout);
  return this.wait(new until.WebElementCondition('for element to be visible ' + locator, function() {
    return element.isDisplayed().then(v => v ? element : null);
  }), timeout);
};

用法:

driver.get("...");

driver.waitForElement(By.id("..."), 2000).getText().then(function(text){
  console.log(text);
});

driver.waitForVisibleElement(By.id("..."), 2000).getText().then(function(text){
  console.log(text);
});

关于javascript - Selenium-webdriver JS - 如何等到元素可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36309529/

相关文章:

python - Selenium 缺少 'JSESSIONID' 的 cookie 的可能原因是什么?

java - 如何通过在 Selenium WebDriver 中搜索文本来访问链接?

java - 在 selenium webdriver 中运行 moveToElement() 方法时出错?

Javascript 仅使用一个查询字符串刷新

javascript - li onClick 功能不起作用

javascript - 使用复选框和javascript动态删除表格行

java - 为什么控制台窗口仍然输出 'UnhandledAlertException'?

javascript - Like Unlike 切换按钮与 jQuery 的 AJAX

c# - 如何在运行 InternetExplorerDriver Selenium 测试后终止 IEDriverServer.exe 控制台窗口

c# - Selenium 和 C# 中的 ChromeOptions 和 DesiredCapabilities 关系