I'm trying to use Selenium to wait for a progress bar to appear and disappear, which indicates that a search result has started and is then done.
When there is no progress bar, the document looks something like this:
<html lang="en-US">
<body class="appian-body">
<a id="skip-to-content"></a>
<div id="aDiv"></div>
<div id="anotherOne"></div>
<div id="OneMore"></div>
...
</body>
</html>
When a search call starts, it looks like this:
<html lang="en-US">
<body class="appian-body">
<a id="skip-to-content"></a>
<div id="aDiv"></div>
<div id="anotherOne"></div>
<div id="OneMore"></div>
...
<div id="appian-working-indicator-hidden" style="display: none;"></div>
</body>
</html>
Note the <div id="appian-working-indicator-hidden" style="display: none;"></div>
has appeared, which is also when the progress bar appears. Of course it then goes away when the search is done and then we're back to the original document.
Here are some attempts I've made to wait for this element:
Attempt 1
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("/html/body/div[4]")));
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("/html/body/div[4]")));
Result: Timeout exception on visibilityOfElementLocated
(i.e. it's never visible).
Attempt 2
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("/html/body/div[4]")));
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("/html/body/div[4]")));
Result: Execution passes through both presenceOfElementLocated
and invisibilityOfElementLocated
without waiting at all.
So, what else can be done to ensure this element has appeared and disappeared?
Update
I've created these recursive methods:
public void waitForProgressBarToStart() {
List<WebElement> progressBarList = driver.findElements(By.xpath("//div[@id='appian-working-indicator-hidden']"));
if(progressBarList.size() == 0) {
waitForProgressBarToStart();
} else {
//for timestamping when the element is found
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
Date date = new Date();
System.out.println(String.format("%s: Progress Bar started", dateFormat.format(date)));
}
}
public void waitForProgressBarToFinish() {
List<WebElement> progressBarList = driver.findElements(By.xpath("//div[@id='appian-working-indicator-hidden']"));
if(progressBarList.size() > 0) {
waitForProgressBarToFinish();
} else {
//for timestamping when the element is gone
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
Date date = new Date();
System.out.println(String.format("%s: Progress Bar done", dateFormat.format(date)));
}
}
public void waitForResults(){
waitForProgressBarToStart();
waitForProgressBarToFinish();
}
After using the timestamps in the methods, I can see that the waitForProgressBarToFinish
method takes 10-13 seconds longer than the actual progress bar. waitForProgressBarToStart
seems to find the element at the correct time, however.
Why would waitForProgressBarToFinish
take longer and how to fix?