title: Pros/cons for using multiple locators per element in Selenium?
body: <p>I am testing a website which is still in development. </p>
  
  <p>Often an element's id, class, text, or position in the DOM will change. And then the locator I've been using will no longer be able to find the element.</p>
  
  <p>But the features are still functioning properly. I don't want several tests to fail when there is no actual regression.</p>
  
  <p>So instead of having a single locator for each element, I have a collection of locators.</p>
  
  <pre><code>public static final ArrayList&lt;By&gt; LOGIN_ANCHOR_LOCATORS = new ArrayList&lt;By&gt;();
  
  static {
       LOGIN_ANCHOR_LOCATORS.add(By.id("loginLink"));
       LOGIN_ANCHOR_LOCATORS.add(By.linkText("Login"));
       LOGIN_ANCHOR_LOCATORS.add(By.xpath("/html/body/div[5]/a"));         
  }
  </code></pre>
  
  <p>My method for finding the element looks like this:</p>
  
  <pre><code>public WebElement locateElement(ArrayList&lt;By&gt; locators){
  
      // create an element to return
      WebElement element = null;
  
      // until the desired element is found...
      while (element == null){
  
          // loop through the locators
          for (By locator : locators){
  
              // try to find by locator
              element = customWait.until(ExpectedConditions.presenceOfElementLocated(locator));
  
              // if not found...
              if (element == null){
  
                  // log the failure
                  logFailingLocator(locator);
              }
          }
      }
      return element;
  }
  </code></pre>
  
  <p>It tries to find the element with the first locator in the collection, and only if it fails, try the next locator.</p>
  
  <p>The collection is an <code>ArrayList</code> (order is defined by insertion order), which means my <code>for loop</code> will try each locator in the order which they were added to the List. </p>
  
  <p>I initialized the list above by adding the locators in a particular order. Id is first, because I figure if the element's position in the DOM changes, but it retains its id, then that will be the way I'll be most likely to locate the correct element. Xpath is last because even if the id/class/text changes, but there is still the same type of element in the DOM at that position, it's probably the right element, but maybe less certain than other locators would be.</p>
  
  <p>I'm using a fluent wait which ignores NoSuchElementException:</p>
  
  <pre><code>// Wait 5 seconds for an element to be present on the page, checking
  // for its presence once every quarter of a second.
  Wait&lt;WebDriver&gt; customWait = new FluentWait&lt;WebDriver&gt;(driver)
          .withTimeout(5L, TimeUnit.SECONDS)
          .pollingEvery(250L, TimeUnit.MILLISECONDS)
          .ignoring(NoSuchElementException.class);
  </code></pre>
  
  <p>So when one locator fails, it won't break the loop - it just logs the failure and then  still goes on to try the next locator.</p>
  
  <p>If all the locators fail, then the element will remain null, the test will fail, and it's far more likely the reason is actual regression of features/functionality.</p>
  
  <p>I periodically check my logs for any element with 1 or 2 failing locators, and update them in my pageObject in the meantime, while tests continue running smoothly. </p>
  
  <p>What are pros or cons to setting up my project this way?</p>