/* * Copyright 2014 Alexei Barantsev * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ru.stqa.selenium.factory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.Capabilities; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriverException; import org.openqa.selenium.remote.DesiredCapabilities; import java.util.ArrayList; import java.util.List; import static org.junit.jupiter.api.Assertions.*; public class ThreadLocalSingleWebDriverPoolTest { private WebDriverPool factory; private DesiredCapabilities fakeCapabilities; @BeforeEach public void setUp() { fakeCapabilities = new DesiredCapabilities(); fakeCapabilities.setBrowserName("FAKE"); factory = new ThreadLocalSingleWebDriverPool(); factory.setLocalDriverProvider(FakeWebDriver::new); } private boolean isActive(WebDriver driver) { return ((FakeWebDriver) driver).isActive(); } @Test public void testCanInstantiateAndDismissADriver() { WebDriver driver = factory.getDriver(fakeCapabilities); assertTrue(isActive(driver)); assertFalse(factory.isEmpty()); factory.dismissDriver(driver); assertFalse(isActive(driver)); assertTrue(factory.isEmpty()); } @Test public void testCanDismissAllDrivers() { WebDriver driver = factory.getDriver(fakeCapabilities); assertTrue(isActive(driver)); assertFalse(factory.isEmpty()); factory.dismissAll(); assertFalse(isActive(driver)); assertTrue(factory.isEmpty()); } @Test public void testShouldReuseADriverWithSameCapabilities() { WebDriver driver = factory.getDriver(fakeCapabilities); assertTrue(isActive(driver)); WebDriver driver2 = factory.getDriver(fakeCapabilities); assertSame(driver2, driver); assertTrue(isActive(driver)); } @Test public void testShouldRecreateADriverWithDifferentCapabilities() { WebDriver driver = factory.getDriver(fakeCapabilities); assertTrue(isActive(driver)); fakeCapabilities.setCapability("foo", "bar"); WebDriver driver2 = factory.getDriver(fakeCapabilities); assertNotSame(driver2, driver); assertTrue(isActive(driver2)); assertFalse(isActive(driver)); } @Test public void testShouldRecreateAnInactiveDriver() { WebDriver driver = factory.getDriver(fakeCapabilities); assertTrue(isActive(driver)); driver.quit(); WebDriver driver2 = factory.getDriver(fakeCapabilities); assertNotSame(driver2, driver); assertTrue(isActive(driver2)); assertFalse(isActive(driver)); factory.dismissDriver(driver2); assertTrue(factory.isEmpty()); } @Test public void testShouldDismissOwnedDriversOnly() { WebDriver driver = factory.getDriver(fakeCapabilities); assertTrue(isActive(driver)); WebDriver driver2 = new FakeWebDriver(fakeCapabilities); assertNotSame(driver2, driver); assertThrows(Error.class, () -> factory.dismissDriver(driver2)); } @Test public void testShouldCreateADriverForEachThread() throws InterruptedException { final WebDriver driver = factory.getDriver(fakeCapabilities); Thread t = new Thread(() -> { WebDriver driver2 = factory.getDriver(fakeCapabilities); assertNotSame(driver2, driver); }); t.start(); assertTrue(isActive(driver)); t.join(); } @Test public void testShouldAutoDismissTheDriverIfAThreadIsOver() throws InterruptedException { final WebDriver driver = factory.getDriver(fakeCapabilities); Thread t = new Thread(() -> { WebDriver driver2 = factory.getDriver(fakeCapabilities); assertNotSame(driver2, driver); }); t.start(); assertTrue(isActive(driver)); assertFalse(factory.isEmpty()); factory.dismissDriver(driver); assertFalse(isActive(driver)); t.join(); // the thread is over, but the driver is not auto dismissed yet assertFalse(factory.isEmpty()); // this action should dismiss the driver in the complete thread WebDriver driver3 = factory.getDriver(fakeCapabilities); factory.dismissDriver(driver3); assertTrue(factory.isEmpty()); } @Test public void testShouldNotDismissADriverFromAnotherThread() throws InterruptedException { final WebDriver driver = factory.getDriver(fakeCapabilities); final List<Throwable> thrown = new ArrayList<>(); Thread t = new Thread(() -> factory.dismissDriver(driver)); t.setUncaughtExceptionHandler((t1, e) -> thrown.add(e)); t.start(); t.join(); assertTrue(isActive(driver)); assertFalse(factory.isEmpty()); assertFalse(thrown.isEmpty()); } @Test public void testDismissAllCanDismissDriversFromAllThreads() { final WebDriver driver = factory.getDriver(fakeCapabilities); new Thread(() -> { WebDriver driver2 = factory.getDriver(fakeCapabilities); assertNotSame(driver2, driver); }).start(); factory.dismissAll(); assertFalse(isActive(driver)); assertTrue(factory.isEmpty()); } @Test public void testShouldRecreateADriverAfterDismissAll() { WebDriver driver = factory.getDriver(fakeCapabilities); factory.dismissAll(); WebDriver driver2 = factory.getDriver(fakeCapabilities); assertNotSame(driver2, driver); assertTrue(isActive(driver2)); assertFalse(isActive(driver)); } @Test public void testConcurrentModificationExceptionInDismissDriversInFinishedThreadsMethod() throws InterruptedException { List<Thread> threads = new ArrayList<>(); List<WebDriver> drivers = new ArrayList<>(); for (int d = 0; d < 1000; d++) { threads.add(new Thread(() -> drivers.add(factory.getDriver(fakeCapabilities)))); } for (Thread thread : threads) { thread.start(); } for (Thread thread : threads) { thread.join(); } assertEquals(threads.size(), drivers.size()); } private static class BrokenFakeWebDriver extends FakeWebDriver { public BrokenFakeWebDriver(Capabilities capabilities) { super(capabilities); } public void quit() { throw new WebDriverException("I don't want to quit"); } } @Test public void testShouldBeAbleToUseFactoryIfDriverCannotQuit() { factory.setLocalDriverProvider(BrokenFakeWebDriver::new); WebDriver driver = factory.getDriver(fakeCapabilities); assertTrue(isActive(driver)); assertThrows(WebDriverException.class, () -> factory.dismissDriver(driver)); WebDriver driver2 = factory.getDriver(fakeCapabilities); assertNotSame(driver2, driver); } }