问题
Using a click()
implementation as follows, selenium will act as if it clicked the button, and will expect the next screen. But the webpage will not receive the click so the next screen will not pop up. I don't really understand what it is going on, maybe some of you encountered this issue before. Here's the click implementation:
public static void click(WebDriver driver, By by) {
new WebDriverWait(driver, DEFAULT_WAIT_FOR_ELEMENT)
.until(ExpectedConditions.elementToBeClickable(by))
.click();
}
Note: With a thread.sleep of 2 seconds, the button is indeed clicked. But as we all know, no one wants thread.sleep.
Note2: This issue will not happen as often on selenium 2.53
Note3: I'm currently using FireFox 49.0.1, with geckodriver 0.11.1
回答1:
I will give you some examples of how I have my wait implemented, perhaps it'll help you be more flexible.
I create a basic waitUntil method with a time parameter with a default time.
private void waitUntil(ExpectedCondition<WebElement> condition, Integer timeout) {
timeout = timeout != null ? timeout : 5;
WebDriverWait wait = new WebDriverWait(driver, timeout);
wait.until(condition);
}
Then I can use that helper method to create my wait for displayed or wait for clickable.
public Boolean waitForIsDisplayed(By locator, Integer... timeout) {
try {
waitUntil(ExpectedConditions.visibilityOfElementLocated(locator),
(timeout.length > 0 ? timeout[0] : null));
} catch (org.openqa.selenium.TimeoutException exception) {
return false;
}
return true;
}
You can do the similar with elementToBeClickable.
public Boolean waitForIsClickable(By locator, Integer... timeout) {
try {
waitUntil(ExpectedConditions.elementToBeClickable(locator),
(timeout.length > 0 ? timeout[0] : null));
} catch (org.openqa.selenium.TimeoutException exception) {
return false;
}
return true;
}
So we can make a click method to do our clicks to use this:
public void click(By locator) {
waitForIsClickable(locator);
driver.findElement(locator).click();
}
The reason I make the waitForIsDisplayed and waitForIsClickable is because I can reuse those in my assertions to make them less brittle.
assertTrue("Expected something to be found, but that something did not appear",
waitForIsDisplayed(locator));
Also, you can use the wait methods with the default time specified in the method (5 seconds), or can do:
waitForIsDisplayed(locator, 20);
That would wait a max of 20 seconds before throwing the exception.
回答2:
May be the reason is it didn't find element while it trying to check element clickable. As per implementation of elementToBeClickable
it assumes element present.
I would suggest to use QMetry Automation Framework for selenium webdriver. It provides extended webdriver and webelement so when you are using this framework you don't need to use such waits. In case you really required wait it provides element level methods for wait, for instance,
ele.waitForVisible()
来源:https://stackoverflow.com/questions/40110192/selenium-3-0-expectedconditions-issue