1 package com.atlassian.pageobjects.elements.query.webdriver;
2
3 import com.atlassian.annotations.Internal;
4 import com.atlassian.pageobjects.elements.WebDriverLocatable;
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.WebDriver;
10 import org.openqa.selenium.WebElement;
11
12 import javax.annotation.Nonnull;
13
14 import static com.atlassian.pageobjects.elements.WebDriverLocatable.LocateTimeout.zero;
15 import static com.atlassian.pageobjects.elements.util.StringConcat.asString;
16 import static com.google.common.base.Preconditions.checkNotNull;
17
18
19
20
21
22
23
24
25
26
27 @Internal
28 public class WebDriverLocatableBasedTimedQuery<T> extends GenericWebDriverTimedQuery<T>
29 {
30 private final WebDriverLocatable locatable;
31
32 public WebDriverLocatableBasedTimedQuery(WebDriverLocatable locatable, WebDriver driver,
33 Function<WebElement, T> valueProvider, long timeout)
34 {
35 super(new LocatableBasedSupplier<T>(driver, locatable, valueProvider), timeout);
36 this.locatable = locatable;
37 }
38
39 public WebDriverLocatableBasedTimedQuery(WebDriverLocatable locatable, WebDriver driver,
40 Function<WebElement, T> valueProvider, long timeout, long interval)
41 {
42 super(new LocatableBasedSupplier<T>(driver, locatable, valueProvider),
43 timeout, interval);
44 this.locatable = locatable;
45 }
46
47 public WebDriverLocatableBasedTimedQuery(WebDriverLocatable locatable, WebDriver driver,
48 Function<WebElement, T> valueProvider, long timeout, long interval,
49 T invalidValue)
50 {
51 super(new LocatableBasedSupplier<T>(driver, locatable, valueProvider, invalidValue),
52 timeout, interval);
53 this.locatable = locatable;
54 }
55
56 public WebDriverLocatableBasedTimedQuery(WebDriverLocatableBasedTimedQuery<T> origin, long timeout)
57 {
58 super(origin.webElementSupplier(), timeout, origin.interval);
59 this.locatable = origin.locatable;
60 }
61
62 LocatableBasedSupplier<T> webElementSupplier()
63 {
64 return (LocatableBasedSupplier<T>) valueSupplier;
65 }
66
67 Function<WebElement,T> valueProvider()
68 {
69 return webElementSupplier().valueProvider;
70 }
71
72 @Override
73 @Nonnull
74 public String toString()
75 {
76 return asString(super.toString(), "[locatable=", locatable, ",valueProvider=", valueProvider(), "]");
77 }
78
79 private static class LocatableBasedSupplier<S> implements Supplier<S>
80 {
81 private final WebDriver webDriver;
82 private final WebDriverLocatable locatable;
83 private final Function<WebElement, S> valueProvider;
84 private final S invalidValue;
85
86 public LocatableBasedSupplier(WebDriver webDriver, WebDriverLocatable locatable,
87 Function<WebElement, S> valueProvider, S invalid)
88 {
89 this.valueProvider = valueProvider;
90 this.webDriver = webDriver;
91 this.locatable = checkNotNull(locatable);
92 this.invalidValue = invalid;
93 }
94
95 public LocatableBasedSupplier(WebDriver webDriver, WebDriverLocatable locatable,
96 Function<WebElement, S> valueProvider)
97 {
98 this(webDriver, locatable, valueProvider, null);
99 }
100
101 public S get()
102 {
103 try
104 {
105 return valueProvider.apply((WebElement) locatable.waitUntilLocated(webDriver, zero()));
106 }
107 catch(StaleElementReferenceException e)
108 {
109
110
111 throw new InvalidValue(invalidValue);
112 }
113 catch (NoSuchElementException e1)
114 {
115 throw new InvalidValue(invalidValue);
116 }
117 }
118 }
119 }