我试图通过使用 webdriver wait 单击页面上可见的按钮,但 webdriver 只能在我将
Thread.sleep
添加到代码。在执行我的代码之前,我还检查了按钮以查看它是否可见 (True),然后它又
返回 = true
。
//按钮可见性检查:
List<WebElement> signOutList = driver.findElements(.xpath(".//*[starts-with(@id,'fulfillment-time-type-section-')]/div[2]//button"));
Assert.assertTrue(signOutList.size() > 0);
//下面的代码没有点击按钮
By timeDropdownButton = By.xpath(".//*[starts-with(@id,'fulfillment-time-type-section-')]/div[2]//button");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.elementToBeClickable(timeDropdownButton));
myDynamicElement.click();
//下面的代码确实点击了按钮:
Thread.sleep(500);
By timeDropdownButton = By.xpath(".//*[starts-with(@id,'fulfillment-time-type-section-')]/div[2]//button");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.elementToBeClickable(timeDropdownButton));
myDynamicElement.click();
请注意,我还尝试使用 JS 代码和 WebDriver 操作等点击按钮
我不知道为什么 'Wait Clickable' 只有在我与 'Thread.sleep' 结合使用时才有效?
最佳答案
一般情况下,您希望在测试中尽可能避免使用 Thread.sleep
。仅仅通过一些测试,它可能看起来并不那么重要,但它们的使用中存在很多固有的问题。首先,如果你有一堆测试,测试套件的运行时间会变得难以管理。其次,他们有时还不够。例如,等待 500 毫秒对于一般的生产机器可能就足够了,但如果 Web 服务器负载很重或在测试环境中,则可能需要 750 毫秒才能准备就绪。然后你正在处理非确定性故障。最好使用像 WebDriverWait
这样的结构,并给它们一个合理的(但过于慷慨的)最大值,这样您就不必等待超过必要的时间,但如果它失败,则意味着有严重的事情被测环境错误。
这里的必胜客网站也大量使用异步 java 脚本和 float 面板等。在使用 Selenium 时,所有这些都需要多加小心,因为元素在与它们交互之前需要准备好,但它们通常已经在 DOM 中了。这意味着默认情况下,Selenium 可能会在 JavaScript 完成之前快速找到它们,并且它们实际上并未处于准备好使用的状态。您将希望像您已经尝试的那样使用 ExpectedConditions。您一直遇到麻烦的按钮需要等待 JavaScript 完成,这已经被建议但它不需要在页面加载时而是在单击按钮之前。在我的机器上运行的示例:
@Test
public void foo() {
WebDriver driver = new FirefoxDriver();
driver.manage()
.window()
.maximize();
// Move through the page to the point you are interested in
driver.get("https://www.pizzahut.co.uk/");
waitForElement(driver, By.cssSelector(".hidden-xs [title='Pizza']")).click();
waitForElement(driver, By.cssSelector("form[action='/menu/startyourorder']")).submit();
WebElement postElement = waitForElement(driver, By.id("ajax-postcode-txt"));
postElement.sendKeys("TS1 4AG" + Keys.ENTER);
// Wait for the java script to finish executing
waitForJavaScript(driver);
// Finally you should be able to click on the link
waitForElement(driver, By.partialLinkText("Start Your Order")).click();
// continue on ... then quit the driver
driver.quit();
}
private WebElement waitForElement(WebDriver driver, By locator) {
return new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(locator));
}
private void waitForJavaScript(WebDriver driver) {
new WebDriverWait(driver, 10).until(new Predicate<WebDriver>() {
public boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript("return document.readyState")
.equals("complete");
}
}
);
}
在 WebDriverWait 中,给定的 int 参数是它将继续尝试给定检查的秒数。如果它达到设定的数量(在上面的示例中为 10
秒),它将抛出一个 TimeoutException
。
关于java - WebDriver Wait '.until(ExpectedConditions.elementToBeClickable' 仅在我将 Thread.sleep(500) 添加到代码时有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38528920/