Reputation: 1290
I'm connecting to a website multiple times every few seconds and sometimes the website just enters a HUGE loading phase where it takes like 5 minutes to stop loading. When it finally stops, it throws an expected ElementNotFoundException
which i then catch and restart the process from the last point. However, i want to be able to detect this loading phase and handle it as soon as possible instead of waiting 5 minutes for it to end. I tried using a FluentWait
implementation and a WebDriverWait
one but none works so far. Here are the two implementations i tried :
FluentWait :
private static WebElement fluentWait(final By locator, WebDriver driver) {
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(10, TimeUnit.SECONDS)
.pollingEvery(2, TimeUnit.SECONDS);
//.ignoring(NoSuchElementException.class);
return wait.until((Function<WebDriver, WebElement>) driver1 -> {
assert driver1 != null;
return driver1.findElement(locator);
});
}
WebDriverWait:
new WebDriverWait(driver,5).until(ExpectedConditions.presenceOfElementLocated(new By.ByCssSelector(someSelector)));
P.S: I'm using Selenium Webdriver and specifically ChromeDriver()
. Here's an image of how the website looks when it enters that huge loading phase ->
Upvotes: 0
Views: 996
Reputation: 546
This is not something to worry about. You can check the below links and I hope this will help.
Selenium -- How to wait until page is completely loaded
Wait for page load in Selenium
Upvotes: 1
Reputation: 618
Based on your question I'm gathering you want to have the code wait for a specific amount of time and timeout if execution hasn't been finished before then?
If you want to do this, I think the best method would be to implement a simple class that uses an executor to wait for a result. Executors support timeouts and are able to return a value OR throw an exception if execution takes too long.
For this I wrote this simple class:
public class TimedWait<T> {
public T run(Callable<T> run, long timeoutMs) throws TimeoutException, ExecutionException, InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
return executor.invokeAny(Collections.singletonList(run), timeoutMs, TimeUnit.MILLISECONDS);
}
}
This will use the timeout I mentioned and will run a provided Callable with a specified timeout, after which an exception is thrown.
An example of how it could function is as followed (I did do some quick and dirty exception handling for example purposes, you might want to clean that up a bit to avoid try catch overuse)
public void run() {
try {
String result = new TimedWait<String>().run(() -> {
Thread.sleep(500);
return "Some Result";
}, 1000L);
System.out.println(result);
String timeOut = new TimedWait<String>().run(() -> {
Thread.sleep(1500);
return "This will time out";
}, 1000L);
System.out.println(timeOut);
} catch (Exception e) {
e.printStackTrace();
}
}
Since in this example the delay for the first output is smaller than the timeout, the result will be printed. For the second output, the delay is bigger than the timeout resulting in an exception.
Output being:
Some Result
java.util.concurrent.TimeoutException
Upvotes: 0