getServlets() {
40 | if ( ! (servlets == null || servlets.isEmpty())) {
41 | return servlets;
42 | }
43 | throw new IllegalStateException("At least one servlet class must be specified");
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/examples/TestNgRoot.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.examples;
2 |
3 | import org.testng.annotations.BeforeClass;
4 |
5 | import com.nordstrom.automation.selenium.support.TestNgBase;
6 |
7 | /**
8 | * This class provides a base for TestNG test classes with methods that target features of {@link ExamplePage}.
9 | */
10 | public class TestNgRoot extends TestNgBase {
11 |
12 | /**
13 | * This BeforeClass method configures Selenium Foundation to target {@link ExamplePage}.
14 | */
15 | @BeforeClass
16 | public void beforeClass() {
17 | ExamplePage.setHubAsTarget();
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/examples/TestNgTargetRoot.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.examples;
2 |
3 | import org.testng.annotations.BeforeClass;
4 |
5 | import com.nordstrom.automation.selenium.platform.TargetType;
6 | import com.nordstrom.automation.selenium.support.TestNgTargetBase;
7 |
8 | /**
9 | * This class provides a base for TestNG test classes with methods that target features of {@link ExamplePage}.
10 | */
11 | public class TestNgTargetRoot extends TestNgTargetBase {
12 |
13 | /**
14 | * This BeforeClass method configures Selenium Foundation to target {@link ExamplePage}.
15 | */
16 | @BeforeClass
17 | public void beforeClass() {
18 | ExamplePage.setHubAsTarget();
19 | }
20 |
21 | /**
22 | * {@inheritDoc}
23 | */
24 | @Override
25 | public TargetType getDefaultPlatform() {
26 | return TargetType.WEB_APP;
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/examples/WindowsPage.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.examples;
2 |
3 | import org.openqa.selenium.By;
4 | import org.openqa.selenium.WebDriver;
5 | import com.nordstrom.automation.selenium.model.Page;
6 |
7 | /**
8 | * This class is the model for the target view of the sample application used by the Appium Windows unit test.
9 | */
10 | public class WindowsPage extends Page {
11 |
12 | /**
13 | * Constructor for main view context.
14 | *
15 | * @param driver driver object
16 | */
17 | public WindowsPage(WebDriver driver) {
18 | super(driver);
19 | }
20 |
21 | /**
22 | * This enumeration defines element locator constants.
23 | */
24 | protected enum Using implements ByEnum {
25 | /** text field */
26 | EDIT_FIELD(By.className("Edit"));
27 |
28 | private final By locator;
29 |
30 | Using(By locator) {
31 | this.locator = locator;
32 | }
33 |
34 | @Override
35 | public By locator() {
36 | return locator;
37 | }
38 | }
39 |
40 | /**
41 | * Populate text field with the specified string.
42 | *
43 | * @param keys string to type into text field
44 | */
45 | public void modifyDocument(String keys) {
46 | findElement(Using.EDIT_FIELD).sendKeys(keys);
47 | }
48 |
49 | /**
50 | * Get document content.
51 | *
52 | * @return document content
53 | */
54 | public String getDocument() {
55 | return findElement(Using.EDIT_FIELD).getText();
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/ComponentStillDisplayedTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.model.PageComponent;
6 |
7 | /**
8 | * This exception is associated with the {@link PageComponent#componentIsHidden()} condition and indicates that the
9 | * indicated page component was still displayed when the timeout interval expired.
10 | */
11 | public class ComponentStillDisplayedTimeoutException extends TimeoutException {
12 |
13 | private static final long serialVersionUID = 5397614393701035129L;
14 |
15 | /**
16 | * Constructor for a new "component still displayed" timeout exception with
17 | * the specified message and cause.
18 | *
19 | * @param message the detail message (which is saved for later retrieval
20 | * by the {@link #getMessage()} method).
21 | * @param cause the cause (which is saved for later retrieval by the
22 | * {@link #getCause()} method). (A {@code null} value is
23 | * permitted, and indicates that the cause is nonexistent or
24 | * unknown.)
25 | */
26 | public ComponentStillDisplayedTimeoutException(String message, Throwable cause) {
27 | super(message, cause);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/ComponentStillInvisibleTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.model.PageComponent;
6 |
7 | /**
8 | * This exception is associated with the {@link PageComponent#componentIsVisible()} condition and indicates that the
9 | * indicated page component was still invisible when the timeout interval expired.
10 | */
11 | public class ComponentStillInvisibleTimeoutException extends TimeoutException {
12 |
13 | private static final long serialVersionUID = 7779370358344583623L;
14 |
15 | /**
16 | * Constructor for a new "component still invisible" timeout exception with
17 | * the specified message and cause.
18 | *
19 | * @param message the detail message (which is saved for later retrieval
20 | * by the {@link #getMessage()} method).
21 | * @param cause the cause (which is saved for later retrieval by the
22 | * {@link #getCause()} method). (A {@code null} value is
23 | * permitted, and indicates that the cause is nonexistent or
24 | * unknown.)
25 | */
26 | public ComponentStillInvisibleTimeoutException(String message, Throwable cause) {
27 | super(message, cause);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/ConditionStillInvalidTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.support.Coordinators;
6 |
7 | /**
8 | * This exception is associated with the {@link Coordinators#has(java.util.function.Function)} wrapper method
9 | * and indicates that the wrapped condition was still returning a 'negative' result when the timeout interval expired.
10 | */
11 | public class ConditionStillInvalidTimeoutException extends TimeoutException {
12 |
13 | private static final long serialVersionUID = -5012103332012897882L;
14 |
15 | /**
16 | * Constructor for a new "component still invalid" timeout exception with
17 | * the specified message and cause.
18 | *
19 | * @param message the detail message (which is saved for later retrieval
20 | * by the {@link #getMessage()} method).
21 | * @param cause the cause (which is saved for later retrieval by the
22 | * {@link #getCause()} method). (A {@code null} value is
23 | * permitted, and indicates that the cause is nonexistent or
24 | * unknown.)
25 | */
26 | public ConditionStillInvalidTimeoutException(String message, Throwable cause) {
27 | super(message, cause);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/ConditionStillValidTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.support.Coordinators;
6 |
7 | /**
8 | * This exception is associated with the {@link Coordinators#not(java.util.function.Function)} wrapper method
9 | * and indicates that the wrapped condition was still returning a 'positive' result when the timeout interval expired.
10 | */
11 | public class ConditionStillValidTimeoutException extends TimeoutException {
12 |
13 | private static final long serialVersionUID = -1194280527172574112L;
14 |
15 | /**
16 | * Constructor for a new "component still valid" timeout exception with
17 | * the specified message and cause.
18 | *
19 | * @param message the detail message (which is saved for later retrieval
20 | * by the {@link #getMessage()} method).
21 | * @param cause the cause (which is saved for later retrieval by the
22 | * {@link #getCause()} method). (A {@code null} value is
23 | * permitted, and indicates that the cause is nonexistent or
24 | * unknown.)
25 | */
26 | public ConditionStillValidTimeoutException(String message, Throwable cause) {
27 | super(message, cause);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/ContainerVacatedException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | /**
4 | * This exception is thrown when a client calls a method of a container object that's no longer valid.
5 | */
6 | public class ContainerVacatedException extends RuntimeException {
7 |
8 | private static final long serialVersionUID = -7653982501901130765L;
9 |
10 | /**
11 | * Constructor for a new "component vacated" exception with the specified
12 | * stack trace.
13 | *
14 | * @param stackTrace execution stack trace for the point at which the
15 | * associated container became invalid
16 | */
17 | public ContainerVacatedException(VacationStackTrace stackTrace) {
18 | super(stackTrace);
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/DocumentNotReadyTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.core.JsUtility;
6 |
7 | /**
8 | * This exception is associated with the {@link JsUtility#documentIsReady()} condition and indicates that the
9 | * current document failed to become ready within the timeout interval.
10 | */
11 | public class DocumentNotReadyTimeoutException extends TimeoutException {
12 |
13 | private static final long serialVersionUID = 3611395001046784941L;
14 |
15 | /**
16 | * Constructor for a new "document not ready" timeout exception with the
17 | * specified message and cause.
18 | *
19 | * @param message the detail message (which is saved for later retrieval
20 | * by the {@link #getMessage()} method).
21 | * @param cause the cause (which is saved for later retrieval by the
22 | * {@link #getCause()} method). (A {@code null} value is
23 | * permitted, and indicates that the cause is nonexistent or
24 | * unknown.)
25 | */
26 | public DocumentNotReadyTimeoutException(String message, Throwable cause) {
27 | super(message, cause);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/DriverExecutableNotFoundException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import com.nordstrom.automation.selenium.utility.BinaryFinder;
4 |
5 | /**
6 | * This exception is associated with the {@link BinaryFinder#findDriver(String)} method and indicates that a
7 | * driver matching the specified capabilities could not be acquired.
8 | */
9 | public class DriverExecutableNotFoundException extends RuntimeException {
10 |
11 | private static final long serialVersionUID = -5718589545720652315L;
12 |
13 | private static final String PATH_DEFINED = "Driver executable neither found at '%s' (specified by [%s]) nor on the PATH";
14 | private static final String PATH_OMITTED = "Driver executable not found on the PATH; add it or specify location in [%s]";
15 |
16 | /**
17 | * Constructor for a new "driver executable not found" exception with
18 | * hints from the specified driver path property.
19 | *
20 | * @param driverPathProp driver path property (may be {@code null}
21 | */
22 | public DriverExecutableNotFoundException(String driverPathProp) {
23 | super(getMessage(driverPathProp));
24 | }
25 |
26 | /**
27 | * Build the exception message with hints from the specified driver path property.
28 | *
29 | * @param driverPathProp driver path property (may be {@code null}
30 | * @return exception message string
31 | */
32 | private static String getMessage(final String driverPathProp) {
33 | String driverPath = System.getProperty(driverPathProp);
34 | if (driverPath != null) {
35 | return String.format(PATH_DEFINED, driverPath, driverPathProp);
36 | } else {
37 | return String.format(PATH_OMITTED, driverPathProp);
38 | }
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/DriverNotAvailableException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import com.nordstrom.automation.selenium.core.TestBase;
4 |
5 | /**
6 | * This exception is thrown by {@link TestBase#getDriver} when no driver is available.
7 | */
8 | public class DriverNotAvailableException extends RuntimeException {
9 |
10 | private static final long serialVersionUID = 657965846077748022L;
11 |
12 | /**
13 | * Constructor for "driver not available" exception with default message.
14 | */
15 | public DriverNotAvailableException() {
16 | super("No driver was found in the current test context");
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/ElementAbsentOrHiddenTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.support.Coordinators;
6 |
7 | /**
8 | * This exception is associated with the {@link Coordinators#visibilityOf(org.openqa.selenium.WebElement)},
9 | * {@link Coordinators#visibilityOfElementLocated(org.openqa.selenium.By)}, and
10 | * {@link Coordinators#visibilityOfAnyElementLocated(org.openqa.selenium.By)} conditions and indicates that the
11 | * specified element was still absent or hidden when the timeout interval expired.
12 | */
13 | public class ElementAbsentOrHiddenTimeoutException extends TimeoutException {
14 |
15 | private static final long serialVersionUID = -2295630523192380636L;
16 |
17 | /**
18 | * Constructor for a new "element absent or hidden" timeout exception with
19 | * the specified message and cause.
20 | *
21 | * @param message the detail message (which is saved for later retrieval
22 | * by the {@link #getMessage()} method).
23 | * @param cause the cause (which is saved for later retrieval by the
24 | * {@link #getCause()} method). (A {@code null} value is
25 | * permitted, and indicates that the cause is nonexistent or
26 | * unknown.)
27 | */
28 | public ElementAbsentOrHiddenTimeoutException(String message, Throwable cause) {
29 | super(message, cause);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/ElementAttributeTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.support.Coordinators;
6 |
7 | /**
8 | * This exception is associated with the
9 | * {@link Coordinators#elementToHaveAttributeValue(org.openqa.selenium.By, String, String)} and
10 | * and {@link Coordinators#textToBePresentInElementValue(org.openqa.selenium.By, String)} conditions and indicates
11 | * that the indicated attribute of the specified element failed to attain the specified value within the timeout
12 | * interval.
13 | */
14 | public class ElementAttributeTimeoutException extends TimeoutException {
15 |
16 | private static final long serialVersionUID = 7422856432865870480L;
17 |
18 | /**
19 | * Constructor for a new "element attribute" timeout exception with
20 | * the specified message and cause.
21 | *
22 | * @param message the detail message (which is saved for later retrieval
23 | * by the {@link #getMessage()} method).
24 | * @param cause the cause (which is saved for later retrieval by the
25 | * {@link #getCause()} method). (A {@code null} value is
26 | * permitted, and indicates that the cause is nonexistent or
27 | * unknown.)
28 | */
29 | public ElementAttributeTimeoutException(String message, Throwable cause) {
30 | super(message, cause);
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/ElementNotClickableTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.support.Coordinators;
6 |
7 | /**
8 | * This exception is associated with the {@link Coordinators#elementToBeClickable(org.openqa.selenium.By)} and
9 | * {@link Coordinators#elementToBeClickable(org.openqa.selenium.WebElement)} conditions and indicates that the
10 | * specified element failed to become click-able within the timeout interval.
11 | */
12 | public class ElementNotClickableTimeoutException extends TimeoutException {
13 |
14 | private static final long serialVersionUID = -8475358618203763123L;
15 |
16 | /**
17 | * Constructor for a new "element not clickable" timeout exception with
18 | * the specified message and cause.
19 | *
20 | * @param message the detail message (which is saved for later retrieval
21 | * by the {@link #getMessage()} method).
22 | * @param cause the cause (which is saved for later retrieval by the
23 | * {@link #getCause()} method). (A {@code null} value is
24 | * permitted, and indicates that the cause is nonexistent or
25 | * unknown.)
26 | */
27 | public ElementNotClickableTimeoutException(String message, Throwable cause) {
28 | super(message, cause);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/ElementNotPresentTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.support.Coordinators;
6 |
7 | /**
8 | * This exception is associated with the {@link Coordinators#presenceOfElementLocated(org.openqa.selenium.By)}
9 | * condition and indicates that no elements matching the specified locator were found within the timeout interval.
10 | */
11 | public class ElementNotPresentTimeoutException extends TimeoutException {
12 |
13 | private static final long serialVersionUID = 7039645286156391657L;
14 |
15 | /**
16 | * Constructor for a new "element not present" timeout exception with
17 | * the specified message and cause.
18 | *
19 | * @param message the detail message (which is saved for later retrieval
20 | * by the {@link #getMessage()} method).
21 | * @param cause the cause (which is saved for later retrieval by the
22 | * {@link #getCause()} method). (A {@code null} value is
23 | * permitted, and indicates that the cause is nonexistent or
24 | * unknown.)
25 | */
26 | public ElementNotPresentTimeoutException(String message, Throwable cause) {
27 | super(message, cause);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/ElementReferenceRefreshFailureException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.StaleElementReferenceException;
4 |
5 | import com.nordstrom.automation.selenium.model.RobustElementWrapper;
6 |
7 | /**
8 | * This exception is associated with
9 | * {@link RobustElementWrapper#refreshReference(org.openqa.selenium.StaleElementReferenceException)}
10 | * and indicates that the attempt to refresh a stale element reference was unsuccessful.
11 | */
12 | public class ElementReferenceRefreshFailureException extends StaleElementReferenceException {
13 |
14 | private static final long serialVersionUID = 417132799562814181L;
15 |
16 | /**
17 | * Constructor for a new "element reference refresh failure" exception with the
18 | * specified message and cause.
19 | *
20 | * @param message the detail message (which is saved for later retrieval
21 | * by the {@link #getMessage()} method).
22 | * @param cause the cause (which is saved for later retrieval by the
23 | * {@link #getCause()} method). (A {@code null} value is
24 | * permitted, and indicates that the cause is nonexistent or
25 | * unknown.)
26 | */
27 | public ElementReferenceRefreshFailureException(String message, Throwable cause) {
28 | super(message, cause);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/ElementSelectionStateTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.support.Coordinators;
6 |
7 | /**
8 | * This exception is associated with the
9 | * {@link Coordinators#elementSelectionStateToBe(org.openqa.selenium.By, boolean)} condition and indicates that the
10 | * specified element failed to attain the indicated selection state within the timeout interval.
11 | */
12 | public class ElementSelectionStateTimeoutException extends TimeoutException {
13 |
14 | private static final long serialVersionUID = 2150778933322672061L;
15 |
16 | /**
17 | * Constructor for a new "element selection state" timeout exception with
18 | * the specified message and cause.
19 | *
20 | * @param message the detail message (which is saved for later retrieval
21 | * by the {@link #getMessage()} method).
22 | * @param cause the cause (which is saved for later retrieval by the
23 | * {@link #getCause()} method). (A {@code null} value is
24 | * permitted, and indicates that the cause is nonexistent or
25 | * unknown.)
26 | */
27 | public ElementSelectionStateTimeoutException(String message, Throwable cause) {
28 | super(message, cause);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/ElementStillFreshTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.support.Coordinators;
6 |
7 | /**
8 | * This exception is associated with the {@link Coordinators#stalenessOf(org.openqa.selenium.WebElement)} condition
9 | * and indicates that the specified element reference failed to go "stale" within the timeout interval.
10 | */
11 | public class ElementStillFreshTimeoutException extends TimeoutException {
12 |
13 | private static final long serialVersionUID = -3082528281757446744L;
14 |
15 | /**
16 | * Constructor for a new "element still fresh" timeout exception with
17 | * the specified message and cause.
18 | *
19 | * @param message the detail message (which is saved for later retrieval
20 | * by the {@link #getMessage()} method).
21 | * @param cause the cause (which is saved for later retrieval by the
22 | * {@link #getCause()} method). (A {@code null} value is
23 | * permitted, and indicates that the cause is nonexistent or
24 | * unknown.)
25 | */
26 | public ElementStillFreshTimeoutException(String message, Throwable cause) {
27 | super(message, cause);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/ElementStillVisibleTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.support.Coordinators;
6 |
7 | /**
8 | * This exception is associated with the {@link Coordinators#invisibilityOfElementLocated(org.openqa.selenium.By)}
9 | * condition and indicates that the specified element was still visible when the timeout interval expired.
10 | */
11 | public class ElementStillVisibleTimeoutException extends TimeoutException {
12 |
13 | private static final long serialVersionUID = -3777087787464228714L;
14 |
15 | /**
16 | * Constructor for a new "element still visible" timeout exception with
17 | * the specified message and cause.
18 | *
19 | * @param message the detail message (which is saved for later retrieval
20 | * by the {@link #getMessage()} method).
21 | * @param cause the cause (which is saved for later retrieval by the
22 | * {@link #getCause()} method). (A {@code null} value is
23 | * permitted, and indicates that the cause is nonexistent or
24 | * unknown.)
25 | */
26 | public ElementStillVisibleTimeoutException(String message, Throwable cause) {
27 | super(message, cause);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/ElementTextContentTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.support.Coordinators;
6 |
7 | /**
8 | * This exception is associated with the
9 | * {@link Coordinators#textToBePresentInElementLocated(org.openqa.selenium.By, String)} and
10 | * {@link Coordinators#textToNotBeEmptyInElementLocated(org.openqa.selenium.By)} conditions and indicates that the
11 | * specified element failed to attain the indicated text content within the timeout interval.
12 | */
13 | public class ElementTextContentTimeoutException extends TimeoutException {
14 |
15 | private static final long serialVersionUID = -2893297898946904937L;
16 |
17 | /**
18 | * Constructor for a new "element text content" timeout exception with
19 | * the specified message and cause.
20 | *
21 | * @param message the detail message (which is saved for later retrieval
22 | * by the {@link #getMessage()} method).
23 | * @param cause the cause (which is saved for later retrieval by the
24 | * {@link #getCause()} method). (A {@code null} value is
25 | * permitted, and indicates that the cause is nonexistent or
26 | * unknown.)
27 | */
28 | public ElementTextContentTimeoutException(String message, Throwable cause) {
29 | super(message, cause);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/GridServerLaunchFailedException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | /**
4 | * Thrown if a Grid component process failed to start.
5 | */
6 | public class GridServerLaunchFailedException extends RuntimeException {
7 |
8 | private static final long serialVersionUID = 5186366410431999078L;
9 | private static final String TEMPLATE = "Failed to start grid %s process";
10 |
11 | /**
12 | * Constructor for {@code launch failed} exception with the specified server role.
13 | *
14 | * @param role Grid server role specifier ({@code hub} or {@code node})
15 | * @param cause the cause of this exception
16 | */
17 | public GridServerLaunchFailedException(final String role, final Throwable cause) {
18 | super(getMessage(role), cause);
19 | }
20 |
21 | /**
22 | * Get exception message for the specified server role.
23 | *
24 | * @param role Grid server role specifier ({@code hub} or {@code node})
25 | * @return exception message for the specified server role
26 | */
27 | private static String getMessage(final String role) {
28 | return String.format(TEMPLATE, role);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/InitialPageNotSpecifiedException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | /**
4 | * This exception is thrown if no initial page was specified.
5 | */
6 | public class InitialPageNotSpecifiedException extends RuntimeException {
7 |
8 | private static final long serialVersionUID = -6182879162513331011L;
9 |
10 | /**
11 | * Constructor for "initial page not specified" exception with default message.
12 | */
13 | public InitialPageNotSpecifiedException() {
14 | super("No initial page has been specified");
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/InvalidGridHostException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import java.net.MalformedURLException;
4 |
5 | import org.apache.http.HttpHost;
6 |
7 | /**
8 | * This exception is thrown to indicate that the Selenium Grid host specification is malformed.
9 | */
10 | public class InvalidGridHostException extends RuntimeException {
11 |
12 | private static final long serialVersionUID = -3037697283479571401L;
13 | private static final String TEMPLATE = "Specified Selenium Grid %s host URI '%s' is malformed";
14 |
15 | /**
16 | * Constructor for {@code invalid host} exception with the specified role and host.
17 | *
18 | * @param role Grid server role specifier ({@code hub} or {@code node})
19 | * @param host Grid server host specifier
20 | * @param cause the cause of this exception
21 | */
22 | public InvalidGridHostException(final String role, final HttpHost host, final MalformedURLException cause) {
23 | super(getMessage(role, host), cause);
24 | }
25 |
26 | /**
27 | * Get exception message for the specified role and host.
28 | *
29 | * @param role Grid server role specifier ({@code hub} or {@code node})
30 | * @param host Grid server host specifier
31 | * @return exception message for the specified role and host
32 | */
33 | private static String getMessage(final String role, final HttpHost host) {
34 | return String.format(TEMPLATE, role, host.toURI());
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/NoWindowAppearedTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.support.Coordinators;
6 |
7 | /**
8 | * This exception is associated with the {@link Coordinators#newWindowIsOpened(java.util.Set)} condition and
9 | * indicates that no new browser window appeared within the timeout interval.
10 | */
11 | public class NoWindowAppearedTimeoutException extends TimeoutException {
12 |
13 | private static final long serialVersionUID = 1178667313414119377L;
14 |
15 | /**
16 | * Constructor for a new "no window appeared" timeout exception with
17 | * the specified message and cause.
18 | *
19 | * @param message the detail message (which is saved for later retrieval
20 | * by the {@link #getMessage()} method).
21 | * @param cause the cause (which is saved for later retrieval by the
22 | * {@link #getCause()} method). (A {@code null} value is
23 | * permitted, and indicates that the cause is nonexistent or
24 | * unknown.)
25 | */
26 | public NoWindowAppearedTimeoutException(String message, Throwable cause) {
27 | super(message, cause);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/OptionalElementNotAcquiredException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.NoSuchElementException;
4 | import org.openqa.selenium.WebElement;
5 |
6 | /**
7 | * This exception is thrown upon failing to acquire the reference for an optional element prior to invoking a
8 | * {@link WebElement} method.
9 | */
10 | public class OptionalElementNotAcquiredException extends NoSuchElementException {
11 |
12 | private static final long serialVersionUID = -1817241270199904930L;
13 |
14 | /**
15 | * Constructor for {@code optional element not acquired} exception.
16 | *
17 | * @param cause the cause of this exception
18 | */
19 | public OptionalElementNotAcquiredException(final NoSuchElementException cause) {
20 | super("Unable to acquire reference for optional element", cause);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/PageLoadRendererTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.model.ContainerMethodInterceptor;
6 |
7 | /**
8 | * This exception is associated with {@link ContainerMethodInterceptor#intercept(Object, Method, Object[], Callable)}
9 | * and indicates that the browser timed out waiting for web page resources to be processed and rendered.
10 | */
11 | public class PageLoadRendererTimeoutException extends TimeoutException {
12 |
13 | private static final long serialVersionUID = 2076867125637147698L;
14 |
15 | /**
16 | * Constructor for a new "page load renderer" timeout exception with the
17 | * specified message and cause.
18 | *
19 | * @param message the detail message (which is saved for later retrieval
20 | * by the {@link #getMessage()} method).
21 | * @param cause the cause (which is saved for later retrieval by the
22 | * {@link #getCause()} method). (A {@code null} value is
23 | * permitted, and indicates that the cause is nonexistent or
24 | * unknown.)
25 | */
26 | public PageLoadRendererTimeoutException(String message, Throwable cause) {
27 | super(message, cause);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/PageNotLoadedException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import java.lang.reflect.Method;
4 | import java.util.concurrent.Callable;
5 |
6 | import org.openqa.selenium.NoSuchElementException;
7 | import org.openqa.selenium.NotFoundException;
8 |
9 | import com.nordstrom.automation.selenium.interfaces.DetectsLoadCompletion;
10 | import com.nordstrom.automation.selenium.model.ComponentContainer;
11 | import com.nordstrom.automation.selenium.model.ContainerMethodInterceptor;
12 | import com.nordstrom.automation.selenium.model.Page;
13 | import com.nordstrom.automation.selenium.support.Coordinator;
14 |
15 | /**
16 | * This exception is thrown by implementations of {@link DetectsLoadCompletion#isLoadComplete()} to indicate that
17 | * loading of the page is not yet complete. The determination of page-load conditions is scenario-specific and may
18 | * include the use of {@link ComponentContainer#checkPageLoadCondition(Coordinator, String)}, which facilitates
19 | * the use of predefined condition evaluation functions for page-load checking.
20 | *
21 | * The condition-polling mechanism employed by
22 | * {@link ContainerMethodInterceptor#intercept(Object, Method, Object[], Callable)} records instances of this
23 | * exception, but will continue to poll until {@link DetectsLoadCompletion#isLoadComplete()} completes without
24 | * exception or time runs out. Note that it's not necessary to wrap instances of {@link NotFoundException}
25 | * (e.g. - {@link NoSuchElementException}) with this exception, as these are automatically handled by
26 | * {@link ComponentContainer#waitForLandingPage(Page)}.
27 | */
28 | public class PageNotLoadedException extends RuntimeException {
29 | private static final long serialVersionUID = -8491929915611599716L;
30 |
31 | /**
32 | * Constructor for {@code page not loaded} exception with specified detail message.
33 | *
34 | * @param message detail message
35 | */
36 | public PageNotLoadedException(final String message) {
37 | super(message);
38 | }
39 |
40 | /**
41 | * Constructor for {@code page not loaded} exception with specified cause.
42 | *
43 | * @param cause cause of this exception
44 | */
45 | public PageNotLoadedException(final Throwable cause) {
46 | super(cause);
47 | }
48 |
49 | /**
50 | * Constructor for {@code page not loaded} exception with specified detail message and cause.
51 | *
52 | * @param message detail message
53 | * @param cause cause of this exception
54 | */
55 | public PageNotLoadedException(final String message, final Throwable cause) {
56 | super(message, cause);
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/PageTransitionRefreshTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.model.ContainerMethodInterceptor;
6 |
7 | /**
8 | * This exception is associated with {@link ContainerMethodInterceptor#intercept(Object, Method, Object[], Callable)}
9 | * and indicates that the parent page reference element failed to go "stale" within the timeout interval.
10 | */
11 | public class PageTransitionRefreshTimeoutException extends TimeoutException {
12 |
13 | private static final long serialVersionUID = 6396536840195276179L;
14 |
15 | /**
16 | * Constructor for a new "page transition refresh" timeout exception with
17 | * the specified message and cause.
18 | *
19 | * @param message the detail message (which is saved for later retrieval
20 | * by the {@link #getMessage()} method).
21 | * @param cause the cause (which is saved for later retrieval by the
22 | * {@link #getCause()} method). (A {@code null} value is
23 | * permitted, and indicates that the cause is nonexistent or
24 | * unknown.)
25 | */
26 | public PageTransitionRefreshTimeoutException(String message, Throwable cause) {
27 | super(message, cause);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/PlatformActivationFailedException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 |
5 | import com.nordstrom.automation.selenium.platform.PlatformEnum;
6 | import com.nordstrom.automation.selenium.platform.PlatformTargetable;
7 |
8 | /**
9 | * This exception is thrown by implementation of the {@link PlatformTargetable#activatePlatform activatePlatform}
10 | * method to indicate that platform activation failed.
11 | *
12 | */
13 | public class PlatformActivationFailedException extends RuntimeException {
14 |
15 | private static final long serialVersionUID = 7336291801605667538L;
16 | private static final String TEMPLATE = "Failed to activate target platform '%s'";
17 |
18 | /**
19 | * Constructor for {@code platform activation failed} exception with the specified platform and optional details.
20 | *
21 | * @param platform platform to be activated
22 | * @param details [optional] message details
23 | */
24 | public PlatformActivationFailedException(final PlatformEnum platform, final String... details) {
25 | super(getMessage(platform, details));
26 | }
27 |
28 | /**
29 | * Constructor for {@code platform activation failed} exception with the specified platform, underlying cause, and
30 | * optional details.
31 | *
32 | * @param platform platform to be activated
33 | * @param cause underlying cause for activation failure
34 | * @param details [optional] message details
35 | */
36 | public PlatformActivationFailedException(
37 | final PlatformEnum platform, final Throwable cause, final String... details) {
38 | super(getMessage(platform, details), cause);
39 | }
40 |
41 | /**
42 | * Get exception message to the specified platform with optional details.
43 | *
44 | * @param platform platform to be activated
45 | * @param details [optional] message details
46 | * @return exception message to the specified platform
47 | */
48 | private static String getMessage(final PlatformEnum platform, String... details) {
49 | String appendix = (details.length == 0) ? "" : "\n" + StringUtils.join(details, "\n");
50 | return String.format(TEMPLATE, platform.getName()) + appendix;
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/ShadowRootContextException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import com.nordstrom.automation.selenium.model.ShadowRoot;
4 |
5 | /**
6 | * This exception is throw during instantiation of {@link ShadowRoot} page components if the indicated root
7 | * element is not a shadow host or has 'closed' shadow-DOM mode.
8 | */
9 | public class ShadowRootContextException extends RuntimeException {
10 |
11 | private static final long serialVersionUID = -2655316241833901377L;
12 |
13 | /**
14 | * Constructor for {@code shadow root context} exception.
15 | */
16 | public ShadowRootContextException() {
17 | super("Context is not a shadow host or has 'closed' shadow-DOM mode");
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/TransitionErrorException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.SearchContext;
4 | import org.openqa.selenium.WebDriver;
5 |
6 | import com.nordstrom.automation.selenium.interfaces.TransitionErrorDetector;
7 | import com.nordstrom.automation.selenium.model.ComponentContainer;
8 | import com.nordstrom.automation.selenium.model.ContainerMethodInterceptor;
9 | import com.nordstrom.automation.selenium.model.Enhanceable;
10 |
11 | /**
12 | * This exception is thrown by {@link ContainerMethodInterceptor#scanForErrors(SearchContext)} when a registered
13 | * {@link TransitionErrorDetector} service provider detects an error.
14 | */
15 | public class TransitionErrorException extends IllegalStateException {
16 |
17 | /** exception error message */
18 | private final String errorMessage;
19 | private static final long serialVersionUID = -2969607575378647073L;
20 |
21 | /**
22 | * Constructor for {@code transition error} exception.
23 | *
24 | * @param context container context in which the error was detected
25 | * @param errorMessage error message
26 | */
27 | public TransitionErrorException(ComponentContainer context, String errorMessage) {
28 | super(buildMessage(context, errorMessage));
29 | this.errorMessage = errorMessage;
30 | }
31 |
32 | /**
33 | * Get message for this transition error.
34 | *
35 | * @return transition error message
36 | */
37 | public String getErrorMessage() {
38 | return errorMessage;
39 | }
40 |
41 | /**
42 | * Build the message for this transition error exception.
43 | *
44 | * @param context container context in which the error was detected
45 | * @param errorMessage error message
46 | * @return transition error exception message
47 | */
48 | private static String buildMessage(ComponentContainer context, String errorMessage) {
49 | StringBuilder builder = new StringBuilder("Transition error detected: ").append(errorMessage);
50 | builder.append("\nContainer: ").append(Enhanceable.getContainerClass(context).getName());
51 | WebDriver driver = context.getWrappedDriver();
52 | if (driver != null) {
53 | String pageUrl = driver.getCurrentUrl();
54 | if (pageUrl != null) {
55 | builder.append("\nPage URL: ").append(pageUrl);
56 | }
57 | String pageTitle = driver.getTitle();
58 | if (pageTitle != null) {
59 | builder.append("\nPage title: ").append(pageTitle);
60 | }
61 | }
62 | return builder.toString();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/UnknownGridHostException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import java.net.UnknownHostException;
4 |
5 | /**
6 | * This exception indicates that the configured Selenium Grid server host name couldn't be resolved to an IP address.
7 | */
8 | public class UnknownGridHostException extends RuntimeException {
9 |
10 | private static final long serialVersionUID = -3037697283479571401L;
11 | private static final String TEMPLATE = "Specified Selenium Grid %s host '%s' was not found";
12 |
13 | /**
14 | * Constructor for {@code unknown host} exception with the specified role and host name.
15 | *
16 | * @param role Grid server role specifier ({@code hub} or {@code node})
17 | * @param hostName Grid server host name
18 | * @param cause the cause of this exception
19 | */
20 | public UnknownGridHostException(final String role, final String hostName, final UnknownHostException cause) {
21 | super(getMessage(role, hostName), cause);
22 | }
23 |
24 | /**
25 | * Get exception message to the specified role and host name.
26 | *
27 | * @param role Grid server role specifier ({@code hub} or {@code node})
28 | * @param hostName Grid server host name
29 | * @return exception message to the specified role and host name
30 | */
31 | private static String getMessage(final String role, final String hostName) {
32 | return String.format(TEMPLATE, role, hostName);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/VacationStackTrace.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import java.lang.reflect.Method;
4 |
5 | import com.nordstrom.automation.selenium.utility.ReflectUtils;
6 | import com.nordstrom.common.base.StackTrace;
7 |
8 | /**
9 | * This exception is used to record the execution stack trace for the point at which the
10 | * associated container became invalid.
11 | *
12 | * @see ContainerVacatedException
13 | */
14 | public class VacationStackTrace extends StackTrace {
15 |
16 | private static final long serialVersionUID = -512001372372827847L;
17 |
18 | private final transient Method vacater;
19 | private final transient String reason;
20 | private static final String PREAMBLE = "Container object was vacated by invocation of method: ";
21 |
22 | /**
23 | * Constructs a new {@code container vacated} exception with the specified vacater.
24 | *
25 | * @param vacater method that caused the container to be vacated
26 | */
27 | public VacationStackTrace(final Method vacater) {
28 | this(vacater, null);
29 | }
30 |
31 | /**
32 | * Constructs a new {@code container vacated} exception with the specified vacater.
33 | *
34 | * @param vacater method that caused the container to be vacated
35 | * @param reason for vacating the target object
36 | */
37 | public VacationStackTrace(final Method vacater, final String reason) {
38 | super(getMessage(vacater, reason));
39 | this.vacater = vacater;
40 | this.reason = reason;
41 | }
42 |
43 | /**
44 | * Get the reason that the affected container object to be vacated.
45 | *
46 | * @return reason for vacating the target object
47 | */
48 | public String getReason() {
49 | return reason;
50 | }
51 |
52 | /**
53 | * Get the method that caused the affected container object to be vacated.
54 | *
55 | * @return method that vacated the target object
56 | */
57 | public Method getVacater() {
58 | return vacater;
59 | }
60 |
61 | /**
62 | * Assemble the message for this exception.
63 | *
64 | * @param method method that vacated the target object.
65 | * @param reason for vacating the target object
66 | * @return message for this exception
67 | */
68 | private static String getMessage(final Method method, final String reason) {
69 | String className = method.getDeclaringClass().getSimpleName();
70 | String signature = ReflectUtils.getSignature(method);
71 | String suffix = (reason != null) ? "\n" + reason : "";
72 | return PREAMBLE + className + ":" + signature + suffix;
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/exceptions/WindowStillExistsTimeoutException.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.exceptions;
2 |
3 | import org.openqa.selenium.TimeoutException;
4 |
5 | import com.nordstrom.automation.selenium.support.Coordinators;
6 |
7 | /**
8 | * This exception is associated with the {@link Coordinators#windowIsClosed(String)} condition and indicates that the
9 | * browser window with the specified window handle was still present when the timeout interval expired.
10 | */
11 | public class WindowStillExistsTimeoutException extends TimeoutException {
12 |
13 | private static final long serialVersionUID = 1228040448300937511L;
14 |
15 | /**
16 | * Constructor for a new "window still exists" timeout exception with
17 | * the specified message and cause.
18 | *
19 | * @param message the detail message (which is saved for later retrieval
20 | * by the {@link #getMessage()} method).
21 | * @param cause the cause (which is saved for later retrieval by the
22 | * {@link #getCause()} method). (A {@code null} value is
23 | * permitted, and indicates that the cause is nonexistent or
24 | * unknown.)
25 | */
26 | public WindowStillExistsTimeoutException(String message, Throwable cause) {
27 | super(message, cause);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/interfaces/DetectsLoadCompletion.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.interfaces;
2 |
3 | import org.openqa.selenium.SearchContext;
4 |
5 | import com.nordstrom.automation.selenium.model.ComponentContainer;
6 |
7 | /**
8 | * Page classes that model pages with complex loading behavior implement this interface to provide scenario-specific
9 | * detection of page load completion. This is typically required for single-page applications or more conventional
10 | * multi-page applications that use dynamic load techniques (e.g. - AJAX).
11 | */
12 | public interface DetectsLoadCompletion {
13 |
14 | /**
15 | * Determine if the page has finished loading.
16 | *
17 | * @return 'true' if the page has finished loading; otherwise 'false'
18 | */
19 | boolean isLoadComplete();
20 |
21 | /**
22 | * Get the container search context
23 | *
24 | * NOTE: This method is lifted from the {@link ComponentContainer} class.
25 | *
26 | * @return container search context
27 | */
28 | SearchContext getContext();
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/interfaces/DriverProvider.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.interfaces;
2 |
3 | import java.lang.reflect.Method;
4 |
5 | import org.openqa.selenium.WebDriver;
6 |
7 | /**
8 | * Test classes with non-standard driver configurations implement this interface, which enables the driver manager
9 | * to obtain a driver from the {@link #provideDriver(Method)} method of test class instance.
10 | */
11 | public interface DriverProvider {
12 |
13 | /**
14 | * Acquire a driver object for the specified method.
15 | * @param method the method being invoked
16 | *
17 | * @return driver object
18 | */
19 | WebDriver provideDriver(Method method);
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/interfaces/TransitionErrorDetector.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.interfaces;
2 |
3 | import com.nordstrom.automation.selenium.model.ComponentContainer;
4 |
5 | /**
6 | * This interface defines the method implemented by Selenium Foundation transition error detectors. These detectors are
7 | * registered via a ServiceLoader provider configuration file. Registered detectors are notified whenever a container
8 | * method returns a new container object.
9 | */
10 | public interface TransitionErrorDetector {
11 |
12 | /**
13 | * Scan the specified container context for transition errors.
14 | *
15 | * @param context container context to scan for errors
16 | * @return error message string; {@code null} if no errors are detected
17 | */
18 | String scanForErrors(ComponentContainer context);
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/interfaces/WrapsContext.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.interfaces;
2 |
3 | import org.openqa.selenium.SearchContext;
4 | import org.openqa.selenium.WrapsDriver;
5 |
6 | /**
7 | * Classes implement this interface to provide access to their underlying native Selenium
8 | * {@link SearchContext}. This interface also defines methods related to automatic recovery from
9 | * {@link org.openqa.selenium.StaleElementReferenceException StaleElementReferenceException}
10 | * failures.
11 | */
12 | public interface WrapsContext extends WrapsDriver {
13 |
14 | /**
15 | * Switch the driver to the context that underlies this object.
16 | *
17 | * @return this object's underlying search context
18 | */
19 | SearchContext switchTo();
20 |
21 | /**
22 | * Get the underlying search context for this object.
23 | *
24 | * @return object search context
25 | */
26 | SearchContext getWrappedContext();
27 |
28 | /**
29 | * Refresh the underlying search context for this object.
30 | *
31 | * @param expiration expiration time of context chain
32 | * @return object search context
33 | */
34 | SearchContext refreshContext(long expiration);
35 |
36 | /**
37 | * Determine when the underlying search context for this object was acquired.
38 | *
39 | * @return search context acquisition time (from {@link System#currentTimeMillis()})
40 | */
41 | long acquiredAt();
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/junit/DriverListener.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.junit;
2 |
3 | import com.nordstrom.automation.junit.ShutdownListener;
4 | import com.nordstrom.automation.selenium.core.DriverManager;
5 |
6 | /**
7 | * This class implements a driver shutdown listener.
8 | */
9 | public class DriverListener implements ShutdownListener {
10 |
11 | /**
12 | * {@inheritDoc}
13 | */
14 | @Override
15 | public void onShutdown() {
16 | DriverManager.onFinish();
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/junit/JUnitTargetBase.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.junit;
2 |
3 | import com.nordstrom.automation.selenium.platform.TargetType;
4 |
5 | /**
6 | * This class is a concrete subclass of {@link JUnitPlatformBase} specifying {@link TargetType} as the platform.
7 | */
8 | public class JUnitTargetBase extends JUnitPlatformBase {
9 |
10 | /**
11 | * Constructor for JUnit tests classes that support the {@link TargetType} platform.
12 | */
13 | public JUnitTargetBase() {
14 | super(TargetType.class);
15 | }
16 |
17 | /**
18 | * {@inheritDoc}
19 | */
20 | @Override
21 | public TargetType getDefaultPlatform() {
22 | return TargetType.SUPPORT;
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/junit/PageSourceArtifact.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.junit;
2 |
3 | import java.nio.file.Path;
4 | import java.util.Optional;
5 |
6 | import org.openqa.selenium.WebDriver;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import com.nordstrom.automation.selenium.core.DriverManager;
10 | import com.nordstrom.automation.selenium.utility.PageSourceUtils;
11 | import com.nordstrom.automation.junit.ArtifactType;
12 |
13 | /**
14 | * This class implements the artifact type for screenshot capture.
15 | */
16 | public class PageSourceArtifact extends ArtifactType {
17 |
18 | private static final String ARTIFACT_PATH = "page-source";
19 | private static final String EXTENSION = "html";
20 | private static final Logger LOGGER = LoggerFactory.getLogger(PageSourceArtifact.class);
21 |
22 | /**
23 | * {@inheritDoc}
24 | */
25 | @Override
26 | public boolean canGetArtifact(final Object instance) {
27 | Optional optDriver = DriverManager.nabDriver(instance);
28 | return PageSourceUtils.canGetArtifact(optDriver, LOGGER);
29 | }
30 |
31 | /**
32 | * {@inheritDoc}
33 | */
34 | @Override
35 | public byte[] getArtifact(final Object instance, final Throwable reason) {
36 | Optional optDriver = DriverManager.nabDriver(instance);
37 | return PageSourceUtils.getArtifact(optDriver, reason, LOGGER).getBytes();
38 | }
39 |
40 | /**
41 | * {@inheritDoc}
42 | */
43 | @Override
44 | public Path getArtifactPath(final Object instance) {
45 | return super.getArtifactPath(instance).resolve(ARTIFACT_PATH);
46 | }
47 |
48 | /**
49 | * {@inheritDoc}
50 | */
51 | @Override
52 | public String getArtifactExtension() {
53 | return EXTENSION;
54 | }
55 |
56 | /**
57 | * {@inheritDoc}
58 | */
59 | @Override
60 | public Logger getLogger() {
61 | return LOGGER;
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/junit/PageSourceCapture.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.junit;
2 |
3 | import com.nordstrom.automation.junit.ArtifactCollector;
4 |
5 | /**
6 | * This class uses the {@link ArtifactCollector} to implement a page source capturing test watcher.
7 | */
8 | public class PageSourceCapture extends ArtifactCollector {
9 |
10 | /**
11 | * This constructor provides a {@link PageSourceArtifact} object to the {@link ArtifactCollector}.
12 | *
13 | * @param instance JUnit test class instance
14 | */
15 | public PageSourceCapture(final Object instance) {
16 | super(instance, new PageSourceArtifact());
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/junit/RetryAnalyzer.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.junit;
2 |
3 | import org.junit.runners.model.FrameworkMethod;
4 | import org.openqa.selenium.WebDriverException;
5 |
6 | import com.nordstrom.automation.junit.JUnitRetryAnalyzer;
7 |
8 | /**
9 | * This class implements a Selenium-specific JUnit retry analyzer.
10 | */
11 | public class RetryAnalyzer implements JUnitRetryAnalyzer {
12 |
13 | /**
14 | * {@inheritDoc}
15 | *
16 | * This implementation deems that a test that fails with an instance of {@link WebDriverException} is re-triable.
17 | */
18 | @Override
19 | public boolean retry(FrameworkMethod method, Throwable thrown) {
20 | return (thrown instanceof WebDriverException);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/junit/ScreenshotArtifact.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.junit;
2 |
3 | import java.nio.file.Path;
4 | import java.util.Optional;
5 |
6 | import org.openqa.selenium.WebDriver;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import com.nordstrom.automation.selenium.core.DriverManager;
10 | import com.nordstrom.automation.selenium.utility.ScreenshotUtils;
11 | import com.nordstrom.automation.junit.ArtifactType;
12 |
13 | /**
14 | * This class implements the artifact type for screenshot capture.
15 | */
16 | public class ScreenshotArtifact extends ArtifactType {
17 |
18 | private static final String ARTIFACT_PATH = "screenshots";
19 | private static final String EXTENSION = "png";
20 | private static final Logger LOGGER = LoggerFactory.getLogger(ScreenshotArtifact.class);
21 |
22 | /**
23 | * {@inheritDoc}
24 | */
25 | @Override
26 | public boolean canGetArtifact(final Object instance) {
27 | Optional optDriver = DriverManager.nabDriver(instance);
28 | return ScreenshotUtils.canGetArtifact(optDriver, LOGGER);
29 | }
30 |
31 | /**
32 | * {@inheritDoc}
33 | */
34 | @Override
35 | public byte[] getArtifact(final Object instance, final Throwable reason) {
36 | Optional optDriver = DriverManager.nabDriver(instance);
37 | return ScreenshotUtils.getArtifact(optDriver, reason, LOGGER);
38 | }
39 |
40 | /**
41 | * {@inheritDoc}
42 | */
43 | @Override
44 | public Path getArtifactPath(final Object instance) {
45 | return super.getArtifactPath(instance).resolve(ARTIFACT_PATH);
46 | }
47 |
48 | /**
49 | * {@inheritDoc}
50 | */
51 | @Override
52 | public String getArtifactExtension() {
53 | return EXTENSION;
54 | }
55 |
56 | /**
57 | * {@inheritDoc}
58 | */
59 | @Override
60 | public Logger getLogger() {
61 | return LOGGER;
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/junit/ScreenshotCapture.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.junit;
2 |
3 | import com.nordstrom.automation.junit.ArtifactCollector;
4 |
5 | /**
6 | * This class uses the {@link ArtifactCollector} to implement a screenshot capturing test watcher.
7 | */
8 | public class ScreenshotCapture extends ArtifactCollector {
9 |
10 | /**
11 | * This constructor provides a {@link ScreenshotArtifact} object to the {@link ArtifactCollector}.
12 | *
13 | * @param instance JUnit test class instance
14 | */
15 | public ScreenshotCapture(final Object instance) {
16 | super(instance, new ScreenshotArtifact());
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/listeners/PageSourceArtifact.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.listeners;
2 |
3 | import java.nio.file.Path;
4 | import java.util.Optional;
5 |
6 | import org.openqa.selenium.WebDriver;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.testng.ITestResult;
10 | import org.testng.Reporter;
11 |
12 | import com.nordstrom.automation.selenium.core.DriverManager;
13 | import com.nordstrom.automation.selenium.utility.PageSourceUtils;
14 | import com.nordstrom.automation.testng.ArtifactType;
15 |
16 | /**
17 | * This class implements the artifact type for screenshot capture.
18 | */
19 | public class PageSourceArtifact extends ArtifactType {
20 |
21 | private static final String ARTIFACT_PATH = "page-source";
22 | private static final String EXTENSION = "html";
23 | private static final Logger LOGGER = LoggerFactory.getLogger(PageSourceArtifact.class);
24 |
25 | /**
26 | * {@inheritDoc}
27 | */
28 | @Override
29 | public boolean canGetArtifact(final ITestResult result) {
30 | // ensure current test result is set
31 | Reporter.setCurrentTestResult(result);
32 | Optional optDriver = DriverManager.nabDriver(result.getInstance());
33 | return PageSourceUtils.canGetArtifact(optDriver, LOGGER);
34 | }
35 |
36 | /**
37 | * {@inheritDoc}
38 | */
39 | @Override
40 | public byte[] getArtifact(final ITestResult result) {
41 | // ensure current test result is set
42 | Reporter.setCurrentTestResult(result);
43 | Optional optDriver = DriverManager.nabDriver(result.getInstance());
44 | return PageSourceUtils.getArtifact(optDriver, result.getThrowable(), LOGGER).getBytes();
45 | }
46 |
47 | /**
48 | * {@inheritDoc}
49 | */
50 | @Override
51 | public Path getArtifactPath(final ITestResult result) {
52 | return super.getArtifactPath(result).resolve(ARTIFACT_PATH);
53 | }
54 |
55 | /**
56 | * {@inheritDoc}
57 | */
58 | @Override
59 | public String getArtifactExtension() {
60 | return EXTENSION;
61 | }
62 |
63 | /**
64 | * {@inheritDoc}
65 | */
66 | @Override
67 | public Logger getLogger() {
68 | return LOGGER;
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/listeners/PageSourceCapture.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.listeners;
2 |
3 | import com.nordstrom.automation.testng.ArtifactCollector;
4 |
5 | /**
6 | * This class uses the {@link ArtifactCollector} to implement a page source capturing listener.
7 | */
8 | public class PageSourceCapture extends ArtifactCollector {
9 |
10 | /**
11 | * This constructor provides a {@link PageSourceArtifact} object to the {@link ArtifactCollector}.
12 | */
13 | public PageSourceCapture() {
14 | super(new PageSourceArtifact());
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/listeners/ScreenshotArtifact.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.listeners;
2 |
3 | import java.nio.file.Path;
4 | import java.util.Optional;
5 |
6 | import org.openqa.selenium.WebDriver;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.testng.ITestResult;
10 | import org.testng.Reporter;
11 |
12 | import com.nordstrom.automation.selenium.core.DriverManager;
13 | import com.nordstrom.automation.selenium.utility.ScreenshotUtils;
14 | import com.nordstrom.automation.testng.ArtifactType;
15 |
16 | /**
17 | * This class implements the artifact type for screenshot capture.
18 | */
19 | public class ScreenshotArtifact extends ArtifactType {
20 |
21 | private static final String ARTIFACT_PATH = "screenshots";
22 | private static final String EXTENSION = "png";
23 | private static final Logger LOGGER = LoggerFactory.getLogger(ScreenshotArtifact.class);
24 |
25 | /**
26 | * {@inheritDoc}
27 | */
28 | @Override
29 | public boolean canGetArtifact(final ITestResult result) {
30 | // ensure current test result is set
31 | Reporter.setCurrentTestResult(result);
32 | Optional optDriver = DriverManager.nabDriver(result.getInstance());
33 | return ScreenshotUtils.canGetArtifact(optDriver, LOGGER);
34 | }
35 |
36 | /**
37 | * {@inheritDoc}
38 | */
39 | @Override
40 | public byte[] getArtifact(final ITestResult result) {
41 | // ensure current test result is set
42 | Reporter.setCurrentTestResult(result);
43 | Optional optDriver = DriverManager.nabDriver(result.getInstance());
44 | return ScreenshotUtils.getArtifact(optDriver, result.getThrowable(), LOGGER);
45 | }
46 |
47 | /**
48 | * {@inheritDoc}
49 | */
50 | @Override
51 | public Path getArtifactPath(final ITestResult result) {
52 | return super.getArtifactPath(result).resolve(ARTIFACT_PATH);
53 | }
54 |
55 | /**
56 | * {@inheritDoc}
57 | */
58 | @Override
59 | public String getArtifactExtension() {
60 | return EXTENSION;
61 | }
62 |
63 | /**
64 | * {@inheritDoc}
65 | */
66 | @Override
67 | public Logger getLogger() {
68 | return LOGGER;
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/listeners/ScreenshotCapture.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.listeners;
2 |
3 | import com.nordstrom.automation.testng.ArtifactCollector;
4 |
5 | /**
6 | * This class uses the {@link ArtifactCollector} to implement a screenshot capturing listener.
7 | */
8 | public class ScreenshotCapture extends ArtifactCollector {
9 |
10 | /**
11 | * This constructor provides a {@link ScreenshotArtifact} object to the {@link ArtifactCollector}.
12 | */
13 | public ScreenshotCapture() {
14 | super(new ScreenshotArtifact());
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/model/ComponentList.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.model;
2 |
3 | import org.openqa.selenium.By;
4 |
5 | /**
6 | * This class defines a list for Selenium Foundation page component objects.
7 | *
8 | * NOTE: This class implements a read-only list; all methods that would alter the composition of the collection
9 | * (e.g. - {@link #add(Object)}) result in {@link UnsupportedOperationException}.
10 | *
11 | * @param the class of page component objects collected by this list
12 | */
13 | public class ComponentList extends ContainerList {
14 |
15 | /**
16 | * Constructor for component list with parent, type, and locator
17 | *
18 | * @param parent parent container
19 | * @param containerType container type
20 | * @param locator container context element locator
21 | */
22 | ComponentList(final ComponentContainer parent, final Class componentType, final By locator) {
23 | super(parent, componentType, locator);
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/model/ComponentMap.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.model;
2 |
3 | import org.openqa.selenium.By;
4 |
5 | /**
6 | * This class defines a map for Selenium Foundation page component objects.
7 | *
8 | * NOTE: This class implements a read-only map; all methods that would alter the composition of the collection
9 | * (e.g. - {@link #put(Object, Object)}) result in {@link UnsupportedOperationException}.
10 | *
11 | * @param the class of page component objects collected by this map
12 | */
13 | public class ComponentMap extends ContainerMap {
14 |
15 | /**
16 | * Constructor for component map with parent, type, and locator
17 | *
18 | * @param parent parent container
19 | * @param containerType container type
20 | * @param locator container context element locator
21 | */
22 | ComponentMap(final ComponentContainer parent, final Class containerType, final By locator) {
23 | super(parent, containerType, locator);
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/model/Enhanced.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.model;
2 |
3 | /**
4 | * This marker interface is added to dynamically created classes for future identification
5 | */
6 | public interface Enhanced { }
7 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/model/FrameList.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.model;
2 |
3 | import org.openqa.selenium.By;
4 |
5 | /**
6 | * This class defines a list for Selenium Foundation frame objects.
7 | *
8 | * NOTE: This class implements a read-only list; all methods that would alter the composition of the collection
9 | * (e.g. - {@link #add(Object)}) result in {@link UnsupportedOperationException}.
10 | *
11 | * @param the class of frame objects collected by this list
12 | */
13 | public class FrameList extends ContainerList {
14 |
15 | /**
16 | * Constructor for frame list with parent, type, and locator
17 | *
18 | * @param parent parent container
19 | * @param containerType container type
20 | * @param locator container context element locator
21 | */
22 | FrameList(final ComponentContainer parent, final Class containerType, final By locator) {
23 | super(parent, containerType, locator);
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/model/FrameMap.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.model;
2 |
3 | import org.openqa.selenium.By;
4 |
5 | /**
6 | * This class defines a map for Selenium Foundation frame objects.
7 | *
8 | * NOTE: This class implements a read-only map; all methods that would alter the composition of the collection
9 | * (e.g. - {@link #put(Object, Object)}) result in {@link UnsupportedOperationException}.
10 | *
11 | * @param the class of frame objects collected by this map
12 | */
13 | public class FrameMap extends ContainerMap {
14 |
15 | /**
16 | * Constructor for frame map with parent, type, and locator
17 | *
18 | * @param parent parent container
19 | * @param containerType container type
20 | * @param locator container context element locator
21 | */
22 | FrameMap(final ComponentContainer parent, final Class containerType, final By locator) {
23 | super(parent, containerType, locator);
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/model/ReferenceFetcher.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.model;
2 |
3 | import org.openqa.selenium.By;
4 | import org.openqa.selenium.SearchContext;
5 | import org.openqa.selenium.StaleElementReferenceException;
6 | import org.openqa.selenium.WebElement;
7 | import org.openqa.selenium.WrapsElement;
8 |
9 | import com.nordstrom.automation.selenium.interfaces.WrapsContext;
10 |
11 | /**
12 | * This interface defines the methods that are added to {@link WebElement} to create {@link RobustElementWrapper}.
13 | */
14 | public interface ReferenceFetcher extends SearchContext, WrapsElement, WrapsContext, Enhanced {
15 |
16 | /**
17 | * Get a wrapped reference to the first element matching the specified locator.
18 | *
19 | * NOTE: Use {@link ReferenceFetcher#hasReference()} to determine if a valid reference was acquired.
20 | *
21 | * @param by the locating mechanism
22 | * @return robust web element
23 | */
24 | WebElement findOptional(By by);
25 |
26 | /**
27 | * Determine if this robust element wraps a valid reference.
28 | *
29 | * @return 'true' if reference was acquired; otherwise 'false'
30 | */
31 | boolean hasReference();
32 |
33 | /**
34 | * Get the search context for this element.
35 | *
36 | * @return element search context
37 | */
38 | WrapsContext getContext();
39 |
40 | /**
41 | * Get the locator for this element.
42 | *
43 | * @return element locator
44 | */
45 | By getLocator();
46 |
47 | /**
48 | * Get the element index.
49 | *
50 | * NOTE: {@link RobustElementWrapper#CARDINAL CARDINAL} = 1st matched reference;
51 | * {@link RobustElementWrapper#OPTIONAL OPTIONAL} = an optional reference
52 | *
53 | * @return element index (see NOTE)
54 | */
55 | int getIndex();
56 |
57 | /**
58 | * Refresh the wrapped element reference.
59 | *
60 | * @param refreshTrigger {@link StaleElementReferenceException} that necessitates reference refresh
61 | * @return this robust element wrapper with refreshed reference
62 | */
63 | RobustElementWrapper refreshReference(StaleElementReferenceException refreshTrigger);
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/model/RobustWebElement.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.model;
2 |
3 | import org.openqa.selenium.WebElement;
4 |
5 | /**
6 | * This interface declares the public API for "robust" web elements, adding the reference-refreshing methods of the
7 | * {@link ReferenceFetcher} interface to the standard {@link WebElement} interface.
8 | */
9 | public interface RobustWebElement extends WebElement, ReferenceFetcher {
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/model/ShadowRootList.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.model;
2 |
3 | import org.openqa.selenium.By;
4 |
5 | /**
6 | * This class defines a list for Selenium Foundation shadow root objects.
7 | *
8 | * NOTE: This class implements a read-only list; all methods that would alter the composition of the collection
9 | * (e.g. - {@link #add(Object)}) result in {@link UnsupportedOperationException}.
10 | *
11 | * @param the class of shadow root objects collected by this list
12 | */
13 | public class ShadowRootList extends ContainerList {
14 |
15 | /**
16 | * Constructor for shadow root list with parent, type, and locator
17 | *
18 | * @param parent parent container
19 | * @param containerType container type
20 | * @param locator container context element locator
21 | */
22 | ShadowRootList(final ComponentContainer parent, final Class containerType, final By locator) {
23 | super(parent, containerType, locator);
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/model/ShadowRootMap.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.model;
2 |
3 | import org.openqa.selenium.By;
4 |
5 | /**
6 | * This class defines a map for Selenium Foundation shadow root objects.
7 | *
8 | * NOTE: This class implements a read-only map; all methods that would alter the composition of the collection
9 | * (e.g. - {@link #put(Object, Object)}) result in {@link UnsupportedOperationException}.
10 | *
11 | * @param the class of shadow root objects collected by this map
12 | */
13 | public class ShadowRootMap extends ContainerMap {
14 |
15 | /**
16 | * Constructor for shadow root map with parent, type, and locator
17 | *
18 | * @param parent parent container
19 | * @param containerType container type
20 | * @param locator container context element locator
21 | */
22 | ShadowRootMap(final ComponentContainer parent, final Class containerType, final By locator) {
23 | super(parent, containerType, locator);
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/platform/PlatformEnum.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.platform;
2 |
3 | /**
4 | * This interface provides common methods for collections of platform constants.
5 | */
6 | public interface PlatformEnum {
7 |
8 | /**
9 | * Get name of platform constant.
10 | *
11 | * @return platform constant name
12 | */
13 | String getName();
14 |
15 | /**
16 | * Determine if the specified context platform matches this constant.
17 | *
18 | * @param contextPlatform active context platform
19 | * @return 'true' if this constant matches the specified context platform; otherwise 'false'
20 | */
21 | boolean matches(String contextPlatform);
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/platform/PlatformTargetable.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.platform;
2 |
3 | import org.openqa.selenium.WebDriver;
4 |
5 | import com.nordstrom.automation.selenium.exceptions.PlatformActivationFailedException;
6 | import com.nordstrom.common.file.PathUtils.PathModifier;
7 |
8 | /**
9 | * Test classes that implement this interface are afforded the ability to specify the platform(s) supported by each
10 | * of its test methods. Each test method can specify one or more target platform on which it should run. At run-time,
11 | * the test flow controller determines which test methods should run on the current target platform, only including
12 | * those test methods that support that platform.
13 | *
14 | * @param platform specifier
15 | */
16 | public interface PlatformTargetable
& PlatformEnum> extends PathModifier {
17 |
18 | /**
19 | * Get the target platform for this test class instance.
20 | *
21 | * @return target platform for this instance
22 | */
23 | P getTargetPlatform();
24 |
25 | /**
26 | * Activate the specified target platform.
27 | *
28 | * @param driver WebDriver object (may be {@code null})
29 | * @param platform platform to be activated
30 | * @throws PlatformActivationFailedException if platform activation fails
31 | */
32 | void activatePlatform(WebDriver driver, P platform) throws PlatformActivationFailedException;
33 |
34 | /**
35 | * Get the collection of valid platforms.
36 | *
37 | * @return array of valid platform constants
38 | */
39 | P[] getValidPlatforms();
40 |
41 | /**
42 | * Get the default platform specifier.
43 | *
44 | * @return default platform constant
45 | */
46 | P getDefaultPlatform();
47 |
48 | /**
49 | * Convert the specified platform name to the corresponding constant.
50 | *
51 | * @param name platform name
52 | * @return platform constant; 'null' for unsupported names
53 | */
54 | P platformFromString(String name);
55 |
56 | /**
57 | * Get data type of platform enumeration.
58 | *
59 | * @return data type of platform enumeration
60 | */
61 | Class
getPlatformType();
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/platform/TargetPlatform.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.platform;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * This annotation is used to describe what target platform the test will be run against.
10 | */
11 | @Target(ElementType.METHOD)
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface TargetPlatform {
14 | /**
15 | * Get platform name.
16 | *
17 | * @return platform name
18 | */
19 | String value();
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/platform/TargetPlatformHandler.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.platform;
2 |
3 | /**
4 | * This class contains support methods used by our target platform implementation.
5 | */
6 | public class TargetPlatformHandler {
7 |
8 | /**
9 | * Resolve the target platform constant for the associated method.
10 | *
11 | * @param
target platform enumeration
12 | * @param testObject test class object
13 | * @param targetPlatform {@link TargetPlatform} annotation for the current method (may be 'null')
14 | * @return target platform constant; 'null' if test class object is not {@link PlatformTargetable}
15 | */
16 | @SuppressWarnings("unchecked")
17 | public static
& PlatformEnum> P resolveTargetPlatform(Object testObject, TargetPlatform targetPlatform) {
18 | P platform = null;
19 |
20 | if (testObject instanceof PlatformTargetable) {
21 | if (targetPlatform == null) {
22 | platform = ((PlatformTargetable
) testObject).getDefaultPlatform();
23 | } else {
24 | platform = ((PlatformTargetable
) testObject).platformFromString(targetPlatform.value());
25 | }
26 | }
27 |
28 | return platform;
29 | }
30 |
31 | /**
32 | * Determine if the associated method should run on the specified target platform.
33 | *
34 | * NOTE: The method is runnable if the test class implements {@link PlatformTargetable} and the method
35 | * supports the specified target platform. If the method has no {@link TargetPlatform @TargetPlatform} annotation,
36 | * it is assumed to support the implementation-defined 'default' platform. If the test class doesn't implement
37 | * PlatformTargetable, the method is runnable if the CONTEXT_PLATFORM setting matches the specified target
38 | * platform.
39 | *
40 | * @param contextPlatform active context platform
41 | * @param platformConstant {@link PlatformEnum} constant for the current method
42 | * @return 'true' if the associated method should run on the specified target platform; otherwise 'false'
43 | */
44 | public static boolean shouldRun(String contextPlatform, PlatformEnum platformConstant) {
45 | if ((contextPlatform != null) && (platformConstant != null)) {
46 | return platformConstant.matches(contextPlatform);
47 | }
48 | return true;
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/platform/TargetPlatformRule.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.platform;
2 |
3 | import org.junit.AssumptionViolatedException;
4 | import org.junit.rules.TestRule;
5 | import org.junit.runner.Description;
6 | import org.junit.runners.model.Statement;
7 |
8 | import com.nordstrom.automation.selenium.SeleniumConfig;
9 |
10 | /**
11 | * This class implements a JUnit test rule that performs target platform method filtering.
12 | *
13 | * @param
platform specifier
14 | */
15 | public class TargetPlatformRule
& PlatformEnum> implements TestRule {
16 |
17 | private Object testObject;
18 | private P platform;
19 |
20 | /**
21 | * Constructor for target platform method rule objects.
22 | *
23 | * @param testObject test class instance
24 | */
25 | public TargetPlatformRule(Object testObject) {
26 | this.testObject = testObject;
27 | }
28 |
29 | /**
30 | * {@inheritDoc}
31 | */
32 | @Override
33 | public Statement apply(final Statement base, final Description description) {
34 | if (!description.isTest()) return base;
35 |
36 | final String contextPlatform = SeleniumConfig.getConfig().getContextPlatform();
37 | final TargetPlatform targetPlatform = description.getAnnotation(TargetPlatform.class);
38 |
39 | platform = TargetPlatformHandler.resolveTargetPlatform(testObject, targetPlatform);
40 |
41 | if (TargetPlatformHandler.shouldRun(contextPlatform, platform)) {
42 | return base;
43 | } else {
44 | return new Statement() {
45 | @Override
46 | public void evaluate() throws Throwable {
47 | String message = String.format("%s.%s() doesn't specify platform '%s'",
48 | description.getClassName(), description.getMethodName(), contextPlatform);
49 | throw new AssumptionViolatedException(message);
50 | }
51 | };
52 | }
53 | }
54 |
55 | /**
56 | * Get platform specifier for this test rule.
57 | *
58 | * @return platform specified
59 | */
60 | public P getPlatform() {
61 | return platform;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/platform/TargetTypeName.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.platform;
2 |
3 | import com.nordstrom.automation.selenium.plugins.EspressoPlugin;
4 | import com.nordstrom.automation.selenium.plugins.Mac2Plugin;
5 | import com.nordstrom.automation.selenium.plugins.RemoteWebDriverPlugin;
6 | import com.nordstrom.automation.selenium.plugins.UiAutomator2Plugin;
7 | import com.nordstrom.automation.selenium.plugins.WindowsPlugin;
8 | import com.nordstrom.automation.selenium.plugins.XCUITestPlugin;
9 |
10 | /**
11 | * This interface defines the names of the platforms supported by the Selenium Foundation unit tests.
12 | */
13 | public interface TargetTypeName extends PlatformEnum {
14 | /**
15 | * target: support feature
16 | * driver: (not-applicable)
17 | */
18 | String SUPPORT_NAME = "support";
19 |
20 | /**
21 | * target: web application
22 | * driver: {@link RemoteWebDriverPlugin}
23 | */
24 | String WEB_APP_NAME = "web-app";
25 |
26 | /**
27 | * target: Android application
28 | * driver: {@link UiAutomator2Plugin}, {@link EspressoPlugin}
29 | */
30 | String ANDROID_NAME = "android";
31 |
32 | /**
33 | * target: iOS application
34 | * driver: {@link XCUITestPlugin}
35 | */
36 | String IOS_APP_NAME = "ios-app";
37 |
38 | /**
39 | * target: Macintosh application
40 | * driver: {@link Mac2Plugin}
41 | */
42 | String MAC_APP_NAME = "mac-app";
43 |
44 | /**
45 | * target: Windows application
46 | * driver: {@link WindowsPlugin}
47 | */
48 | String WINDOWS_NAME = "windows";
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/plugins/EspressoPlugin.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.plugins;
2 |
3 | import java.util.Collections;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | import com.nordstrom.automation.selenium.SeleniumConfig;
8 |
9 | /**
10 | * This class is the plug-in for the Espresso engine of Appium
11 | */
12 | public class EspressoPlugin extends AbstractAppiumPlugin {
13 |
14 | /** driver name */
15 | public static final String DRIVER_NAME = "Espresso";
16 |
17 | /**
18 | * Constructor for EspressoPlugin objects.
19 | */
20 | public EspressoPlugin() {
21 | super(DRIVER_NAME);
22 | }
23 |
24 | private static final String CAPABILITIES =
25 | "{\"appium:automationName\":\"Espresso\",\"platformName\":\"Android\"}";
26 |
27 | private static final String BASELINE =
28 | "{\"appium:automationName\":\"Espresso\",\"platformName\":\"Android\"," +
29 | "\"nord:options\":{\"personality\":\"Espresso\"," +
30 | "\"pluginClass\":\"com.nordstrom.automation.selenium.plugins.EspressoPlugin\"}}";
31 |
32 | private static final Map PERSONALITIES;
33 |
34 | private static final String DRIVER_CLASS_NAME = "io.appium.java_client.android.AndroidDriver";
35 |
36 | static {
37 | Map personalities = new HashMap<>();
38 | personalities.put(DRIVER_NAME, BASELINE);
39 | PERSONALITIES = Collections.unmodifiableMap(personalities);
40 | }
41 |
42 | /**
43 | * {@inheritDoc}
44 | */
45 | @Override
46 | public String getCapabilities(SeleniumConfig config) {
47 | return addNordOptions(config, CAPABILITIES);
48 | }
49 |
50 | /**
51 | * {@inheritDoc}
52 | */
53 | @Override
54 | public Map getPersonalities() {
55 | return PERSONALITIES;
56 | }
57 |
58 | /**
59 | * {@inheritDoc}
60 | */
61 | @Override
62 | public String getDriverClassName() {
63 | return DRIVER_CLASS_NAME;
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/plugins/Mac2Plugin.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.plugins;
2 |
3 | import java.util.Collections;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | import com.nordstrom.automation.selenium.SeleniumConfig;
8 |
9 | /**
10 | * This class is the plug-in for the Mac2 engine of Appium
11 | */
12 | public class Mac2Plugin extends AbstractAppiumPlugin {
13 |
14 | /** driver name */
15 | public static final String DRIVER_NAME = "Mac2";
16 |
17 | /**
18 | * Constructor for Mac2Plugin objects.
19 | */
20 | public Mac2Plugin() {
21 | super(DRIVER_NAME);
22 | }
23 |
24 | private static final String CAPABILITIES =
25 | "{\"appium:automationName\":\"Mac2\",\"platformName\":\"Mac\"}";
26 |
27 | private static final String BASELINE =
28 | "{\"appium:automationName\":\"Mac2\",\"platformName\":\"Mac\"," +
29 | "\"nord:options\":{\"personality\":\"Mac2\"," +
30 | "\"pluginClass\":\"com.nordstrom.automation.selenium.plugins.Mac2Plugin\"}}";
31 |
32 | private static final Map PERSONALITIES;
33 |
34 | private static final String DRIVER_CLASS_NAME = "io.appium.java_client.mac.Mac2Driver";
35 |
36 | static {
37 | Map personalities = new HashMap<>();
38 | personalities.put(DRIVER_NAME, BASELINE);
39 | PERSONALITIES = Collections.unmodifiableMap(personalities);
40 | }
41 |
42 | /**
43 | * {@inheritDoc}
44 | */
45 | @Override
46 | public String getCapabilities(SeleniumConfig config) {
47 | return addNordOptions(config, CAPABILITIES);
48 | }
49 |
50 | /**
51 | * {@inheritDoc}
52 | */
53 | @Override
54 | public Map getPersonalities() {
55 | return PERSONALITIES;
56 | }
57 |
58 | /**
59 | * {@inheritDoc}
60 | */
61 | @Override
62 | public String getDriverClassName() {
63 | return DRIVER_CLASS_NAME;
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/plugins/UiAutomator2Plugin.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.plugins;
2 |
3 | import java.util.Collections;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | import com.nordstrom.automation.selenium.SeleniumConfig;
8 |
9 | /**
10 | * This class is the plug-in for the UiAutomator2 engine of Appium
11 | */
12 | public class UiAutomator2Plugin extends AbstractAppiumPlugin {
13 |
14 | /** driver name */
15 | public static final String DRIVER_NAME = "UiAutomator2";
16 |
17 | /**
18 | * Constructor for UiAutomator2Plugin objects.
19 | */
20 | public UiAutomator2Plugin() {
21 | super(DRIVER_NAME);
22 | }
23 |
24 | private static final String CAPABILITIES =
25 | "{\"appium:automationName\":\"UiAutomator2\",\"platformName\":\"Android\"}," +
26 | "{\"appium:automationName\":\"UiAutomator2\",\"platformName\":\"Android\",\"browserName\":\"chrome\"}";
27 |
28 | private static final String BASELINE =
29 | "{\"appium:automationName\":\"UiAutomator2\",\"platformName\":\"Android\"," +
30 | "\"nord:options\":{\"personality\":\"UiAutomator2\"," +
31 | "\"pluginClass\":\"com.nordstrom.automation.selenium.plugins.UiAutomator2Plugin\"}}";
32 |
33 | private static final String CHROME =
34 | "{\"appium:automationName\":\"UiAutomator2\",\"platformName\":\"Android\",\"browserName\":\"chrome\"," +
35 | "\"nord:options\":{\"personality\":\"UiAutomator2.chrome\"," +
36 | "\"pluginClass\":\"com.nordstrom.automation.selenium.plugins.UiAutomator2Plugin\"}}";
37 |
38 | private static final Map PERSONALITIES;
39 |
40 | private static final String DRIVER_CLASS_NAME = "io.appium.java_client.android.AndroidDriver";
41 |
42 | static {
43 | Map personalities = new HashMap<>();
44 | personalities.put(DRIVER_NAME, BASELINE);
45 | personalities.put(DRIVER_NAME + ".chrome", CHROME);
46 | PERSONALITIES = Collections.unmodifiableMap(personalities);
47 | }
48 |
49 | /**
50 | * {@inheritDoc}
51 | */
52 | @Override
53 | public String getCapabilities(SeleniumConfig config) {
54 | return addNordOptions(config, CAPABILITIES);
55 | }
56 |
57 | /**
58 | * {@inheritDoc}
59 | */
60 | @Override
61 | public Map getPersonalities() {
62 | return PERSONALITIES;
63 | }
64 |
65 | /**
66 | * {@inheritDoc}
67 | */
68 | @Override
69 | public String getDriverClassName() {
70 | return DRIVER_CLASS_NAME;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/plugins/WindowsPlugin.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.plugins;
2 |
3 | import java.util.Collections;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | import com.nordstrom.automation.selenium.SeleniumConfig;
8 |
9 | /**
10 | * This class is the plug-in for the Windows engine of Appium
11 | */
12 | public class WindowsPlugin extends AbstractAppiumPlugin {
13 |
14 | /** driver name */
15 | public static final String DRIVER_NAME = "Windows";
16 |
17 | /**
18 | * Constructor for WindowsPlugin objects.
19 | */
20 | public WindowsPlugin() {
21 | super(DRIVER_NAME);
22 | }
23 |
24 | private static final String CAPABILITIES =
25 | "{\"appium:automationName\":\"Windows\",\"platformName\":\"Windows\"}";
26 |
27 | private static final String BASELINE =
28 | "{\"appium:automationName\":\"Windows\",\"platformName\":\"Windows\"," +
29 | "\"nord:options\":{\"personality\":\"Windows\"," +
30 | "\"pluginClass\":\"com.nordstrom.automation.selenium.plugins.WindowsPlugin\"}}";
31 |
32 | private static final Map PERSONALITIES;
33 |
34 | private static final String DRIVER_CLASS_NAME = "io.appium.java_client.windows.WindowsDriver";
35 |
36 | static {
37 | Map personalities = new HashMap<>();
38 | personalities.put(DRIVER_NAME, BASELINE);
39 | PERSONALITIES = Collections.unmodifiableMap(personalities);
40 | }
41 |
42 | /**
43 | * {@inheritDoc}
44 | */
45 | @Override
46 | public String getCapabilities(SeleniumConfig config) {
47 | return addNordOptions(config, CAPABILITIES);
48 | }
49 |
50 | /**
51 | * {@inheritDoc}
52 | */
53 | @Override
54 | public Map getPersonalities() {
55 | return PERSONALITIES;
56 | }
57 |
58 | /**
59 | * {@inheritDoc}
60 | */
61 | @Override
62 | public String getDriverClassName() {
63 | return DRIVER_CLASS_NAME;
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/plugins/XCUITestPlugin.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.plugins;
2 |
3 | import java.util.Collections;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | import com.nordstrom.automation.selenium.SeleniumConfig;
8 |
9 | /**
10 | * This class is the plug-in for the XCUITest engine of Appium
11 | */
12 | public class XCUITestPlugin extends AbstractAppiumPlugin {
13 |
14 | /** driver name */
15 | public static final String DRIVER_NAME = "XCUITest";
16 |
17 | /**
18 | * Constructor for XCUITestPlugin objects.
19 | */
20 | public XCUITestPlugin() {
21 | super(DRIVER_NAME);
22 | }
23 |
24 | private static final String CAPABILITIES =
25 | "{\"appium:automationName\":\"XCUITest\",\"platformName\":\"iOS\",\"browserName\":\"Safari\"," +
26 | "\"appium:deviceName\":\"iPhone Simulator\"}";
27 |
28 | private static final String BASELINE =
29 | "{\"appium:automationName\":\"XCUITest\",\"platformName\":\"iOS\"," +
30 | "\"nord:options\":{\"personality\":\"XCUITest\"," +
31 | "\"pluginClass\":\"com.nordstrom.automation.selenium.plugins.XCUITestPlugin\"}}";
32 |
33 | private static final Map PERSONALITIES;
34 |
35 | private static final String DRIVER_CLASS_NAME = "io.appium.java_client.ios.IOSDriver";
36 |
37 | static {
38 | Map personalities = new HashMap<>();
39 | personalities.put(DRIVER_NAME, BASELINE);
40 | PERSONALITIES = Collections.unmodifiableMap(personalities);
41 | }
42 |
43 | /**
44 | * {@inheritDoc}
45 | */
46 | @Override
47 | public String getCapabilities(SeleniumConfig config) {
48 | return addNordOptions(config, CAPABILITIES);
49 | }
50 |
51 | /**
52 | * {@inheritDoc}
53 | */
54 | @Override
55 | public Map getPersonalities() {
56 | return PERSONALITIES;
57 | }
58 |
59 | /**
60 | * {@inheritDoc}
61 | */
62 | @Override
63 | public String getDriverClassName() {
64 | return DRIVER_CLASS_NAME;
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/support/Coordinator.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.support;
2 |
3 | import java.util.function.Function;
4 |
5 | import org.openqa.selenium.SearchContext;
6 | import org.openqa.selenium.TimeoutException;
7 |
8 | /**
9 | * Models a condition that might reasonably be expected to eventually evaluate to something that is
10 | * neither null nor false. Examples would include determining if a web page has loaded or that an
11 | * element is visible.
12 | *
13 | * Note that implementations of the Coordinator interface are expected to be idempotent. They will
14 | * be called in a loop by {@link SearchContextWait} and any modification of the state of the application
15 | * under test may have unexpected side-effects.
16 | *
17 | * @param The return type
18 | */
19 | public abstract class Coordinator implements Function {
20 |
21 | /**
22 | * This method can be overridden by implementations of {@link Coordinator} to provide a context-specific
23 | * timeout exception associated with the implemented condition.
24 | *
25 | * @param e The original {@link TimeoutException} object thrown by the framework "wait" implementation
26 | * @return an instance of a context-specific sub-class of {@link TimeoutException}
27 | */
28 | public TimeoutException differentiateTimeout(TimeoutException e) {
29 | return e;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/support/RetryAnalyzer.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.support;
2 |
3 | import org.openqa.selenium.WebDriverException;
4 | import org.testng.ITestResult;
5 |
6 | import com.nordstrom.automation.testng.TestNGRetryAnalyzer;
7 |
8 | /**
9 | * This class implements a Selenium-specific TestNG retry analyzer.
10 | */
11 | public class RetryAnalyzer implements TestNGRetryAnalyzer {
12 |
13 | /**
14 | * {@inheritDoc}
15 | *
16 | * This implementation deems that a test that fails with an instance of {@link WebDriverException} is re-triable.
17 | */
18 | @Override
19 | public boolean retry(ITestResult result) {
20 | return (result.getThrowable() instanceof WebDriverException);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/nordstrom/automation/selenium/support/TestNgTargetBase.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.support;
2 |
3 | import com.nordstrom.automation.selenium.platform.TargetType;
4 |
5 | /**
6 | * This class is a concrete subclass of {@link TestNgPlatformBase} specifying {@link TargetType} as the platform.
7 | */
8 | public class TestNgTargetBase extends TestNgPlatformBase {
9 |
10 | /**
11 | * Constructor for TestNG tests classes that support the {@link TargetType} platform.
12 | */
13 | public TestNgTargetBase() {
14 | super(TargetType.class);
15 | }
16 |
17 | /**
18 | * {@inheritDoc}
19 | */
20 | @Override
21 | public TargetType getDefaultPlatform() {
22 | return TargetType.SUPPORT;
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/resources/checkShadowHost.js:
--------------------------------------------------------------------------------
1 | var shadow = arguments[0].shadowRoot;
2 | if (shadow == null) throw "invalid shadow host";
3 |
--------------------------------------------------------------------------------
/src/main/resources/createScriptNode.js:
--------------------------------------------------------------------------------
1 | var head = document.getElementsByTagName('head')[0];
2 | var script = document.createElement('script');
3 | script.textContent = arguments[0];
4 | head.appendChild(script);
5 |
--------------------------------------------------------------------------------
/src/main/resources/documentReady.js:
--------------------------------------------------------------------------------
1 | return ((typeof window.jQuery == 'undefined') || ((window.jQuery.active == 0) && ($(':animated').length == 0)) && (document.readyState == 'complete'));
--------------------------------------------------------------------------------
/src/main/resources/frame_a.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Frame A Title
5 |
6 |
7 |
8 | Frame A
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/main/resources/frame_b.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Frame B Title
5 |
6 |
7 |
8 | Frame B
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/main/resources/frame_c.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Frame C Title
5 |
6 |
7 |
8 | Frame C
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/main/resources/frame_d.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Frame D Title
5 |
6 |
7 |
8 | Frame D
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/main/resources/hubConfig-s3.json:
--------------------------------------------------------------------------------
1 | {
2 | "newSessionWaitTimeout": -1,
3 | "capabilityMatcher": "com.nordstrom.automation.selenium.core.FoundationSlotMatcher",
4 | "throwOnCapabilityNotPresent": true,
5 | "cleanUpCycle": 5000,
6 | "role": "hub",
7 | "debug": false,
8 | "browserTimeout": 0,
9 | "timeout": 300000
10 | }
--------------------------------------------------------------------------------
/src/main/resources/hubConfig-s4.json:
--------------------------------------------------------------------------------
1 | {
2 | "distributor": {
3 | "slot-matcher": "com.nordstrom.automation.selenium.core.FoundationSlotMatcher",
4 | "reject-unsupported-caps": true
5 | }
6 | }
--------------------------------------------------------------------------------
/src/main/resources/locateByXpath.js:
--------------------------------------------------------------------------------
1 | var context = (arguments[0].length) ? arguments[0][0] : document;
2 | return document.evaluate(arguments[1], context, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
3 |
--------------------------------------------------------------------------------
/src/main/resources/locateEveryByCss.format:
--------------------------------------------------------------------------------
1 | return %s.querySelectorAll(%s);
2 |
--------------------------------------------------------------------------------
/src/main/resources/locateEveryByXpath.format:
--------------------------------------------------------------------------------
1 | return document.evaluate(%2$s, %1$s, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null).singleNodeValue;
2 |
--------------------------------------------------------------------------------
/src/main/resources/locateFirstByCss.format:
--------------------------------------------------------------------------------
1 | return %s.querySelector(%s);
2 |
--------------------------------------------------------------------------------
/src/main/resources/locateFirstByXpath.format:
--------------------------------------------------------------------------------
1 | return document.evaluate(%2$s, %1$s, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
2 |
--------------------------------------------------------------------------------
/src/main/resources/locateIndexByCss.format:
--------------------------------------------------------------------------------
1 | return %s.querySelectorAll(%s)[%d];
2 |
--------------------------------------------------------------------------------
/src/main/resources/locateIndexByXpath.format:
--------------------------------------------------------------------------------
1 | return document.evaluate(%2$s[%3$d], %1$s, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
2 |
--------------------------------------------------------------------------------
/src/main/resources/nodeConfig-s3.json:
--------------------------------------------------------------------------------
1 | {
2 | "capabilities": [ ],
3 | "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
4 | "maxSession": 5,
5 | "register": true,
6 | "registerCycle": 5000,
7 | "nodeStatusCheckTimeout": 5000,
8 | "nodePolling": 5000,
9 | "role": "node",
10 | "unregisterIfStillDownAfter": 60000,
11 | "downPollingLimit": 2,
12 | "debug": false
13 | }
--------------------------------------------------------------------------------
/src/main/resources/nodeConfig-s4.json:
--------------------------------------------------------------------------------
1 | {
2 | "node": {
3 | "detect-drivers": false
4 | }
5 | }
--------------------------------------------------------------------------------
/src/main/resources/operaChromiumVersions.json:
--------------------------------------------------------------------------------
1 | {
2 | "109": "123",
3 | "110": "124",
4 | "111": "125",
5 | "112": "126",
6 | "113": "127",
7 | "114": "128",
8 | "115": "130",
9 | "116": "131",
10 | "117": "132",
11 | "118": "133",
12 | "119": "134"
13 | }
14 |
--------------------------------------------------------------------------------
/src/selenium3/java/com/nordstrom/automation/selenium/api/GridProxyResponse.java:
--------------------------------------------------------------------------------
1 | package com.nordstrom.automation.selenium.api;
2 |
3 | import java.util.Collections;
4 | import java.util.List;
5 | import java.util.Map;
6 | import java.util.stream.Collectors;
7 |
8 | import org.openqa.selenium.Capabilities;
9 | import org.openqa.selenium.MutableCapabilities;
10 |
11 | public class GridProxyResponse {
12 |
13 | @SuppressWarnings("unchecked")
14 | public static List fromJson(Object obj) {
15 | try {
16 | Map input = (Map) obj;
17 | Map request = (Map) input.get("request");
18 | Map configuration = (Map) request.get("configuration");
19 | List