【问题标题】:How do I catch Selenium Errors using WebDriverJS如何使用 WebDriverJS 捕获 Selenium 错误
【发布时间】:2015-04-22 13:40:58
【问题描述】:

所以我使用的是 Selenium 的 JavaScript 实现,WebDriverJS。与任何网络浏览器自动化一样,最大的障碍是让代码变慢足够长的时间以加载页面元素。我的解决方案是这样的:

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

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";

以this为函数在等待函数中重复

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

【问题讨论】:

    标签: javascript selenium selenium-webdriver try-catch


    【解决方案1】:

    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 失败则调用它。因为selenium-webdriver 使用promise 操作,所以这就是您必须捕获错误的方式。使用 try...catch 无法工作,因为 Selenium 不会立即开始工作;您要求 Selenium 处理 findElement 的工作将在未来未确定的时间执行。到那时,JavaScript 执行将移出您的try...catch

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

    【讨论】:

    • 非常感谢您的回答。您的错误处理解决方案正是我所需要的。
    • then语句中的null有什么作用?
    • then 的第一个参数通常是在 promise 成功解析时调用的回调。由于上面的演示无法成功,因此在那里进行回调是没有意义的。因此,使用null。它与function () {} 一样有效。
    【解决方案2】:

    您还可以在链式“catch”方法中捕获该错误:

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

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

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

    【讨论】:

      【解决方案3】:

      我建议阅读explicit and implicit waits。概括地说,显式等待将轮询网站,直到满足特定条件,而隐式等待更一般,将等待指定的时间量来执行命令。在你的情况下,我会参考这个previous question,它是通过使用解决的:

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

      driver.wait(function() {
          return driver.isElementPresent(locator);
      }, timeout);
      

      如果您需要任何澄清,请发表评论。

      编辑:

      我弄错了问题。捕获 NoSuchElementError 的另一种方法是使用方法 findElements,该方法记录在 here 中,并有一个示例实现 here。如果不存在元素,则返回一个大小为0的列表。这样就不会抛出异常,您可以通过列表的大小来判断它是否存在。

      我希望这是您问题的更好答案。

      【讨论】:

      • 如果元素不存在,选项 1 不会抛出错误吗?
      • 如果该选项在超时期间从未出现,那么它会抛出一个错误。这个想法是您可以将超时设置为等于 3000 之类的值,因此元素出现有 3 秒的缓冲区。
      • 对不起,我好像误解了你的问题,我已经编辑了它,所以它是一个完整的答案。
      猜你喜欢
      • 2015-09-29
      • 1970-01-01
      • 2018-09-05
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-13
      相关资源
      最近更新 更多