From 7005779da48b6fb264f7c3d1651a0899db98f1e4 Mon Sep 17 00:00:00 2001 From: aplekhov Date: Sat, 17 Mar 2018 20:17:19 +0300 Subject: [PATCH 1/5] Added waiter to be sure that new window is really appeared before switching. --- .../selenium/elements/upgrade/TeasyWindow.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java b/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java index 5d68a96..b107a1c 100644 --- a/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java +++ b/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java @@ -1,13 +1,16 @@ package com.wiley.autotest.selenium.elements.upgrade; import com.wiley.autotest.selenium.Report; +import com.wiley.autotest.selenium.SeleniumHolder; import com.wiley.autotest.selenium.elements.upgrade.conditions.PageLoaded; import com.wiley.autotest.selenium.elements.upgrade.conditions.window.WindowMatcher; +import com.wiley.autotest.selenium.elements.upgrade.waitfor.CustomWaitFor; import io.appium.java_client.AppiumDriver; import org.openqa.selenium.*; import java.net.URL; import java.util.Iterator; +import java.util.function.Function; /** * Represents browser window @@ -24,6 +27,7 @@ public TeasyWindow(WebDriver driver) { @Override public void switchToLast() { + waitForNewWindowAppeared(); Iterator iterator = driver.getWindowHandles().iterator(); String window = null; while (iterator.hasNext()) { @@ -106,4 +110,16 @@ public void maximize() { public void scrollTo(TeasyElement element) { ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element); } + + private void waitForNewWindowAppeared() { + int windowCount = SeleniumHolder.getWebDriver().getWindowHandles().size(); + new CustomWaitFor().condition(newWindowAppeared(), windowCount); + } + + private Function newWindowAppeared() { + return count -> { + int currentWindowsCount = driver.getWindowHandles().size(); + return count != currentWindowsCount; + }; + } } From bb41d4b230942ac746e06f9c2a1e182f0a0ee430 Mon Sep 17 00:00:00 2001 From: aplekhov Date: Sat, 17 Mar 2018 20:20:35 +0300 Subject: [PATCH 2/5] Added waiter to be sure that new window is really appeared before switching. --- .../wiley/autotest/selenium/elements/upgrade/TeasyWindow.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java b/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java index b107a1c..52ea947 100644 --- a/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java +++ b/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java @@ -1,7 +1,6 @@ package com.wiley.autotest.selenium.elements.upgrade; import com.wiley.autotest.selenium.Report; -import com.wiley.autotest.selenium.SeleniumHolder; import com.wiley.autotest.selenium.elements.upgrade.conditions.PageLoaded; import com.wiley.autotest.selenium.elements.upgrade.conditions.window.WindowMatcher; import com.wiley.autotest.selenium.elements.upgrade.waitfor.CustomWaitFor; @@ -112,7 +111,7 @@ public void scrollTo(TeasyElement element) { } private void waitForNewWindowAppeared() { - int windowCount = SeleniumHolder.getWebDriver().getWindowHandles().size(); + int windowCount = driver.getWindowHandles().size(); new CustomWaitFor().condition(newWindowAppeared(), windowCount); } From d9a02c2ee51427518e51ee61993a5fc174197a45 Mon Sep 17 00:00:00 2001 From: aplekhov Date: Sat, 17 Mar 2018 20:50:54 +0300 Subject: [PATCH 3/5] Added waiter to be sure that new window is really appeared before switching. --- .../elements/upgrade/TeasyWindow.java | 25 ++++++++++++++----- .../selenium/elements/upgrade/Window.java | 3 +++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java b/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java index 52ea947..4d8de51 100644 --- a/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java +++ b/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java @@ -1,5 +1,6 @@ package com.wiley.autotest.selenium.elements.upgrade; +import com.wiley.autotest.actions.Actions; import com.wiley.autotest.selenium.Report; import com.wiley.autotest.selenium.elements.upgrade.conditions.PageLoaded; import com.wiley.autotest.selenium.elements.upgrade.conditions.window.WindowMatcher; @@ -26,7 +27,6 @@ public TeasyWindow(WebDriver driver) { @Override public void switchToLast() { - waitForNewWindowAppeared(); Iterator iterator = driver.getWindowHandles().iterator(); String window = null; while (iterator.hasNext()) { @@ -35,6 +35,24 @@ public void switchToLast() { driver.switchTo().window(window); } + /** + * To be sure that new window appeared after an action. + * For example, after clicking on a link with new + * window target. + * + * Example usage: switchToLastAfter(() -> element.click()); + * + * @param action - an action to do before new window appeared + * and before switching. + */ + @Override + public void switchToLastAfter(Actions action) { + int windowCount = driver.getWindowHandles().size(); + action.execute(); + new CustomWaitFor().condition(newWindowAppeared(), windowCount); + switchToLast(); + } + @Override public void switchTo(WindowMatcher matcher) { fluentWait.waitFor(matcher.get().findAndSwitch()); @@ -110,11 +128,6 @@ public void scrollTo(TeasyElement element) { ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element); } - private void waitForNewWindowAppeared() { - int windowCount = driver.getWindowHandles().size(); - new CustomWaitFor().condition(newWindowAppeared(), windowCount); - } - private Function newWindowAppeared() { return count -> { int currentWindowsCount = driver.getWindowHandles().size(); diff --git a/src/main/java/com/wiley/autotest/selenium/elements/upgrade/Window.java b/src/main/java/com/wiley/autotest/selenium/elements/upgrade/Window.java index cf5c6ac..4e6d14b 100644 --- a/src/main/java/com/wiley/autotest/selenium/elements/upgrade/Window.java +++ b/src/main/java/com/wiley/autotest/selenium/elements/upgrade/Window.java @@ -1,5 +1,6 @@ package com.wiley.autotest.selenium.elements.upgrade; +import com.wiley.autotest.actions.Actions; import com.wiley.autotest.selenium.elements.upgrade.conditions.window.WindowMatcher; import java.net.URL; @@ -11,6 +12,8 @@ public interface Window { void switchToLast(); + void switchToLastAfter(Actions action); + void switchTo(WindowMatcher matcher); void close(); From 88b25a33fde09e32569b926d5b8211a94f030e87 Mon Sep 17 00:00:00 2001 From: aplekhov Date: Sat, 17 Mar 2018 21:06:17 +0300 Subject: [PATCH 4/5] Added waiter to be sure that new window is really appeared before switching. --- .../selenium/elements/upgrade/TeasyWindow.java | 12 ++++++++++++ .../autotest/selenium/elements/upgrade/Window.java | 1 + 2 files changed, 13 insertions(+) diff --git a/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java b/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java index 4d8de51..3115523 100644 --- a/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java +++ b/src/main/java/com/wiley/autotest/selenium/elements/upgrade/TeasyWindow.java @@ -53,6 +53,18 @@ public void switchToLastAfter(Actions action) { switchToLast(); } + /** + * To be sure that new window appeared after click on element. + * For example, after clicking on a link with new + * window target. + * + * @param element - an element to click to new window switch. + */ + @Override + public void switchToLastAfter(TeasyElement element) { + switchToLastAfter(element::click); + } + @Override public void switchTo(WindowMatcher matcher) { fluentWait.waitFor(matcher.get().findAndSwitch()); diff --git a/src/main/java/com/wiley/autotest/selenium/elements/upgrade/Window.java b/src/main/java/com/wiley/autotest/selenium/elements/upgrade/Window.java index 4e6d14b..8f0dfb6 100644 --- a/src/main/java/com/wiley/autotest/selenium/elements/upgrade/Window.java +++ b/src/main/java/com/wiley/autotest/selenium/elements/upgrade/Window.java @@ -13,6 +13,7 @@ public interface Window { void switchToLast(); void switchToLastAfter(Actions action); + void switchToLastAfter(TeasyElement element); void switchTo(WindowMatcher matcher); From 630e3645e57c8741fcee0422fa0fbc9ceeeeac88 Mon Sep 17 00:00:00 2001 From: aplekhov Date: Sat, 17 Mar 2018 21:47:29 +0300 Subject: [PATCH 5/5] Added method to RepeatableAction which can return a value. Added unit test for such function. Added message() call into existing test to be sure about such function. --- .../autotest/actions/RepeatableAction.java | 34 +++++++++++++++++-- .../framework/pages/RepeaterPage.java | 26 +++++++++++++- .../tests/repeater/RepeaterTest.java | 7 ++++ 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/wiley/autotest/actions/RepeatableAction.java b/src/main/java/com/wiley/autotest/actions/RepeatableAction.java index 4f0c386..4fb6b24 100644 --- a/src/main/java/com/wiley/autotest/actions/RepeatableAction.java +++ b/src/main/java/com/wiley/autotest/actions/RepeatableAction.java @@ -3,6 +3,7 @@ import com.wiley.autotest.services.StopTestExecutionException; import com.wiley.autotest.utils.TestUtils; +import java.util.function.Function; import java.util.function.Supplier; /** @@ -11,7 +12,7 @@ *

* If the condition does not become true after all attempts - AssertionError is thrown */ -public class RepeatableAction { +public class RepeatableAction { private Actions action; private Conditions condition; @@ -20,6 +21,8 @@ public class RepeatableAction { private final int millisecondsBetweenAttempts; private int attemptCounter = 0; private String errorMessage; + private Supplier output; + private Function dependedCondition; /** * By default will try 5 types and sleep 3 seconds after each attempt @@ -53,7 +56,18 @@ public RepeatableAction(Actions action, Conditions condition, int numberOfAttemp this.millisecondsBetweenAttempts = millisecondsBetweenAttempts; } - public RepeatableAction message(String errorMessage) { + public RepeatableAction(Supplier output, Function condition, int millisecondsBetweenAttempts) { + this(output, condition, 5, millisecondsBetweenAttempts); + } + + public RepeatableAction(Supplier output, Function condition, int numberOfAttempts, int millisecondsBetweenAttempts) { + this.output = output; + this.dependedCondition = condition; + this.numberOfAttempts = numberOfAttempts; + this.millisecondsBetweenAttempts = millisecondsBetweenAttempts; + } + + public RepeatableAction message(String errorMessage) { this.errorMessage = errorMessage; return this; } @@ -79,6 +93,22 @@ public void perform() { } } + public T performAndGet() { + T result = null; + for (int i = 0; i < numberOfAttempts; i++) { + T localResult = output.get(); + if (dependedCondition.apply(localResult)) { + result = localResult; + break; + } else { + TestUtils.waitForSomeTime(millisecondsBetweenAttempts, "Sleeping inside action repeater"); + } + } + if (result == null) { + throw new StopTestExecutionException(getErrorMessage()); + } else return result; + } + private String getErrorMessage() { String baseMessage = "Unable to perform actions after " + numberOfAttempts + " attempts"; if (errorMessage != null) { diff --git a/src/test/java/com/wiley/autotest/framework/pages/RepeaterPage.java b/src/test/java/com/wiley/autotest/framework/pages/RepeaterPage.java index f75fa6b..65ee055 100644 --- a/src/test/java/com/wiley/autotest/framework/pages/RepeaterPage.java +++ b/src/test/java/com/wiley/autotest/framework/pages/RepeaterPage.java @@ -3,6 +3,8 @@ import com.wiley.autotest.actions.RepeatableAction; import com.wiley.autotest.selenium.context.AbstractPage; import com.wiley.autotest.selenium.context.SearchStrategy; +import com.wiley.autotest.selenium.elements.upgrade.TeasyElement; +import org.assertj.core.api.Assertions; import org.openqa.selenium.By; import org.springframework.stereotype.Component; @@ -13,7 +15,9 @@ public class RepeaterPage extends AbstractPage { public RepeaterPage negativeCheck() { - new RepeatableAction(this::clickOnFailure).perform(); + new RepeatableAction(this::clickOnFailure) + .message("The Div3 isn't displayed.") + .perform(); return this; } @@ -22,6 +26,26 @@ public RepeaterPage positiveCheck() { return this; } + public RepeaterPage outputCheck() { + String string = new RepeatableAction<>( + () -> { + element(By.cssSelector("[id='testDiv2']")).click(); + TeasyElement element = element(By.cssSelector("[id='testDiv3']"), new SearchStrategy(1).nullOnFailure()); + if (element != null) { + return element.getText(); + } else { + return "No text"; + } + }, + (text) -> text.equals("Div3"), + 10, + 1000) + .message("No text for element.") + .performAndGet(); + Assertions.assertThat(string).isEqualTo("Div3"); + return this; + } + private boolean clickOnFailure() { clickElement("[id='testDiv1']"); return isElementDisplayed(); diff --git a/src/test/java/com/wiley/autotest/framework/tests/repeater/RepeaterTest.java b/src/test/java/com/wiley/autotest/framework/tests/repeater/RepeaterTest.java index 36935c1..54847b4 100644 --- a/src/test/java/com/wiley/autotest/framework/tests/repeater/RepeaterTest.java +++ b/src/test/java/com/wiley/autotest/framework/tests/repeater/RepeaterTest.java @@ -13,9 +13,16 @@ public void performAction() { .positiveCheck(); } + @Test() + public void performActionWithOutput() { + openPage("repeater.html", RepeaterPage.class) + .outputCheck(); + } + @Test(expectedExceptions = StopTestExecutionException.class) public void unableToPerformAction() { openPage("repeater.html", RepeaterPage.class) .negativeCheck(); } + }