Implicit wait doesn't wait for the specified time causing the test to fail
ImplicitWait is not that effective when interacting with dynamic elements. Instead you need to replace implicit wait with explicit wait.
As an example, to retrieve the text from the element you have to induce WebDriverWait for the ElementIsVisible()
and you can use either of the following Locator Strategies:
Id
:string text = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementIsVisible(By.Id("finish"))).Text;
Assert.AreEqual("Hello World!", text);CssSelector:
string text = new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementIsVisible(By.CssSelector("div#finish"))).Text;
Assert.AreEqual("Hello World!", text);XPath:
string text = new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementIsVisible(By.XPath("//div[@id='div#finish']"))).Text;
Assert.AreEqual("Hello World!", text);
Selenium: How do I check if an element is on a page without use implicitlyWait?
You are already using findElements
, Note that findElements
will not throw any error even the passed locators is not available in HTMLDOM.
If it finds, it will return a list of web elements.
Now findElements
will try to POLL
the DOM
if it does not find anything immediately
, so that's the reason we use ImplicitWait.
Since you've mentioned that you do not wanna deal with ImplicitWait, and wants to grab the list of web elements, you either have to use ExplicitWait
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("css_selector_here")));
or
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.cssSelector("css_selector_here")));
But note that using explicit wait
, if elements are not found then You will likely get TimeOutException.
ExplicitWait:
Explicit waits are available to Selenium clients for imperative, procedural languages. They allow your code to halt program execution, or freeze the thread, until the condition you pass it resolves. The condition is called with a certain frequency until the timeout of the wait is elapsed. This means that for as long as the condition returns a falsy value, it will keep trying and waiting.
Since explicit waits allow you to wait for a condition to occur, they make a good fit for synchronizing the state between the browser and its DOM, and your WebDriver script.
ImplicitWait:
There is a second type of wait that is distinct from explicit wait called implicit wait. By implicitly waiting, WebDriver polls the DOM for a certain duration when trying to find any element. This can be useful when certain elements on the webpage are not available immediately and need some time to load.
Implicit waiting for elements to appear is disabled by default and will need to be manually enabled on a per-session basis. Mixing explicit waits and implicit waits will cause unintended consequences, namely waits sleeping for the maximum time even if the element is available or condition is true.
Warning: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example, setting an implicit wait of 10 seconds and an explicit wait of 15 seconds could cause a timeout to occur after 20 seconds.
An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0, meaning disabled. Once set, the implicit wait is set for the life of the session.
Official Docs
How to speed up Java Selenium Script,with minimum wait time
There are a few issues with your approach.
.implicitlyWait()
doesn't actually wait. It sets the timeout for the driver instance so you only need to set it once, not call it each time you want to wait.driver.findElement(...).isEmpty()
won't compile. Maybe you meant.findElements()
? Either way,.isEmpty()
vs.size() > 0
is going to be a negligible difference in speed.The main problem is that you have an implicit wait enabled when checking for something to NOT be present... especially a 10s wait. That means that each time an element is checked for, Selenium will wait for 10s even if it's expecting it to NOT be there.
You would be better served by turning off implicit wait (setting it to 0) and then do your existence check for elements you expect not to be there and then turn it back on. That will be 10s x # of existence checks you expect to not be there. Depending on how many existence checks you do, that could add up to a LOT of time. One downside of this, if you have a complex page with background processes, you will need to have a specific wait for the page (or portion of a page) to finish loading before checking for existence of elements with implicit wait off.
Side note... Selenium contributors have stated that implicit waits shouldn't be used period. Use WebDriverWait
instead but that's a whole other discussion.
Related Topics
Compare One String with Multiple Values in One Expression
What Is the Priority of Casting in Java
How to Tell If a Checkbox Is Selected in Selenium for Java
How to Convert List to JSON in Java
Nullpointerexception Through Auto-Boxing-Behavior of Java Ternary Operator
Hexadecimal to Integer in Java
"Non-Static Variable This Cannot Be Referenced from a Static Context" When Creating an Object
Passing Command Line Unicode Argument to Java Code
In Java 8, Is There a Bytestream Class
Java - Removing Duplicates in an Arraylist
Java Error: "Your Security Settings Have Blocked a Local Application from Running"
How to Pause and Resume a Thread in Java from Another Thread
Running a Java Program from Another Java Program