View Javadoc

1   package com.atlassian.webdriver.utils.by;
2   
3   import com.atlassian.webdriver.utils.element.ElementLocated;
4   import org.openqa.selenium.By;
5   import org.openqa.selenium.SearchContext;
6   import org.openqa.selenium.TimeoutException;
7   import org.openqa.selenium.WebElement;
8   import org.openqa.selenium.support.ui.WebDriverWait;
9   import org.slf4j.Logger;
10  import org.slf4j.LoggerFactory;
11  
12  import java.util.List;
13  
14  import static com.atlassian.webdriver.LifecycleAwareWebDriverGrid.getDriver;
15  
16  /**
17   * Looks for an element by using the WebDriver wait and ElementLocated condition.
18   * It will wait up to 20 seconds for the element to be located.
19   *
20   * @since 2.0
21   */
22  public abstract class DeferredBy extends By
23  {
24  
25      private static final Logger log = LoggerFactory.getLogger(DeferredBy.class);
26  
27      private static final int DEFERRED_BY_WAIT = 20;
28  
29  
30      private static WebDriverWait getWait()
31      {
32          return new WebDriverWait(getDriver(), DEFERRED_BY_WAIT);
33      }
34  
35      private static DeferredBy by(final By selector) {
36  
37          if (selector == null)
38          {
39              throw new IllegalArgumentException("Cannot find elements with a null by selector");
40          }
41  
42          return new DeferredBy() {
43  
44              @Override
45              public List<WebElement> findElements(final SearchContext context)
46              {
47                  try
48                  {
49                      getWait().until(new ElementLocated(selector));
50                      return context.findElements(selector);
51                  }
52                  catch(TimeoutException e)
53                  {
54                      log.error("DeferredBy was unable to findElements using the selector: " + selector);
55                      throw e;
56                  }
57              }
58  
59              @Override
60              public WebElement findElement(final SearchContext context)
61              {
62                  try
63                  {
64                      getWait().until(new ElementLocated(selector));
65                      return context.findElement(selector);
66                  }
67                  catch(TimeoutException e)
68                  {
69                      log.error("DeferredBy was unable to findElement using the selector: " + selector);
70                      throw e;
71                  }
72              }
73  
74              @Override
75              public String toString()
76              {
77                  return "DeferredBy(" + super.toString() + ")";
78              }
79          };
80  
81      }
82  
83      /**
84       * @param id The value of the "id" attribute to search for
85       * @return a By which locates elements by the value of the "id" attribute.
86       */
87      public static DeferredBy id(final String id) {
88          return by(By.id(id));
89      }
90  
91      /**
92       * @param linkText The exact text to match against
93       * @return a By which locates A elements by the exact text it displays
94       */
95      public static By linkText(final String linkText) {
96          return by(By.linkText(linkText));
97      }
98  
99      /**
100      * @param linkText The text to match against
101      * @return a By which locates A elements that contain the given link text
102      */
103     public static By partialLinkText(final String linkText) {
104       return by(By.partialLinkText(linkText));
105     }
106 
107     /**
108      * @param name The value of the "name" attribute to search for
109      * @return a By which locates elements by the value of the "name" attribute.
110      */
111     public static By name(final String name) {
112         return by(By.name(name));
113     }
114 
115     /**
116      * @param name The element's tagName
117      * @return a By which locates elements by their tag name
118      */
119     public static By tagName(final String name) {
120       return by(By.tagName(name));
121     }
122 
123     /**
124    * @param xpathExpression The xpath to use
125    * @return a By which locates elements via XPath
126    */
127     public static By xpath(final String xpathExpression) {
128       return by(By.xpath(xpathExpression));
129     }
130 
131     /**
132    * Finds elements based on the value of the "class" attribute. If an element has many classes
133    * then this will match against each of them. For example if the value is "one two onone", then the
134    * following "className"s will match: "one" and "two"
135    *
136    * @param className The value of the "class" attribute to search for
137    * @return a By which locates elements by the value of the "class" attribute.
138    */
139     public static By className(final String className) {
140        return by(By.className(className));
141     }
142 
143     /**
144      * Finds elements via the driver's underlying W3 Selector engine. If the browser does not
145      * implement the Selector API an exception will be thrown.
146      */
147     public static By cssSelector(final String selector) {
148         return by(By.cssSelector(selector));
149     }
150 
151     @Override
152     public boolean equals(Object o) {
153         if (this == o) return true;
154         if (o == null || getClass() != o.getClass()) return false;
155 
156         DeferredBy by = (DeferredBy) o;
157 
158         return toString().equals(by.toString());
159     }
160 
161     @Override
162     public int hashCode() {
163         return toString().hashCode();
164     }
165 
166 }