From 2ea3448efa0fafb185a5c46f3e4b8677a7c5f447 Mon Sep 17 00:00:00 2001 From: AndiCover <33127132+AndiCover@users.noreply.github.com> Date: Tue, 6 Dec 2022 01:08:01 +0100 Subject: [PATCH] Bael 4555 selenium tab switching (#13131) * BAEL-4555 Added Selenium TabHelper and tab switching live tests * BAEL-4555 Upgraded Selenium to 4.6.0 * BAEL-4555 fixed naming Co-authored-by: andicover --- testing-modules/selenium-junit-testng/pom.xml | 2 +- .../selenium/config/SeleniumConfig.java | 10 +- .../com/baeldung/selenium/tabs/TabHelper.java | 76 +++++++++++++++ .../SeleniumJavaScriptClickLiveTest.java | 6 +- .../cookies/SeleniumCookiesJUnitLiveTest.java | 12 +-- .../TakeScreenShotSeleniumLiveTest.java | 12 +-- .../selenium/tabs/SeleniumTabsLiveTest.java | 97 +++++++++++++++++++ .../selenium/tabs/SeleniumTestBase.java | 55 +++++++++++ 8 files changed, 247 insertions(+), 23 deletions(-) create mode 100644 testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/tabs/TabHelper.java create mode 100644 testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/tabs/SeleniumTabsLiveTest.java create mode 100644 testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/tabs/SeleniumTestBase.java diff --git a/testing-modules/selenium-junit-testng/pom.xml b/testing-modules/selenium-junit-testng/pom.xml index cf7c121dc8..f0a2e43eeb 100644 --- a/testing-modules/selenium-junit-testng/pom.xml +++ b/testing-modules/selenium-junit-testng/pom.xml @@ -57,7 +57,7 @@ 6.10 - 3.141.59 + 4.6.0 1.5.4 5.3.0 diff --git a/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/config/SeleniumConfig.java b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/config/SeleniumConfig.java index b1b7754648..14b2db7fc8 100644 --- a/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/config/SeleniumConfig.java +++ b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/config/SeleniumConfig.java @@ -1,24 +1,22 @@ package com.baeldung.selenium.config; import java.io.File; +import java.time.Duration; import java.util.concurrent.TimeUnit; -import org.openqa.selenium.Capabilities; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; -import org.openqa.selenium.remote.DesiredCapabilities; public class SeleniumConfig { private WebDriver driver; public SeleniumConfig() { - Capabilities capabilities = DesiredCapabilities.firefox(); - driver = new FirefoxDriver(capabilities); + driver = new FirefoxDriver(); driver.manage() .timeouts() - .implicitlyWait(5, TimeUnit.SECONDS); + .implicitlyWait(Duration.ofSeconds(5)); } static { @@ -50,4 +48,4 @@ public class SeleniumConfig { public WebDriver getDriver() { return driver; } -} +} \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/tabs/TabHelper.java b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/tabs/TabHelper.java new file mode 100644 index 0000000000..0ad91c51f0 --- /dev/null +++ b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/tabs/TabHelper.java @@ -0,0 +1,76 @@ +package com.baeldung.selenium.tabs; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; + +import javax.annotation.Nonnull; +import java.util.Optional; +import java.util.Set; + +/** + * Helper class for browser tab handling. + */ +public class TabHelper { + + private final WebDriver driver; + + public TabHelper(@Nonnull final WebDriver driver) { + this.driver = driver; + } + + /** + * Switch to the given browser tab. + * + * @param destinationWindowHandle the window handle of the destination tab. + * @return the window handle of the current tab before switching. + */ + public String switchToTab(@Nonnull final String destinationWindowHandle) { + final String currentWindowHandle = driver.getWindowHandle(); + driver.switchTo().window(destinationWindowHandle); + return currentWindowHandle; + } + + /** + * Close all browser tabs except the given one. + * + * @param windowHandle the window handle of the tab that should stay open. + */ + public void closeAllTabsExcept(@Nonnull final String windowHandle) { + for (final String handle : driver.getWindowHandles()) { + if (!handle.equals(windowHandle)) { + driver.switchTo().window(handle); + driver.close(); + } + } + driver.switchTo().window(windowHandle); + } + + /** + * Close all browser tabs except the current active one. + */ + public void closeAllTabsExceptCurrent() { + final String currentWindow = driver.getWindowHandle(); + closeAllTabsExcept(currentWindow); + } + + /** + * Open the given link and switch to the new opened tab. + * If the link is not opened in a new tab then no switch will be performed. + * + * @param link By of the link to open. + * @return the window handle of the tab before switching. + */ + public String openLinkAndSwitchToNewTab(@Nonnull final By link) { + final String windowHandle = driver.getWindowHandle(); + final Set windowHandlesBefore = driver.getWindowHandles(); + + driver.findElement(link).click(); + final Set windowHandlesAfter = driver.getWindowHandles(); + windowHandlesAfter.removeAll(windowHandlesBefore); + + final Optional newWindowHandle = windowHandlesAfter.stream().findFirst(); + newWindowHandle.ifPresent(s -> driver.switchTo().window(s)); + + return windowHandle; + } +} \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/clickusingjavascript/SeleniumJavaScriptClickLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/clickusingjavascript/SeleniumJavaScriptClickLiveTest.java index de519a44fc..c6abda08ee 100644 --- a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/clickusingjavascript/SeleniumJavaScriptClickLiveTest.java +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/clickusingjavascript/SeleniumJavaScriptClickLiveTest.java @@ -15,6 +15,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.File; +import java.time.Duration; +import java.time.temporal.ChronoUnit; public class SeleniumJavaScriptClickLiveTest { @@ -25,7 +27,7 @@ public class SeleniumJavaScriptClickLiveTest { public void setUp() { System.setProperty("webdriver.chrome.driver", new File("src/main/resources/chromedriver.mac").getAbsolutePath()); driver = new ChromeDriver(); - wait = new WebDriverWait(driver, 20); + wait = new WebDriverWait(driver, Duration.of(20, ChronoUnit.SECONDS)); } @After @@ -62,4 +64,4 @@ public class SeleniumJavaScriptClickLiveTest { executor.executeScript("arguments[0].click();", element); } -} +} \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/cookies/SeleniumCookiesJUnitLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/cookies/SeleniumCookiesJUnitLiveTest.java index 337e3b85fb..8906f89fba 100644 --- a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/cookies/SeleniumCookiesJUnitLiveTest.java +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/cookies/SeleniumCookiesJUnitLiveTest.java @@ -9,17 +9,16 @@ import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; import java.io.File; +import java.time.Duration; import java.util.Set; import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.openqa.selenium.Capabilities; import org.openqa.selenium.Cookie; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; -import org.openqa.selenium.remote.DesiredCapabilities; public class SeleniumCookiesJUnitLiveTest { @@ -29,11 +28,10 @@ public class SeleniumCookiesJUnitLiveTest { @Before public void setUp() { System.setProperty("webdriver.gecko.driver", findFile("geckodriver.mac")); - - Capabilities capabilities = DesiredCapabilities.firefox(); - driver = new FirefoxDriver(capabilities); + + driver = new FirefoxDriver(); navUrl = "https://baeldung.com"; - driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); + driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5)); } private static String findFile(String filename) { @@ -123,4 +121,4 @@ public class SeleniumCookiesJUnitLiveTest { assertThat(overriddenCookie.getValue(), equalTo("foo")); } -} +} \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/screenshot/TakeScreenShotSeleniumLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/screenshot/TakeScreenShotSeleniumLiveTest.java index cf705bb81f..e1ecdb4fa4 100644 --- a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/screenshot/TakeScreenShotSeleniumLiveTest.java +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/screenshot/TakeScreenShotSeleniumLiveTest.java @@ -4,6 +4,7 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; +import java.time.Duration; import java.util.concurrent.TimeUnit; import javax.imageio.ImageIO; @@ -13,12 +14,10 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.openqa.selenium.By; -import org.openqa.selenium.Capabilities; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; -import org.openqa.selenium.remote.DesiredCapabilities; import ru.yandex.qatools.ashot.AShot; import ru.yandex.qatools.ashot.Screenshot; @@ -33,17 +32,16 @@ public class TakeScreenShotSeleniumLiveTest { public static void setUp() { System.setProperty("webdriver.chrome.driver", resolveResourcePath("chromedriver.mac")); - Capabilities capabilities = DesiredCapabilities.chrome(); - driver = new ChromeDriver(capabilities); + driver = new ChromeDriver(); driver.manage() .timeouts() - .implicitlyWait(5, TimeUnit.SECONDS); + .implicitlyWait(Duration.ofSeconds(5)); driver.get("http://www.google.com/"); } @AfterClass - public static void tearDown() throws IOException { + public static void tearDown() { driver.close(); System.clearProperty("webdriver.chrome.driver"); @@ -82,4 +80,4 @@ public class TakeScreenShotSeleniumLiveTest { File file = new File("src/test/resources/" + filename); return file.getAbsolutePath(); } -} +} \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/tabs/SeleniumTabsLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/tabs/SeleniumTabsLiveTest.java new file mode 100644 index 0000000000..08708fb0bc --- /dev/null +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/tabs/SeleniumTabsLiveTest.java @@ -0,0 +1,97 @@ +package com.baeldung.selenium.tabs; + +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WindowType; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +final class SeleniumTabsLiveTest extends SeleniumTestBase { + + private static final By LINK_TO_ATTRIBUTES_PAGE_XPATH = By.xpath("//a[.='Attributes in new page']"); + private static final By LINK_TO_ALERT_PAGE_XPATH = By.xpath("//a[.='Alerts In A New Window From JavaScript']"); + + private static final String MAIN_PAGE_URL = "https://testpages.herokuapp.com/styled/windows-test.html"; + private static final String ATTRIBUTES_PAGE_URL = "https://testpages.herokuapp.com/styled/attributes-test.html"; + private static final String ALERT_PAGE_URL = "https://testpages.herokuapp.com/styled/alerts/alert-test.html"; + + @Test + void givenOneTab_whenOpenTab_thenTwoTabsOpen() { + //given + driver.get(MAIN_PAGE_URL); + assertEquals(1, driver.getWindowHandles().size()); + + //when + driver.switchTo().newWindow(WindowType.TAB); + + //then + assertEquals(2, driver.getWindowHandles().size()); + } + + @Test + void givenOneTab_whenOpenLinkInTab_thenTwoTabsOpen() { + //given + driver.get(MAIN_PAGE_URL); + + //when + final String mainWindow = tabHelper.openLinkAndSwitchToNewTab(LINK_TO_ATTRIBUTES_PAGE_XPATH); + assertEquals(ATTRIBUTES_PAGE_URL, driver.getCurrentUrl()); + + //then + tabHelper.switchToTab(mainWindow); + assertEquals(MAIN_PAGE_URL, driver.getCurrentUrl()); + assertEquals(2, driver.getWindowHandles().size()); + } + + @Test + void givenTwoTabs_whenCloseAllExceptMainTab_thenOneTabOpen() { + //given + driver.get(MAIN_PAGE_URL); + final String mainWindow = tabHelper.openLinkAndSwitchToNewTab(LINK_TO_ATTRIBUTES_PAGE_XPATH); + assertEquals(ATTRIBUTES_PAGE_URL, driver.getCurrentUrl()); + assertEquals(2, driver.getWindowHandles().size()); + + //when + tabHelper.closeAllTabsExcept(mainWindow); + + //then + assertEquals(1, driver.getWindowHandles().size()); + assertEquals(MAIN_PAGE_URL, driver.getCurrentUrl()); + } + + @Test + void givenTwoTabs_whenSwitching_thenCorrectTabOpen() { + //given + driver.get(MAIN_PAGE_URL); + final String mainWindow = tabHelper.openLinkAndSwitchToNewTab(LINK_TO_ATTRIBUTES_PAGE_XPATH); + assertEquals(ATTRIBUTES_PAGE_URL, driver.getCurrentUrl()); + assertEquals(2, driver.getWindowHandles().size()); + + //when/then + final String secondWindow = tabHelper.switchToTab(mainWindow); + assertEquals(MAIN_PAGE_URL, driver.getCurrentUrl()); + tabHelper.switchToTab(secondWindow); + assertEquals(ATTRIBUTES_PAGE_URL, driver.getCurrentUrl()); + } + + @Test + void givenThreeTabs_whenSwitching_thenCorrectTabOpen() { + //given + driver.get(MAIN_PAGE_URL); + final String mainWindow = tabHelper.openLinkAndSwitchToNewTab(LINK_TO_ATTRIBUTES_PAGE_XPATH); + final String secondWindow = tabHelper.switchToTab(mainWindow); + tabHelper.openLinkAndSwitchToNewTab(LINK_TO_ALERT_PAGE_XPATH); + final String thirdWindow = driver.getWindowHandle(); + assertEquals(3, driver.getWindowHandles().size()); + + //when/then + tabHelper.switchToTab(mainWindow); + assertEquals(MAIN_PAGE_URL, driver.getCurrentUrl()); + + tabHelper.switchToTab(secondWindow); + assertEquals(ATTRIBUTES_PAGE_URL, driver.getCurrentUrl()); + + tabHelper.switchToTab(thirdWindow); + assertEquals(ALERT_PAGE_URL, driver.getCurrentUrl()); + } +} \ No newline at end of file diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/tabs/SeleniumTestBase.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/tabs/SeleniumTestBase.java new file mode 100644 index 0000000000..71efbb84da --- /dev/null +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/tabs/SeleniumTestBase.java @@ -0,0 +1,55 @@ +package com.baeldung.selenium.tabs; + +import io.github.bonigarcia.wdm.WebDriverManager; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.chrome.ChromeDriver; + +/** + * Base class for Selenium Tests. This class handles the WebDriver setup and configuration. + * It takes care about closing all tabs except one after each test. After a test class it will close the browser. + */ +public class SeleniumTestBase { + + protected static WebDriver driver; + protected static TabHelper tabHelper; + + private static void setupChromeDriver() { + WebDriverManager.chromedriver().setup(); + driver = new ChromeDriver(); + options(); + tabHelper = new TabHelper(driver); + } + + private static void options() { + driver.manage().window().maximize(); + } + + /** + * Initializes the ChromeDriver before all tests. + */ + @BeforeAll + public static void init() { + setupChromeDriver(); + } + + /** + * After each test all tabs except the current tab will be closed. + */ + @AfterEach + public void closeTabs() { + tabHelper.closeAllTabsExceptCurrent(); + } + + /** + * After all tests the browser will be closed. + */ + @AfterAll + public static void cleanup() { + if (driver != null) { + driver.quit(); + } + } +} \ No newline at end of file