|
1 | 1 | package uk.co.evoco.webdriver.utils; |
2 | 2 |
|
3 | | -import org.openqa.selenium.*; |
4 | | -import org.openqa.selenium.support.ui.ExpectedConditions; |
5 | | -import org.openqa.selenium.support.ui.Sleeper; |
6 | | -import org.openqa.selenium.support.ui.WebDriverWait; |
7 | | -import org.slf4j.Logger; |
8 | | -import org.slf4j.LoggerFactory; |
9 | | -import uk.co.evoco.webdriver.configuration.TestConfigManager; |
| 3 | +import org.openqa.selenium.WebElement; |
10 | 4 |
|
11 | | -import java.time.Clock; |
12 | | -import java.time.Duration; |
13 | | -import java.time.Instant; |
| 5 | +import java.util.Optional; |
14 | 6 |
|
15 | 7 | /** |
16 | 8 | * Only for us in the situations outlined for the provided methods. |
17 | 9 | * There's nothing wrong with WebDrivers normal click method, if you don't need this, steer well clear. |
18 | 10 | */ |
19 | | -public final class ClickUtils { |
20 | | - |
21 | | - private static final Logger logger = LoggerFactory.getLogger(ClickUtils.class); |
| 11 | +public final class ClickUtils extends TolerantInteraction { |
22 | 12 |
|
23 | 13 | /** |
24 | | - * Use this method if you're experiencing exceptions that are UN-FIXABLE in your application |
25 | | - * and you find that you're getting intermittent (and unhelpful) exceptions. |
26 | | - * |
27 | | - * This method takes its configuration from the configuration file (see documentation for how to add exceptions |
28 | | - * to the list of exceptions that this method will tolerate). |
29 | 14 | * |
30 | | - * It retries only once and waits for 3 seconds. This may become configurable in the future. |
31 | | - * |
32 | | - * @param webDriver active WebDriver instance |
33 | | - * @param webElement active WebElement, already located |
34 | | - * @param waitTimeBeforeRetry time to wait explicitly before we retry |
35 | | - * @throws InterruptedException because there is a Thread.sleep in this method. |
| 15 | + * @param webElement active WebElements, already located |
| 16 | + * @param timeout time in seconds to keep trying |
| 17 | + * @throws Throwable any unhandled or un-tolerated exception |
36 | 18 | */ |
37 | | - public static void tolerantClick(WebDriver webDriver, WebElement webElement, int waitTimeBeforeRetry) throws InterruptedException { |
38 | | - try { |
39 | | - click(webDriver, webElement, TestConfigManager.get().getWebDriverWaitTimeout()); |
40 | | - } catch(Exception e) { |
41 | | - logger.error("Encountered an issue while trying to click, will check to see if we tolerate this exception. Debug this issue to make your tests more stable. Stacktrace follows."); |
42 | | - e.printStackTrace(); |
43 | | - for(String exceptionToHandle : TestConfigManager.get().getExceptionsToHandleOnTolerantActions()) { |
44 | | - if(e.getClass().getName().contains(exceptionToHandle)) { |
45 | | - logger.error("Exception {} is tolerated, retrying after a {} second wait", waitTimeBeforeRetry, exceptionToHandle); |
46 | | - Thread.sleep(waitTimeBeforeRetry); |
47 | | - logger.error("Waited {} seconds after {}, now retrying", waitTimeBeforeRetry, exceptionToHandle); |
48 | | - click(webDriver, webElement, TestConfigManager.get().getWebDriverWaitTimeout()); |
49 | | - } |
50 | | - } |
51 | | - } |
52 | | - } |
53 | | - |
54 | | - /** |
55 | | - * |
56 | | - * Use this method if you're experiencing exceptions that are UN-FIXABLE in your application |
57 | | - * and you find that you're getting intermittent (and unhelpful) exceptions. |
58 | | - * |
59 | | - * This method takes its configuration from the configuration file (see documentation for how to add exceptions |
60 | | - * to the list of exceptions that this method will tolerate). |
61 | | - * |
62 | | - * It retries only once and waits for 3 seconds. This may become configurable in the future. |
63 | | - * |
64 | | - * @param webDriver active WebDriver instance |
65 | | - * @param locator locator we will use to re-lookup the element on retry |
66 | | - * @param waitTimeBeforeRetry time to wait explicitly before we retry |
67 | | - * @throws InterruptedException |
68 | | - */ |
69 | | - public static void tolerantClick(WebDriver webDriver, By locator, int waitTimeBeforeRetry) throws InterruptedException { |
70 | | - try { |
71 | | - click(webDriver, locator, TestConfigManager.get().getWebDriverWaitTimeout()); |
72 | | - } catch(Exception e) { |
73 | | - logger.error("Encountered an issue while trying to click, will check to see if we tolerate this exception. Debug this issue to make your tests more stable. Stacktrace follows."); |
74 | | - e.printStackTrace(); |
75 | | - for(String exceptionToHandle : TestConfigManager.get().getExceptionsToHandleOnTolerantActions()) { |
76 | | - if(e.getClass().getName().contains(exceptionToHandle)) { |
77 | | - logger.error("Exception {} is tolerated, retrying after a {} second wait", waitTimeBeforeRetry, exceptionToHandle); |
78 | | - Thread.sleep(waitTimeBeforeRetry); |
79 | | - logger.error("Waited {} seconds after {}, now retrying", waitTimeBeforeRetry, exceptionToHandle); |
80 | | - click(webDriver, locator, TestConfigManager.get().getWebDriverWaitTimeout()); |
81 | | - } |
82 | | - } |
83 | | - } |
84 | | - } |
85 | | - |
86 | | - /** |
87 | | - * |
88 | | - * @param webDriver active WebDriver instance |
89 | | - * @param webElement locator we will use to re-lookup the element on retry |
90 | | - * @param timeoutInSeconds time to continue trying for |
91 | | - * @throws Throwable |
92 | | - */ |
93 | | - public static void tolerantPollingClick(WebDriver webDriver, WebElement webElement, int timeoutInSeconds) throws Throwable { |
94 | | - Clock clock = Clock.systemDefaultZone(); |
95 | | - Instant end = clock.instant().plusSeconds(timeoutInSeconds); |
96 | | - Sleeper sleeper = Sleeper.SYSTEM_SLEEPER; |
97 | | - Duration intervalDuration = Duration.ofMillis(500); |
98 | | - |
99 | | - Throwable lastException = null; |
100 | | - while(true) { |
101 | | - try { |
102 | | - logger.info("Testing is element is currently clickable"); |
103 | | - if(Boolean.TRUE.equals(webElement.isEnabled())) { |
104 | | - logger.info("Element was found, clicking and exiting"); |
105 | | - webElement.click(); |
106 | | - return; |
107 | | - } else { |
108 | | - logger.info("Element is currently not clickable"); |
109 | | - } |
110 | | - } catch(Throwable e) { |
111 | | - logger.info("Exception thrown {}, will check if ignored", lastException.getCause()); |
112 | | - lastException = propagateIfNotIgnored(e); |
113 | | - } |
114 | | - |
115 | | - if(end.isBefore(clock.instant())) { |
116 | | - if(null == lastException) { |
117 | | - logger.error("Exception condition failed: Timeout (tried for {} seconds with 500ms interval", timeoutInSeconds); |
118 | | - lastException = new TimeoutException(); |
119 | | - } else { |
120 | | - logger.error("Exception condition failed: {} (tried for {} seconds with 500ms interval", |
121 | | - lastException.getCause(), timeoutInSeconds); |
122 | | - } |
123 | | - throw lastException; |
124 | | - } |
125 | | - |
126 | | - try { |
127 | | - logger.info("Waiting before poll for {}ms", intervalDuration.toMillis()); |
128 | | - sleeper.sleep(intervalDuration); |
129 | | - } catch (InterruptedException e) { |
130 | | - Thread.currentThread().interrupt(); |
131 | | - throw new WebDriverException(e); |
132 | | - } |
133 | | - } |
134 | | - } |
135 | | - |
136 | | - private static void click(WebDriver webDriver, WebElement webElement, long timeout) { |
137 | | - new WebDriverWait(webDriver, timeout).until(ExpectedConditions.elementToBeClickable(webElement)).click(); |
138 | | - } |
139 | | - |
140 | | - private static void click(WebDriver webDriver, By locator, long timeout) { |
141 | | - WebElement webElement = webDriver.findElement(locator); |
142 | | - new WebDriverWait(webDriver, timeout).until(ExpectedConditions.elementToBeClickable(webElement)).click(); |
143 | | - } |
144 | | - |
145 | | - private static Throwable propagateIfNotIgnored(Throwable e) throws Throwable { |
146 | | - for (String ignoredException : TestConfigManager.get().getExceptionsToHandleOnTolerantActions()) { |
147 | | - if (Class.forName(ignoredException).isInstance(e)) { |
148 | | - logger.info("Exception {} will be ignored", ignoredException); |
149 | | - } else { |
150 | | - return e; |
151 | | - } |
152 | | - } |
153 | | - return e; |
| 19 | + public static void tolerantClick(WebElement webElement, int timeout) throws Throwable { |
| 20 | + new SendKeysUtils().tolerantInteraction(webElement, Optional.empty(), timeout); |
154 | 21 | } |
155 | 22 | } |
0 commit comments