【问题标题】:Selenium WebDriver wait till element is displayedSelenium WebDriver 等到元素显示
【发布时间】:2014-11-03 08:52:59
【问题描述】:

我在 Google 和 SO 网站上进行了搜索,我得到了 JAVA 的答案,但似乎没有得到 node.js 的答案

我有一个需要时间加载的网络应用程序。我希望 selenium 程序等到页面加载完毕,然后执行一些操作。

我目前的代码如下

//dependencies
var webdriver = require('selenium-webdriver'),
    util = require('util'),
    _ = require('underscore');

var driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build();
var branchName =  _.isUndefined(process.argv[3]) ? 'branch' : process.argv[3], 
    hostName = _.isUndefined(process.argv[2]) ? 'localhost' : process.argv[2],
    appTmpl = 'http://%s/%s',
    username = 'xxxx',
    password = 'xxxx';
var appUrl = util.format(appTmpl, hostName, branchName);

driver.get(appUrl);
driver.findElement(webdriver.By.name("username")).sendKeys(username);
driver.findElement(webdriver.By.name("password")).sendKeys(password);
driver.findElement(webdriver.By.name("login_button")).click();
driver.quit();

我得到的错误是:

    C:\Work\study\selenium\node_modules\selenium-webdriver\lib\webdriver\promise.js:1643
      throw error;
            ^
NoSuchElementError: no such element
  (Session info: chrome=37.0.2062.103)
  (Driver info: chromedriver=2.10.267521,platform=Windows NT 6.1 SP1 x86_64)
    at new bot.Error (C:\Work\study\selenium\node_modules\selenium-webdriver\lib\atoms\error.js:109:18)
    at Object.bot.response.checkResponse (C:\Work\study\selenium\node_modules\selenium-webdriver\lib\atoms\response.js:106:9)
    at C:\Work\study\selenium\node_modules\selenium-webdriver\lib\webdriver\webdriver.js:277:20
    at C:\Work\study\selenium\node_modules\selenium-webdriver\lib\goog\base.js:1243:15
    at webdriver.promise.ControlFlow.runInNewFrame_ (C:\Work\study\selenium\node_modules\selenium-webdriver\lib\webdriver\promise.js:1539:20)
    at notify (C:\Work\study\selenium\node_modules\selenium-webdriver\lib\webdriver\promise.js:362:12)
    at notifyAll (C:\Work\study\selenium\node_modules\selenium-webdriver\lib\webdriver\promise.js:331:7)
    at resolve (C:\Work\study\selenium\node_modules\selenium-webdriver\lib\webdriver\promise.js:309:7)
    at fulfill (C:\Work\study\selenium\node_modules\selenium-webdriver\lib\webdriver\promise.js:429:5)
    at C:\Work\study\selenium\node_modules\selenium-webdriver\lib\webdriver\promise.js:1406:10
==== async task ====
WebDriver.findElement(By.name("username"))
    at webdriver.WebDriver.schedule (C:\Work\study\selenium\node_modules\selenium-webdriver\lib\webdriver\webdriver.js:268:15)
    at webdriver.WebDriver.findElement (C:\Work\study\selenium\node_modules\selenium-webdriver\lib\webdriver\webdriver.js:711:17)
    at Object.<anonymous> (C:\Work\study\selenium\test.js:15:8)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)

【问题讨论】:

  • 您的网站是否处理 ajax 请求?如果是这样,您是否考虑过在 java 中使用 javascriptexecutor 类来检查请求的 node.js 标志?

标签: javascript node.js selenium-webdriver


【解决方案1】:

我偶然发现了我的问题的答案

所以要等待一个元素出现,我们必须:

driver.wait(function () {
    return driver.isElementPresent(webdriver.By.name("username"));
}, timeout);

【讨论】:

  • 感谢您的回答。
  • isElementPresent 函数在 3.0 中已被弃用,因此在较新的版本中将无法使用。
  • @jmreicha 你能解释一下新版本的工作原理吗?
  • @AnandSunderraman 下面使用elementLocated 函数的答案对我有用。
  • @jmreicha elementLocated 在微调器加载时被拦截,它试图在我的情况下单击按钮!
【解决方案2】:

你不需要自定义函数,你可以这样做:

let el = await driver.findElement(By.id(`import-file-acqId:${acqId}`));
await driver.wait(until.elementIsVisible(el),100);
await el.sendKeys(file);

请参阅文档here

【讨论】:

  • 这是一个最新且惯用的有效解决方案。应该投票得更高!
【解决方案3】:

您可以使用then()webdriver.wait 上注册一个监听器

driver.wait(until.elementLocated(By.name('username')), 5 * 1000).then(el => {
    el.sendKeys(username);
});

【讨论】:

  • 你能解释一下为什么你有5 * 10005000吗? (顺便说一句,我不是反对者...... :))
  • 这是处理毫秒时的常见模式。许多开发人员更喜欢以毫秒为单位的清晰度。
  • 这个对我有用,记得 const {until} = require('selenium-webdriver');之前
  • 注意:我想在显示按钮时单击它,但要使此解决方案起作用,我必须在单击它之前使用 then 方法中的 sleep 函数,例如显示后等待 1 秒:driver.sleep(1000).then(function() {el.click();});。您被检测为机器人的机会也会减少。
  • @baptx 理想情况下,您希望自动化在没有显式等待的情况下尽可能快地运行。您可以尝试 until.elementIsVisible() 或调用 driver.wait() 并传入自定义函数。见docs。在 Selenium 中避免 bot 检测涉及更多内容,因为您还必须更改用户代理和其他设置。
【解决方案4】:

试试这样的:

function isItThere(driver, element){

    driver.findElement(webdriver.By.id(element)).then(function(webElement) {
            console.log(element + ' exists');
        }, function(err) {
            if (err.state && err.state === 'no such element') {
                console.log(element + ' not found');
            } else {
                webdriver.promise.rejected(err);
            }
        });
}

我根据我在这里找到的内容稍微调整了它:Check if element exists - selenium / javascript / node-js,它很有魅力。

【讨论】:

    【解决方案5】:

    这是唯一对我有用的东西:

    const element = By.id('element');
    driver.wait(until.elementLocated(element));
    const whatElement = driver.findElement(element);
    driver.wait(until.elementIsVisible(whatElement), 5000).click();
    

    【讨论】:

      【解决方案6】:

      我一般是这样用的:

       var el = driver.wait(until.elementLocated(By.name('username')));
      el.click();
      

      【讨论】:

        【解决方案7】:

        编写异步函数来避免这个问题

        (async function() {
          let url = args[0];
          await driver.get(url);
          driver.quit();
        })();
        

        【讨论】:

          【解决方案8】:

          我想出了这种方法,因为它维护了可链接的 promise 语法,因此我可以这样写:await waitFind(By.id('abc')).click()

          const waitFind = (locator) => {
              return driver.findElement(async () => {
                  await driver.wait(until.elementLocated(locator));
                  return driver.findElement(locator);
              });
          }
          

          【讨论】:

          • 你能更精确一点吗?这如何纠正问题中遇到的错误?
          • @Alexandre 问题的答案是等待元素出现。其他答案提出了各种解决方案来做到这一点,但这个有保留从 findElement 返回的代理元素的好处。否则,返回的对象将是缺少 click() 和 sendKeys() 代理方法的 Promise。
          【解决方案9】:

          主要问题是 webdriver 认为元素已经存在,但还没有。我有一个解决方案,丑陋但有效。 webdriver think项出现后,尝试点击。 获取错误消息:

          StaleElementReferenceError: stale element reference: element is not attached to the page document  (Session info: chrome=83.0.4103.106)
          

          没问题,在循环中等待500ms,再次点击尝试。在我的情况下,尝试 5 次就足够了,大约 2-3 次点击就成功了。

          async clickonitem( driver, itemname ) {
              const strftime = require('strftime');
              var trycounter = 0;
              var timeout = 500;
              var success;
              do {
                try {
                  trycounter++;
                  success = true;
                  console.log( strftime('%F %T.%L'), "Finding #" + trycounter + " " + itemname );
                  var item = await driver.wait( until.elementLocated( By.xpath( '//input[@name="' + itemname +'"]' ) ), 
                                  timeout );
                  console.log( strftime('%F %T.%L'), "Found or Timeout #" + trycounter );
                  //await item.click();
                  await driver.wait( item.click(), 
                                  timeout );
                  console.log( strftime('%F %T.%L'), "Click #" + trycounter + " " + itemname );
                } 
                catch(err) {
                  success = false;
                  //this.log( "Error #" + trycounter + " " + itemname + "\n" +err );
                  this.log( strftime('%F %T.%L'), "Error #" + trycounter + " " + itemname + " waiting: " + timeout );
                  await wait( timeout );
                  continue;
                }
          
              } while( !success && trycounter < 5 );
          }       
                  async wait( ms ) {
                    return new Promise((resolve) => {
                      setTimeout(resolve, ms);
                    });
                  }
          
          clickonitem( driver, "login_button" );
          

          【讨论】:

            猜你喜欢
            • 2011-10-23
            • 1970-01-01
            • 1970-01-01
            • 2012-03-26
            • 1970-01-01
            • 2016-07-18
            • 1970-01-01
            • 2016-12-25
            • 1970-01-01
            相关资源
            最近更新 更多