Selenium 隐式和显式等待,未找到超时异常元素

Posted

技术标签:

【中文标题】Selenium 隐式和显式等待,未找到超时异常元素【英文标题】:Selenium implicit and explicit wait, timeout exception element not found 【发布时间】:2018-05-20 07:09:31 【问题描述】:

我是 selenium 新手(但经验丰富的 java 开发人员)。

我正在使用类似下面的东西:

WebElement searchBasket = pDriver.findElement(By.xpath("//a[contains(.,'Search&Baskets')]"));
WebElement searchproduct = pDriver.findElement(By.xpath("//a[contains(.,'Search a product')]"));

//if search an agreement is not show up, then click on other menu, then click it back
pWait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(.,'Search&Baskets')]")));
pDriver.findElement(By.xpath("//a[contains(.,'Search&Baskets')]")).click();

// click on search an agreement
try 
    pWait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(.,'Search&Baskets')]")));
    action = new Actions(pDriver);
    action.moveToElement(searchBasket).build().perform();

    pWait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(.,'Search a product')]")));
    searchproduct.click();
 catch (TimeoutException e) 

pWait 在哪里:

WebDriverWait wait = new WebDriverWait(driver, 15);

但是,当我运行测试用例时,出现以下错误:

Unable to locate element: "method":"xpath","selector":"//a[contains(.,'Search&Baskets')]"
Command duration or timeout: 4 milliseconds

我认为它应该至少等待 15 秒才能抛出此异常。从上面的日志看来,它似乎只在 4 毫秒内引发了异常。 我可以在控制台上看到,一旦它到达那条线,它就会抛出异常。

我将隐式等待设置为 0 并使用显式等待。

我有什么遗漏吗?

此外,在显式和隐式等待中,是最多多少时间还是确切多少时间, 例如,如果我将隐式等待设置为 10 秒,那么这是否意味着等待确切的 10 秒或等待最多 10 秒(如果找到元素,则继续,即使元素 founf 在第 6 秒)

显式等待也一样吗?

请帮忙

【问题讨论】:

嗨,我尝试将隐式等待设置为 0,将显式等待时间设置为 10。它恰好在第 10 秒超时。此外,不建议同时使用隐式等待和显式等待。但这应该不是问题,因为您的隐式超时为 0 秒。如果在第 6 秒内找到元素,则将进行下一步。对于隐式和显式等待,它不会等待整个 10 秒。你能把整个代码贴在这里吗? 谢谢...更新了代码... 【参考方案1】:

让我们分析一下我们的代码中发生了什么。

我们定义了两个WebElementssearchBasketsearchproduct如下:

WebElement searchBasket = pDriver.findElement(By.xpath("//a[contains(.,'Search&Baskets')]"));
WebElement searchproduct = pDriver.findElement(By.xpath("//a[contains(.,'Search a product')]"));

我们没有尝试立即在我们的代码中使用这些 WebElement,所以没有影响

接下来,我们尝试 WebDriverWait 获取WebElement,如下所示:

pWait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(.,'Search&Baskets')]")));

同样,我们没有捕获结果的return type,所以有No Impact

现在,在try 块内,我们再次尝试了WebDriverWait

pWait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(.,'Search&Baskets')]")));

但同样,我们还没有捕获/执行结果的return type。这就是为什么我们继续前进的原因:

action.moveToElement(searchBasket).build().perform();

searchBasket 引用了我们之前存储的WebElement

WebElement searchBasket = pDriver.findElement(By.xpath("//a[contains(.,'Search&Baskets')]"));

因为第一个搜索结果(没有 WebDriverWait)可能根本没有返回任何 WebElement 并且返回了 Null

最后,报错的最重要因素无法定位元素:"method":"xpath","selector":"//a[contains(.,'Search&Baskets')]" 是 WebDriverWait 实例为 wait。而不是使用wait,我们一直尝试使用pWait

因此,由于所有这些原因,WebDriverWait 从未在我们的代码中正确实现。


混合 ImplicitWaitExplicitWait

Selenium Documentation 明确提及以下内容:

警告:不要混合隐式和显式等待。这样做可能会导致无法预测的等待时间。例如,设置 10 秒的隐式等待和 15 秒的显式等待,可能会导致 20 秒后发生超时。

【讨论】:

【参考方案2】:

ExpectedConditions.elementToBeClickable 在 EXISTING WebElement 上调用 isDisplayed()isEnabled() 方法。

您提供By 作为参数,这意味着驱动程序必须首先找到您的元素。它未能做到这一点。

使用wait 直到presenceOfElementLocatedBy(By by) 确保您的元素存在。

例子:

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfElementLocatedBy(By.xpath("//a[contains(.,'Search&Baskets')]")));
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(.,'Search&Baskets')]")));

【讨论】:

以上是关于Selenium 隐式和显式等待,未找到超时异常元素的主要内容,如果未能解决你的问题,请参考以下文章

爬虫之selenium和webdriver—基础:操作cookie和显式等待与隐式等待

Oracle sql中的隐式和显式数据类型转换有啥区别

activity的隐式和显式启动

C#接口的隐式和显式实现之间的区别[重复]

C#接口的隐式和显式实现

将隐式等待和显式等待结合在一起会导致意外的等待时间