I need to change timeout for waiting particular webElements. For all of others default is pretty fine. Default timeout could be changed in settings:
timeout.wait.element=10
How to change timeout only for given elements?
For setting specific timeout on element you can use
textField.setWaitTimeout(10);
textField.input("TEXT");
But if you also has some waiting criteria and want to do something after it becomes true you can use
String text = textField.wait(w -> w.getText(), t -> t.equals("test"), 10);
or textField.wait(w -> w.getText().equals("test"), 10); if you just want to wait something
For setting specific implicit timeout on element you can use #WaitTimeout(sec)
#WaitTimeout(sec) — set sec seconds implicit wait for the element
or if you just want to wait until element is present in DOM:
someWebElement.waitFor(10).displayed();
Related
I'm trying to click a specific link in the web page with specific text.
However, if the link is not present, it takes 1 minute before it prints out element is not found. How do I reduce this time for faster execution?
try{
if (!driver.findElements(By.xpath("//a[text()='specifictext']/#href")).isEmpty())
{
By loadMoreComment=By.linkText("specifictext");
driver.findElement(loadMoreComment).click();
}
}
catch (NoSuchElementException e)
{
logger.warn("Specific text not found");
}
That would only happen because of implicit waits. Look at below definition
Implicit Waits
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. Once set, the implicit wait is set for the life of the WebDriver object instance.
So you should lower that implicit wait if you want an early failure
driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
The above call before your code, will ensure the failure happens within 2 seconds
Use Implicit wait to reduce tag waiting time.
Implicit waits are used to provide a waiting time (say 30 seconds)
between each consecutive test steps across the entire test script or
program. Next step only executed when the 30 Seconds (or whatever time
is given is elapsed) after execution of previous step.
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
Currently I wait for an element to appear like this:
let populated = GREYCondition(name: "Wait for UICollectionView to populate", block: { _ in
var errorOrNil: NSError?
EarlGrey().selectElementWithMatcher(collectionViewMatcher)
.assertWithMatcher(grey_notNil(), error: &errorOrNil)
let success = (errorOrNil == nil)
return success
}).waitWithTimeout(20.0)
GREYAssertTrue(populated, reason: "Failed to populate UICollectionView in 20 seconds")
Which polls constantly for 20 seconds for collection view to populate. Is there a better, non-polling way of achieving this?
EarlGrey recommends using its synchronization for waiting for elements rather than using sleeps or conditional checks like waits wherever possible.
EarlGrey has a variable kGREYConfigKeyInteractionTimeoutDuration value in GREYConfiguration that is set to 30 seconds and states -
* Configuration that holds timeout duration (in seconds) for action and assertions. Actions or
* assertions that are not scheduled within this time will fail due to timeout.
Since you're waiting for 20 seconds for your check, you can instead simply change it to -
EarlGrey().selectElementWithMatcher(collectionViewMatcher)
.assertWithMatcher(grey_notNil(), error: &errorOrNil)
and it'll be populated without a timeout.
I like to connect Earl Grey with basic XCTest and I've come up with this simple solution to problem of waiting for elements:
app.webViews.buttons["logout()"].waitForExistence(timeout: 5)
app.webViews.buttons["logout()"].tap()
Implicit Wait : If wait is set, it will wait for specified amount of time for each findElement/findElements call. It will throw an exception if action is not complete.
Assume we set implicit wait to 10 secs. My question is will selenium move on to next step if findElement action is complete before 10 secs?
Yes. Setting implicit wait causes the driver object to wait for the set time if the element it is looking for is not found immediately. The driver object keeps polling the DOM every 500 milliseconds until it finds the element or the time-out expires.
This is the explanation from official Selenium documentation page:
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. Once set, the
implicit wait is set for the life of the WebDriver object instance.
So, to answer your question in short, yes it continues with executing next steps as soon as it finds the element(s) it is looking for. You may also understand that to be the case from a simple experiment like #sircapsalot has shown in his answer.
Answer:
Yes. It will continue with the next step if it finds the element before the implicit timeout is hit.
Proof of concept:
#Test
public void test29800926() {
driver.get("http://ddavison.io/tests/getting-started-with-selenium.htm");
driver.manage().timeouts().implicitlyWait(30000, TimeUnit.MILLISECONDS);
System.out.println(driver.findElement(By.id("click")).getText());
}
Instead of waiting the total of 30 seconds that I set the implicit wait to (30000ms / 1000 = 30sec), it found it immediately and continued to print the text of the element.
Does Selenium implicit wait always take the entire wait time or can it finish sooner? If I set the implicit wait to 10 seconds, could a call to .findElement finish in a few seconds or would it always take the entire 10 seconds?
This page implies that it waits the full 10 seconds, which is very confusing because its not what the javadoc implies.
The following code comment from WebDriver.java implies that its a polling action which can finish sooner than the implicit timeout is defined at. BUT, the last sentence in the comment really throws a wrench into that belief and makes me not totally sure about it. If it is actually polling, then how would it "adversely affect test time", since it wouldn't go the entire implicit wait duration?
/**
* from WebDriver.java
* Specifies the amount of time the driver should wait when searching for an element if
* it is not immediately present.
* <p/>
* When searching for a single element, the driver should poll the page until the
* element has been found, or this timeout expires before throwing a
* {#link NoSuchElementException}. When searching for multiple elements, the driver
* should poll the page until at least one element has been found or this timeout has
* expired.
* <p/>
* Increasing the implicit wait timeout should be used judiciously as it will have an
* adverse effect on test run time, especially when used with slower location
* strategies like XPath.
*
* #param time The amount of time to wait.
* #param unit The unit of measure for {#code time}.
* #return A self reference.
*/
Timeouts implicitlyWait(long time, TimeUnit unit);
Also, if anyone can provide information on how often the default "polling" occurs?
It can finish once it was able to find the element. If not it does throws the error and stops. The poll time is again very specific to the driver implementation ( not Java bindings , but the driver part, example: FireFox extension, Safari Extension etc.)
As I have mentioned here, these are very specific to the driver implementation. All driver related calls goes via execute method.
I'm putting up the gist over of the execute method (you can find the full source here):
protected Response execute(String driverCommand, Map<String, ?> parameters) {
Command command = new Command(sessionId, driverCommand, parameters);
Response response;
long start = System.currentTimeMillis();
String currentName = Thread.currentThread().getName();
Thread.currentThread().setName(
String.format("Forwarding %s on session %s to remote", driverCommand, sessionId));
try {
log(sessionId, command.getName(), command, When.BEFORE);
response = executor.execute(command);
log(sessionId, command.getName(), command, When.AFTER);
if (response == null) {
return null;
}
//other codes
}
The line:
response = executor.execute(command);
says the whole story. executor is of type CommandExecutor, so all calls goes to the specific driver class like ChromeCommandExecutor,SafariDriverCommandExecutor, which has their own handling.
So the polling is upto the driver implementation.
If you want to specify the polling time, then you should probably start using Explicit Waits.
As mentioned the code comment:
* When searching for a single element, the driver should poll the page until the
* element has been found, or this timeout expires before throwing a
* {#link NoSuchElementException}.
Its going to wait till that element present, or timeout occurs.
For example, If you set Implicit wait as 10 seconds, .findElement is going to wait maximum of 10 seconds for that element. Suppose that element available in the DOM in 5 seconds, then it will come out of "wait" and start executing next step.
Hope this clarifies.
To my knowledge polling period is not 0.5 seconds with implicit wait. It is the case with explicit wait. Explicit wait polls the DOM every 500ms. Implicit wait, if the element is not found on page load waits for the specified time and then checks again after time is run out. If not found it throws an error
I use Selenium and PHPUnit. In my testcases, I use
PHPUnit_Extensions_SeleniumTestCase::waitForElementPresent($xpath);
to wait for some time until element specified by $xpath becomes present. Is there any way to change the maximum time of waiting?
waitForElementPresent() takes two arguments. The first one is the locator and the other is Timeout in miliseconds.
Example :
waitForElementPresent("Your xpath","80000").
This will wait for the given xpath for 80 seconds.