Selenium 2: Interrupt a page load
I have an issue when clicking on a button with Selenium 2.0b3 Java API with FirefoxDriver. Clicking on the button sends a form to the webserver and then browser goes to a new page as a result of the form submission.
When clicking on an element with element.click(), selenium is waiting for the browser to complete its operations. The browser waits until the page load is finished. But, sometimes the page load takes an enormous amount of time due to some advertisement requests.
How to work around the synchronisation between element.click() and the page load?
EDIT:
As explained in the WebEl开发者_运维问答ement javadoc:
Click this element. If this causes a new page to load, this method will block until the page has loaded.
Thanks
Try the beta feature only for Firefox listed in the last section of the firefoxdriver wiki page http://code.google.com/p/selenium/wiki/FirefoxDriver
You will need at least version 2.9, I recommend going with the latest 2.18 (2.0b3 is nearly a year old now!)
driver.get() is actually supposed to block until the page has finished loading. However sometimes it doesn't for example if JavaScript continues to load after the main HTML has loaded. In this case you'll sometimes get problems with clicking elements which have not appeared yet. You can either use WebDriverWait() to wait for the element to appear or increase the implicit wait time with:
driver.manage().timeouts().implicitlyWait(X, TimeUnit.SECONDS);
Here is the equivalent using WebDriverWait:
public void waitAndClick(WebDriver driver, By by) {
WebDriverWait wait = new WebDriverWait(driver, 10000);
Function<WebDriver, Boolean> waitForElement = new waitForElement(by);
wait.until(waitForElement);
Actions builder = new Actions(driver);
builder.click(driver.findElement(by)).perform();
}
And the waitForElement class:
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;
}
}
}
This is completely untested, but I thought I'd throw it out there for you. I thought that maybe you could work around it by building a custom action.
protected static void maybeAsyncClick(WebElement element, WebDriver driver)
{
Actions builder = new Actions(driver);
Action newClick = builder.moveToElement(element)
.click()
.build();
newClick.perform();
}
精彩评论