Using the solution provided by Mike Kwan may have an impact in overall testing performance, since the implicit wait will be used in all FindElement calls.
Many times you'll want the FindElement to fail right away when an element is not present (you're testing for a malformed page, missing elements, etc.). With the implicit wait these operations would wait for the whole timeout to expire before throwing the exception. The default implicit wait is set to 0 seconds.
I've written a little extension method to IWebDriver that adds a timeout (in seconds) parameter to the FindElement()
method. It's quite self-explanatory:
public static class WebDriverExtensions
{
public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutInSeconds)
{
if (timeoutInSeconds > 0)
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
return wait.Until(drv => drv.FindElement(by));
}
return driver.FindElement(by);
}
}
I didn't cache the WebDriverWait object as its creation is very cheap, this extension may be used simultaneously for different WebDriver objects, and I only do optimizations when ultimately needed.
Usage is straightforward:
var driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://localhost/mypage");
var btn = driver.FindElement(By.CssSelector("#login_button"));
btn.Click();
var employeeLabel = driver.FindElement(By.CssSelector("#VCC_VSL"), 10);
Assert.AreEqual("Employee", employeeLabel.Text);
driver.Close();
TL;DR: Always use explicit wait. Forget that implicit wait exists.
Here is a quick rundown on the differences between explicit and implicit wait:
Explicit wait:
- documented and defined behaviour.
- runs in the local part of selenium (in the language of your code).
- works on any condition you can think of.
- returns either success or timeout error.
- can define absence of element as success condition.
- can customize delay between retries and exceptions to ignore.
Implicit wait:
- undocumented and practically undefined behaviour.
- runs in the remote part of selenium (the part controlling the browser).
- only works on find element(s) methods.
- returns either element found or (after timeout) not found.
- if checking for absence of element must always wait until timeout.
- cannot be customized other than global timeout.
Code examples with explanation. First implicit wait:
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));
Now explicit wait:
WebDriver driver = new FirefoxDriver();
driver.get("http://somedomain/url_that_delays_loading");
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement myDynamicElement = wait.until(
ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));
Both code examples do the same thing. Find a certain element and give up if not found after 10 seconds. The implicit wait can do only this. It can only try to find an element with a timeout. The strength of explicit wait is that it can wait for all kinds of conditions. Also customize timeout and ignore certain exceptions.
Example of possible conditions: elementToBeClickable
, numberOfElementsToBeMoreThan
or invisibilityOf
. Here is a list of the built in expected conditions: https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html
More explanations:
The implicit wait timeout has effect only on findElement*
methods. If set then all findElement*
will "wait" for the set time before declaring that the element cannot be found.
How a findElement*
will wait is not defined. It depends on browser or operating system or version of selenium. Possible implementations are:
- repeatedly try to find element until timeout. return as soon as element is found.
- try to find element. wait until timeout. try again.
- wait until timeout. try to find element.
This list is gathered from observations and reading bug reports and cursory reading of selenium source code.
My conclusion: Implicit wait is bad. The capabilities are limited. The behaviour is undocumented and implementation dependent.
Explicit wait can do everything implicit wait can and more. The only disadvantage of explicit wait is a bit more verbose code. But that verbosity makes the code explicit. And explicit is better that implicit. Right?
Further reading:
Best Answer
For sure you can. We use Selenium a lot as an assistant in getting some datas from websites.
When you have a process involving multiple steps, including opening website, login, choosing 54 parameters and need only 1 human interaction (resolving a captcha, for example), Selenium can automate those boring tasks and let the user concentrate on the one which is important.
What we do here, is to make a Swing dialog with an input field to get what the user want to enter, then the actual form submission is performed by Selenium. You can do the same thing with links, and you can ask the user to select a link to click on, and perform the actual click with webdriver.
The
ExplicitWait
method ofAmith
is also a good one. You can focus on what you expect after the user has clicked, and wait until this condition is realized