Javascript Selenium WebDriver 等待元素显示

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25753014/
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-08-22 21:49:12  来源:igfitidea点击:

Selenium WebDriver wait till element is displayed

javascriptnode.jsselenium-webdriver

提问by Anand Sunderraman

I have searched on Google and the SO site and I get answers for JAVA but do not seem to get answers for node.js

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

I have a web app that takes time to load. I would selenium program to wait till the page is loaded and then perform some actions.

我有一个需要时间加载的网络应用程序。我会硒程序等到页面加载然后执行一些操作。

My current code is as follows

我目前的代码如下

//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();

The error I get is:

我得到的错误是:

    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)

回答by Anand Sunderraman

I stumbled upon an answer to my question

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

So to wait for an element to appear we have to:

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

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

回答by Joe Coder

You can register a listener on webdriver.waitby using then()

您可以使用以下方法注册侦听webdriver.waitthen()

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

回答by Alexander Mills

You don't need a custom function, you can just do this:

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

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

See the docs here:

请参阅此处的文档:

https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/until.html

https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/until.html

回答by QualiT

Try something like this:

尝试这样的事情:

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);
            }
        });
}

I adapted it slightly based on what I found here: Check if element exists - selenium / javascript / node-jsand it worked a charm.

我根据我在此处找到的内容对其进行了稍微调整:检查元素是否存在 - selenium / javascript / node-js并且它很有魅力。

回答by Christopher Grigg

This is the only thing that is working for me:

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

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

回答by James H

I came up with this approach because it maintains the chainable promise syntax so that I can write this: await waitFind(By.id('abc')).click()

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

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

回答by Tadeu Rangel

I usually use this way:

我通常使用这种方式:

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

回答by Tamil

Writing asynchronous functionto avoid this problem

异步函数避免这个问题

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