Skip to content

Instantly share code, notes, and snippets.

@richmondwang
Last active March 16, 2022 14:20
Show Gist options
  • Save richmondwang/b32079d148009f73ea05 to your computer and use it in GitHub Desktop.
Save richmondwang/b32079d148009f73ea05 to your computer and use it in GitHub Desktop.
Selenium. Methods for waiting for load and reload.
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.pagefactory.FieldDecorator;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
import xxx.CustomFieldDecorator;
import xxx.CustomElementLocatorFactory;
import java.rmi.UnexpectedException;
import java.util.UUID;
public abstract class AbstractDocument {
protected final WebDriver driver;
protected final FieldDecorator decorator;
private String loadMarkerId;
public AbstractDocument(WebDriver driver, String prefix) {
this.driver = driver;
this.decorator = new CustomFieldDecorator(
new CustomElementLocatorFactory(driver, prefix));
}
public void waitForLoad() throws InterruptedException { this.waitForLoad(null); }
// will wait for page load and javascript code execution
public void waitForLoad(Integer waitAfterLoad) throws InterruptedException {
new WebDriverWait(driver, 10).until((ExpectedCondition<Boolean>) wd ->
((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
this.createLoadMarker();
// allow for the javascripts to execute so we can right away findElement after this void
if (waitAfterLoad != null)
Thread.sleep(waitAfterLoad);
}
private void waitInteractive() throws InterruptedException {
// waits for the page to be at least 'interactive' - body DOM is present but not all element necessarily
new WebDriverWait(driver, 10).until((ExpectedCondition<Boolean>) wd ->
((JavascriptExecutor) wd).executeScript("return document.readyState")
.toString().matches("interactive|complete"));
}
/**
* Waits for the page to unload.
* @throws UnexpectedException
*/
public void waitForUnload() throws InterruptedException, UnexpectedException { this.waitForUnload(null); }
/**
* Waits for the page to unload.
*
* @param waitAfterUnload Milliseconds to wait after unload.
* @throws UnexpectedException
*/
public void waitForUnload(Integer waitAfterUnload) throws InterruptedException, UnexpectedException {
if (this.loadMarkerId == null)
throw new UnexpectedException("Expected loader marker not initialized. Please use page.init() or page.waitForLoad() first.");
try {
new WebDriverWait(driver, 10).until((ExpectedCondition<Boolean>) wd -> !isMarkerLoaded(wd));
this.loadMarkerId = null;
} catch (TimeoutException e) {
throw new TimeoutException("Timed out waiting for page to unload.", e);
}
if (waitAfterUnload != null)
Thread.sleep(waitAfterUnload);
}
/**
* Waits for the window to reload, useful for switching pages or submitting forms.
* Underlying behavior is invoking waitForUnload and waitForLoad.
* @throws UnexpectedException
*
*/
public void waitForReload() throws InterruptedException, UnexpectedException { this.waitForReload(null); }
/**
* Waits for the window to reload, useful for switching pages or submitting forms.
* Underlying behavior is invoking waitForUnload and waitForLoad.
*
* @param waitAfterReload Milliseconds. After the preceeding calls, Thread.sleep(waitAfterReload) will be invoked.
* @throws UnexpectedException
*/
public void waitForReload(Integer waitAfterReload) throws InterruptedException, UnexpectedException {
this.waitForUnload();
this.waitForLoad();
Thread.sleep(waitAfterReload != null ? waitAfterReload : 0);
}
public enum CreateMarker {
YES, NO
}
public void init() throws InterruptedException { init(CreateMarker.YES); }
public void init(CreateMarker marker) throws InterruptedException {
PageFactory.initElements(this.decorator, this);
if (marker == CreateMarker.YES) {
this.createLoadMarker();
}
}
private void createLoadMarker() throws InterruptedException {
this.waitInteractive();
// inserts a marker variable
if (isMarkerLoaded(driver)) return;
this.loadMarkerId = ("seleniumloader" + UUID.randomUUID().toString()).replaceAll("-", "");
((JavascriptExecutor) driver).executeScript("window." + this.loadMarkerId + " = true;");
}
private Boolean isMarkerLoaded(WebDriver driver) {
if (this.loadMarkerId == null)
return false;
return !(null == ((JavascriptExecutor) driver).executeScript("return window." + this.loadMarkerId));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment