View Javadoc

1   package com.atlassian.pageobjects.elements.query.webdriver;
2   
3   import com.atlassian.pageobjects.elements.WebDriverLocatable;
4   import com.atlassian.webdriver.AtlassianWebDriver;
5   import com.google.common.base.Function;
6   import com.google.common.base.Supplier;
7   import org.openqa.selenium.NoSuchElementException;
8   import org.openqa.selenium.StaleElementReferenceException;
9   import org.openqa.selenium.WebElement;
10  
11  import static com.atlassian.pageobjects.elements.util.StringConcat.asString;
12  import static com.google.common.base.Preconditions.checkNotNull;
13  
14  /**
15   * <p/>
16   * {@link WebDriverLocatable} based timed query that retrieves {@link WebElement} using provided
17   * {@link WebDriverLocatable} and applies provided function from that element to the target value.
18   *
19   * <p/>
20   * If given element is not found, the 'invalid value' semantics of the timed query are applied. 
21   *
22   */
23  public class WebDriverLocatableBasedTimedQuery<T> extends GenericWebDriverTimedQuery<T>
24  {
25      private final WebDriverLocatable locatable;
26  
27      public WebDriverLocatableBasedTimedQuery(WebDriverLocatable locatable, AtlassianWebDriver driver,
28                                               Function<WebElement, T> valueProvider, long timeout)
29      {
30          super(new LocatableBasedSupplier<T>(driver, locatable, valueProvider), timeout);
31          this.locatable = locatable;
32      }
33  
34      public WebDriverLocatableBasedTimedQuery(WebDriverLocatable locatable, AtlassianWebDriver driver,
35                                               Function<WebElement, T> valueProvider, long timeout, long interval)
36      {
37          super(new LocatableBasedSupplier<T>(driver, locatable, valueProvider), timeout, interval);
38          this.locatable = locatable;
39      }
40  
41      public WebDriverLocatableBasedTimedQuery(WebDriverLocatable locatable, AtlassianWebDriver driver,
42                                               Function<WebElement, T> valueProvider, long timeout, long interval,
43                                               T invalidValue)
44      {
45          super(new LocatableBasedSupplier<T>(driver, locatable, valueProvider, invalidValue), timeout, interval);
46          this.locatable = locatable;
47      }
48  
49      public WebDriverLocatableBasedTimedQuery(WebDriverLocatableBasedTimedQuery<T> origin, long timeout)
50      {
51          super(origin.webElementSupplier(), timeout, origin.interval);
52          this.locatable = origin.locatable;
53      }
54  
55      LocatableBasedSupplier<T> webElementSupplier()
56      {
57          return (LocatableBasedSupplier<T>) valueSupplier;
58      }
59  
60      Function<WebElement,T> valueProvider()
61      {
62          return webElementSupplier().valueProvider;
63      }
64  
65      @Override
66      public String toString()
67      {
68          return asString(super.toString(), "[locatable=", locatable, ",valueProvider=", valueProvider(), "]");
69      }
70  
71      private static class LocatableBasedSupplier<S> implements Supplier<S>
72      {
73          private final AtlassianWebDriver webDriver;
74          private final WebDriverLocatable locatable;
75          private final Function<WebElement, S> valueProvider;
76          private final S invalidValue;
77  
78           public LocatableBasedSupplier(AtlassianWebDriver webDriver ,WebDriverLocatable locatable,
79                                         Function<WebElement, S> valueProvider, S invalid)
80          {
81              this.valueProvider = valueProvider;
82              this.webDriver = webDriver;
83              this.locatable = checkNotNull(locatable);
84              this.invalidValue = invalid;
85          }
86  
87          public LocatableBasedSupplier(AtlassianWebDriver webDriver, WebDriverLocatable locatable, Function<WebElement, S> valueProvider)
88          {
89              this(webDriver, locatable, valueProvider, null);
90          }
91  
92          public S get()
93          {
94              try
95              {
96                  return valueProvider.apply((WebElement) locatable.waitUntilLocated(webDriver, 0));
97              }
98              catch(StaleElementReferenceException e)
99              {
100                 // element became stale between the time we got it from the locatable and we called the
101                 // value provider. Error out here and try on next poll.
102                 throw new InvalidValue(invalidValue);
103             }
104             catch (NoSuchElementException e1)
105             {
106                 throw new InvalidValue(invalidValue);
107             }
108         }
109     }
110 }