title: Use Selenium to wait for progress bar
body: <p>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.</p>
  
  <p>When there is no progress bar, the document looks something like this:</p>
  
  <pre><code>&lt;html lang="en-US"&gt;
      &lt;body class="appian-body"&gt;
          &lt;a id="skip-to-content"&gt;&lt;/a&gt;
          &lt;div id="aDiv"&gt;&lt;/div&gt;
          &lt;div id="anotherOne"&gt;&lt;/div&gt;
          &lt;div id="OneMore"&gt;&lt;/div&gt;
          ...
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>When a search call starts, it looks like this:</p>
  
  <pre><code>&lt;html lang="en-US"&gt;
      &lt;body class="appian-body"&gt;
          &lt;a id="skip-to-content"&gt;&lt;/a&gt;
          &lt;div id="aDiv"&gt;&lt;/div&gt;
          &lt;div id="anotherOne"&gt;&lt;/div&gt;
          &lt;div id="OneMore"&gt;&lt;/div&gt;
          ...
          &lt;div id="appian-working-indicator-hidden" style="display: none;"&gt;&lt;/div&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>Note the <code>&lt;div id="appian-working-indicator-hidden" style="display: none;"&gt;&lt;/div&gt;</code> 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.</p>
  
  <p>Here are some attempts I've made to wait for this element:  </p>
  
  <h1>Attempt 1</h1>
  
  <pre><code>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]")));
  </code></pre>
  
  <p><strong>Result:</strong> Timeout exception on <code>visibilityOfElementLocated</code> (i.e. it's never visible).</p>
  
  <h1>Attempt 2</h1>
  
  <pre><code>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]")));
  </code></pre>
  
  <p><strong>Result:</strong> Execution passes through both <code>presenceOfElementLocated</code> and <code>invisibilityOfElementLocated</code> without waiting at all.</p>
  
  <p>So, what else can be done to ensure this element has appeared and disappeared?</p>
  
  <h1>Update</h1>
  
  <p>I've created these recursive methods:  </p>
  
  <pre><code>public void waitForProgressBarToStart() {
      List&lt;WebElement&gt; 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&lt;WebElement&gt; progressBarList = driver.findElements(By.xpath("//div[@id='appian-working-indicator-hidden']"));
      if(progressBarList.size() &gt; 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();
  }
  </code></pre>
  
  <p>After using the timestamps in the methods, I can see that the <code>waitForProgressBarToFinish</code> method takes 10-13 seconds longer than the actual progress bar. <code>waitForProgressBarToStart</code> seems to find the element at the correct time, however.  </p>
  
  <p>Why would <code>waitForProgressBarToFinish</code> take longer and how to fix?</p>