Javascript 如何使用WebDriverJ捕捉Selenium错误

Javascript 如何使用WebDriverJ捕捉Selenium错误,javascript,selenium,selenium-webdriver,try-catch,Javascript,Selenium,Selenium Webdriver,Try Catch,所以我使用的是Selenium的JavaScript实现WebDriverJS。与任何web浏览器自动化一样,最大的障碍是让代码慢到足以加载页面元素的程度。我的解决办法是: 对于我想要与之交互的每个元素,我都有这样一个代码块 xpath = "//div[@id='gs_lc0']/input[@id='gbqfq']" driver.wait(function(){ return waitForElement(xPath,driver); }); try{ element =

所以我使用的是Selenium的JavaScript实现WebDriverJS。与任何web浏览器自动化一样,最大的障碍是让代码慢到足以加载页面元素的程度。我的解决办法是:

对于我想要与之交互的每个元素,我都有这样一个代码块

xpath = "//div[@id='gs_lc0']/input[@id='gbqfq']"
driver.wait(function(){
    return waitForElement(xPath,driver);
});
try{
    element = driver.findElement(webdriver.By.xpath(xPath));
}catch(e){
    console.log("Wait Function False Positive")
}
element.sendKeys("Let Me Google That For You\n";
在等待函数中重复此函数

var waitForElement = function(path, driver){
    console.log("try: " + path)
    try{
        driver.findElement(webdriver.By.xpath(path));
    }catch (e){
        console.log("FAILURE")
        return false;
    }
    console.log("SUCCESS")
    return true;
}
现在,这个代码有时会工作,但有时不会。我支持等待功能根本不起作用,我只是得到了幸运的网页加载时间。所以为了测试这个理论,我在代码块中添加了try函数,我甚至无法捕获“NoSuchElementError”。因此,我的问题主要是,是否有其他方法来形成tryCatch函数,以便捕获这些错误

如果我想要完整的复制,我的代码的头部看起来也是这样

var webdriver = require('selenium-webdriver'), element

var driver = new webdriver.Builder().
    withCapabilities(webdriver.Capabilities.chrome()).
    build();

driver.get('google.com');

我建议你仔细阅读一下。摘要、显式等待将轮询网站,直到满足特定条件为止,而隐式等待更一般,将等待指定的时间执行命令。在您的情况下,我将引用以下内容:

driver.wait(function() {
    return driver.findElement(webdriver.By.xpath(xPath)).isDisplayed();
}, timeout);

driver.wait(function() {
    return driver.isElementPresent(locator);
}, timeout);
如果您需要任何澄清,请发表评论

编辑:

我误解了这个问题。捕获NoTouchElementError的另一种方法是使用方法
findelelements
,该方法已被记录,并有一个示例实现。如果不存在元素,它将返回大小为0的列表。这样,就不会抛出异常,您可以通过列表的大小来确定它是否存在


我希望这是对你的问题的一个更好的回答。

bagelmaker建议使用
findElements
。当我想检查一个元素是否存在而不是处理异常时,通常就是这样做的

但是,为了完整起见,下面是如何处理元素不存在时生成的错误:

var webdriver = require('selenium-webdriver');

var driver = new webdriver.Builder().
    withCapabilities(webdriver.Capabilities.chrome()).
    build();

driver.get('http://www.google.com');

driver.findElement(webdriver.By.id("fofofo")).then(null, function (err) {
    if (err.name === "NoSuchElementError")
        console.log("Element was missing!");
});

driver.quit();
then
的第二个参数是一个errback,如果
findElement
失败,则调用该参数。因为
seleniumwebdriver
是以承诺的方式操作的,所以您必须这样捕捉错误。使用
try…catch
无法工作,因为Selenium没有立即开始工作;您要求Selenium在
findElement
中执行的工作将在将来的不确定时间执行。到那时,JavaScript执行将从您的
try…catch
中移出


上面的代码搜索
id
值为
fofofofo
的元素,该元素不存在且失败。

您也可以通过链式“catch”方法捕获该错误:

如果您使用的是async/await,则可以执行以下操作:

try {
  await driver.findElement(webdriver.By.id("fofofo"));
  // do some task
}
catch (e) {
  if (e.name === 'NoSuchElementError')
    console.log('Element not found');
}

如果元素不存在,选项1不会抛出错误吗?如果该选项在超时期间从未出现,那么它会抛出错误。我们的想法是,您可以将timeout设置为3000左右,因此有一个3秒的缓冲区用于显示元素。抱歉,看起来我误解了您的问题,我已对其进行了编辑,使其成为完整的答案。非常感谢您的回答。您的错误处理解决方案正是我所需要的。then语句中null的用途是什么?
then
的第一个参数通常是在承诺成功解析时调用的回调。由于上面的演示无法成功,因此没有必要在那里进行回调。因此,使用了
null
。它同样适用于
函数(){}
try {
  await driver.findElement(webdriver.By.id("fofofo"));
  // do some task
}
catch (e) {
  if (e.name === 'NoSuchElementError')
    console.log('Element not found');
}