title: Selenium - Search for Element With Class and Text
body: <p>I have the following code that will search for an element with given className and text until found or it times out. I don't like the fact that it is in an open loop for 30 seconds while returnElement == null. Is there a more efficient way of doing this? Note: It can't find the element based solely on text. </p>
  
  <pre><code>    #region FindAndWaitForElementListWithClassAndText
      public static IWebElement FindAndWaitForElementWithClassAndText(IWebDriver driver, string className, string text, int timeout = 30)
      {
          if (driver == null)
              throw new ApplicationException("No Selenium Driver defined, cannot continue.");
  
          WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeout));
          IWebElement returnElement = null;
  
          wait.Until(a =&gt; driver.FindElements(By.ClassName(className)));
  
          //Starts task that times out after specified TIMEOUT_MILLIS
          var tokenSource = new CancellationTokenSource();
          CancellationToken token =  tokenSource.Token;
          var task = Task.Factory.StartNew(() =&gt; searchForElementWtihClassAndText(driver, className, text), token);
          if(!task.Wait(TIMEOUT_MILLIS, token))
          {
              LoggerHelper.ErrorFormat("Could not find element with class and text: {0} :: {1}", className, text);
              returnElement = null;
          }
  
          returnElement = task.Result;
  
          return returnElement;
      }
      #endregion
  
      private static IWebElement searchForElementWtihClassAndText(IWebDriver driver, String className, String text)
      {
          IWebElement returnElement = null;
  
          while (returnElement == null)
          {
              var theList = driver.FindElements(By.ClassName(className));
              if (theList != null &amp;&amp; theList.Count &gt; 0)
              {
                  foreach (IWebElement el in theList)
                  {
                      if (el.Text.Equals(text, StringComparison.OrdinalIgnoreCase))
                      {
                          returnElement = el;
                          LoggerHelper.InfoFormat("Found Class Name and Text: {0} / {1}", className, text);
                      }
                  }
              }
          }
          return returnElement;
      }
  </code></pre>
  
  <p>Here's an example element:</p>
  
  <pre><code>&lt;div class="smtListItem smtMessageItem"&gt;
      &lt;!-- ngIf: message.SentItem --&gt;
      &lt;!-- ngIf: !message.SentItem --&gt;
      &lt;span class="smtListName ng-binding ng-
      scope" data-ng if=
      "!message.SentItem"&gt;user08&amp;nbsp;EIGHT&lt;/span&gt;
      &lt;!-- end ngIf: !message.SentItem --&gt;
  
      ...
  &lt;/div&gt;
  </code></pre>