I am trying to perform a relatively simple task: to wait until a page redirect is complete. Just seen another answered question on the subject, where an advice is to wait for a particular text on the latter page to appear (IF I've got it right). If so, how about waiting till window.location
will be changed? Is it better? Worse? Less applicable? Any other idea? just curious, if needed, can mark this question as a community wiki.
Thanks!
You can program Selenium to wait for an element to be displayed, to change, or wait for specific text. When applications load elements or update the text of elements dynamically based on behavior or time, you can wait for text in Selenium until that change happens on the web page.
The respective command that takes you forward by one page on the browser's history can be written as: driver. navigate(). forward();
Implementations should wait until the condition evaluates to a value that is neither null nor false. Because of this contract, the return type must not be Void. If the condition does not become true within a certain time (as defined by the implementing class), this method will throw a non-specified Throwable .
Yes I've encountered this problem many times when using Selenium. There are 2 ways I worked around this problem. First off you can actually change the implicit wait time. For example given this piece of code:
Actions builder = new Actions( driver );
builder.click( driver.findElement( By.className("lala") ) ).perform();
This code will throw an exception if at the point it's called there are no elements that could be found to match the "lala" class. You can change this implicit wait time with:
driver.manage().timeouts().implicitlyWait( 5, TimeUnit.SECONDS );
This makes the driver poll for 5 seconds instead of failing straight away. If the element still can't be located after 5 seconds then the action will fail. Of course you can change that setting. I found that this method works okay the majority of the time. Most of the time you don't care about the whole page loading, just a certain part.
I also wrote another function which is GetElementByClassAndText which will do the same as implicit wait on an element except it also checks the containing text as well to allow finer detailing of what you want:
public static void waitAndClick( WebDriver driver, By by, String text ) {
WebDriverWait wait = new WebDriverWait( driver, 10000 );
Function<WebDriver, Boolean> waitForElement = new waitForElement( by );
wait.until( waitForElement );
for( WebElement e : driver.findElements( by ) ) {
if( e.getText().equals( text ) ) {
Actions builder = new Actions( driver );
builder.click( e ).perform();
return;
}
}
}
And the corresponding Function it uses:
public class waitForElement implements Function<WebDriver, Boolean> {
private final By by;
private String text = null;
public waitForElement( By by ) {
this.by = by;
}
public waitForElement( By by, String text ) {
this.by = by;
this.text = text;
}
@Override
public Boolean apply( WebDriver from ) {
if( this.text != null ) {
for( WebElement e : from.findElements( this.by ) ) {
if( e.getText().equals( this.text ) ) {
return Boolean.TRUE;
}
}
return Boolean.FALSE;
} else {
try {
from.findElement( this.by );
} catch( Exception e ) {
return Boolean.FALSE;
}
return Boolean.TRUE;
}
}
}
I realise that you're using Selenium in Ruby but hopefully some of my code (at least conceptually) is transferable and helpful to you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With