Skip to content

Commit ef58711

Browse files
author
travis-ci
committed
Complete rewrite of the tolerant methods and a nice tidy up around that part of the code. Adding some supporter classes for this work as well and bumping version number ready for release to v.0.0.10.
1 parent 7259ad9 commit ef58711

File tree

10 files changed

+272
-384
lines changed

10 files changed

+272
-384
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ submit an issue ticket.
3838
## Documentation
3939

4040
- A full reference guide is here: https://github.com/digital-delivery-academy/selenium-pom-framework/wiki
41-
- Technical reference documentation (javadocs) are here: https://digital-delivery-academy.github.io/selenium-pom-framework/javadoc-0.0.9
41+
- Technical reference documentation (javadocs) are here: https://digital-delivery-academy.github.io/selenium-pom-framework/javadoc-0.0.10
4242

4343
## Example tests
4444

@@ -52,7 +52,7 @@ Put this in your POM.xml.
5252
<dependency>
5353
<groupId>uk.co.evoco</groupId>
5454
<artifactId>selenium-pom-framework</artifactId>
55-
<version>0.0.9</version>
55+
<version>0.0.10</version>
5656
</dependency>
5757
```
5858

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>uk.co.evoco</groupId>
88
<artifactId>selenium-pom-framework</artifactId>
9-
<version>0.0.9</version>
9+
<version>0.0.10</version>
1010

1111
<contributors>
1212
<contributor>

src/main/java/uk/co/evoco/webdriver/WebDriverListener.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,9 @@ public void afterNavigateRefresh(WebDriver webDriver) {
141141
* @param webDriver active WebDriver instance
142142
*/
143143
public void beforeFindBy(By by, WebElement webElement, WebDriver webDriver) {
144-
new WebDriverWait(webDriver, TestConfigManager.get().getWebDriverWaitTimeout()).until(ExpectedConditions.presenceOfElementLocated(by));
144+
new WebDriverWait(webDriver,
145+
TestConfigManager.get().getWebDriverWaitTimeout()).until(
146+
ExpectedConditions.presenceOfElementLocated(by));
145147
}
146148

147149
/**
@@ -164,7 +166,9 @@ public void afterFindBy(By by, WebElement webElement, WebDriver webDriver) {
164166
* @param webDriver active WebDriver instance
165167
*/
166168
public void beforeClickOn(WebElement webElement, WebDriver webDriver) {
167-
new WebDriverWait(webDriver, TestConfigManager.get().getWebDriverWaitTimeout()).until(ExpectedConditions.elementToBeClickable(webElement));
169+
new WebDriverWait(webDriver,
170+
TestConfigManager.get().getWebDriverWaitTimeout()).until(
171+
ExpectedConditions.elementToBeClickable(webElement));
168172
}
169173

170174
/**
Lines changed: 8 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -1,155 +1,22 @@
11
package uk.co.evoco.webdriver.utils;
22

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;
104

11-
import java.time.Clock;
12-
import java.time.Duration;
13-
import java.time.Instant;
5+
import java.util.Optional;
146

157
/**
168
* Only for us in the situations outlined for the provided methods.
179
* There's nothing wrong with WebDrivers normal click method, if you don't need this, steer well clear.
1810
*/
19-
public final class ClickUtils {
20-
21-
private static final Logger logger = LoggerFactory.getLogger(ClickUtils.class);
11+
public final class ClickUtils extends TolerantInteraction {
2212

2313
/**
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).
2914
*
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
3618
*/
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);
15421
}
15522
}
Lines changed: 8 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,18 @@
11
package uk.co.evoco.webdriver.utils;
22

3-
import org.openqa.selenium.By;
4-
import org.openqa.selenium.WebDriver;
53
import org.openqa.selenium.WebElement;
6-
import org.openqa.selenium.support.ui.ExpectedConditions;
7-
import org.openqa.selenium.support.ui.WebDriverWait;
8-
import org.slf4j.Logger;
9-
import org.slf4j.LoggerFactory;
10-
import uk.co.evoco.webdriver.configuration.TestConfigManager;
114

125
import java.util.List;
136

147
/**
158
* Utility methods to select radio buttons
169
*/
17-
public final class RadioButtonUtils {
18-
19-
private static final Logger logger = LoggerFactory.getLogger(RadioButtonUtils.class);
10+
public final class RadioButtonUtils extends TolerantInteraction {
2011

2112
/**
2213
* Given a list of WebElements that locate the labels of the radio buttons,
2314
* finds the radio button with the given visible label text and selects it.
24-
* @param webElements active WebElement, already located
15+
* @param webElements active WebElements, already located
2516
* @param visibleLabelText text that is visible on the page in the label tags
2617
*/
2718
public static void selectByLabel(List<WebElement> webElements, String visibleLabelText) {
@@ -35,81 +26,13 @@ public static void selectByLabel(List<WebElement> webElements, String visibleLab
3526

3627
/**
3728
*
38-
* @param webDriver active WebDriver
39-
* @param locator for us to manage the lookup of the WebElement
29+
* @param webElements active WebElements, already located
4030
* @param visibleLabelText text that is visible on the page in the label tags
31+
* @param timeout time in seconds to keep trying
32+
* @throws Throwable any unhandled or un-tolerated exception
4133
*/
42-
public static void selectByLabel(WebDriver webDriver, By locator, String visibleLabelText) {
43-
List<WebElement> webElements = new WebDriverWait(
44-
webDriver, TestConfigManager.get().getWebDriverWaitTimeout())
45-
.until(ExpectedConditions.presenceOfElementLocated(locator)).findElements(locator);
46-
for (WebElement webElement : webElements) {
47-
if (webElement.getText().equals(visibleLabelText)) {
48-
webElement.click();
49-
break;
50-
}
51-
}
52-
}
53-
54-
/**
55-
*
56-
* @param webDriver active WebDriver
57-
* @param locator locator for us to manage the lookup of the WebElements
58-
* @param visibleLabelText text that is visible on the page in the label tags
59-
* @param waitTimeBeforeRetry time to wait before we retry
60-
* @throws InterruptedException because there's a Thread.sleep here
61-
*/
62-
public static void tolerantSelectByLabel(
63-
WebDriver webDriver, By locator, String visibleLabelText, int waitTimeBeforeRetry) throws InterruptedException {
64-
try {
65-
selectByLabel(webDriver, locator, visibleLabelText);
66-
} catch (Exception e) {
67-
logger.error("Encountered an issue while trying to select visible text from select box, will check " +
68-
"to see if we tolerate this exception. Debug this issue to make your tests more stable. " +
69-
"Stacktrace follows.");
70-
e.printStackTrace();
71-
for (String exceptionToHandle :
72-
TestConfigManager.get().getExceptionsToHandleOnTolerantActions()) {
73-
if (e.getClass().getName().contains(exceptionToHandle)) {
74-
logger.error(
75-
"Exception {} is tolerated, retrying after a {} second wait",
76-
waitTimeBeforeRetry,
77-
exceptionToHandle);
78-
Thread.sleep(waitTimeBeforeRetry);
79-
logger.error("Waited {} seconds after {}, now retrying", waitTimeBeforeRetry, exceptionToHandle);
80-
selectByLabel(webDriver, locator, visibleLabelText);
81-
}
82-
}
83-
}
84-
}
85-
86-
/**
87-
*
88-
* @param elements WebElements
89-
* @param visibleLabelText text that is visible on the page in the label tags
90-
* @param waitTimeBeforeRetry time to wait before we retry
91-
* @throws InterruptedException because there's a Thread.sleep here
92-
*/
93-
public static void tolerantSelectByLabel(List<WebElement> elements, String visibleLabelText, int waitTimeBeforeRetry) throws InterruptedException {
94-
try {
95-
selectByLabel(elements, visibleLabelText);
96-
} catch (Exception e) {
97-
logger.error("Encountered an issue while trying to select visible text from select box, will check " +
98-
"to see if we tolerate this exception. Debug this issue to make your tests more stable. " +
99-
"Stacktrace follows.");
100-
e.printStackTrace();
101-
for (String exceptionToHandle :
102-
TestConfigManager.get().getExceptionsToHandleOnTolerantActions()) {
103-
if (e.getClass().getName().contains(exceptionToHandle)) {
104-
logger.error(
105-
"Exception {} is tolerated, retrying after a {} second wait",
106-
waitTimeBeforeRetry,
107-
exceptionToHandle);
108-
Thread.sleep(waitTimeBeforeRetry);
109-
logger.error("Waited {} seconds after {}, now retrying", waitTimeBeforeRetry, exceptionToHandle);
110-
selectByLabel(elements, visibleLabelText);
111-
}
112-
}
113-
}
34+
public static void tolerantSelectByLabel(List<WebElement> webElements, String visibleLabelText, int timeout)
35+
throws Throwable {
36+
new RadioButtonUtils().tolerantInteraction(webElements, visibleLabelText, timeout).click();
11437
}
11538
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package uk.co.evoco.webdriver.utils;
2+
3+
public enum SelectBoxInteractionType {
4+
BY_VISIBLE_TEXT,
5+
BY_VALUE,
6+
BY_INDEX
7+
}

0 commit comments

Comments
 (0)