如何使用 WebDriverJS 捕获 Selenium 错误

How do I catch Selenium Errors using WebDriverJS

所以我正在使用 JavaScript Selenium 的实现,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";

以此为函数在wait函数中重复

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

我建议阅读 explicit and implicit waits. A summary, explicit waits will poll the website until a specific condition is filled, while an implicit wait is more general and will wait a specified amount of time for a command to execute. In your case, I would refer to this 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, and has an example implementation here。如果没有元素,它会return一个大小为0的列表。这样不会抛出异常,你可以通过列表的大小来判断它是否存在。

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

bagelmaker 关于使用 findElements 的建议不错。当我想检查一个元素是否存在而不是 fiddle 时,我通常会这样做。

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

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

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

您还可以在链式 "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');
}