/* * JBoss, Home of Professional Open Source * Copyright 2011, Red Hat Middleware LLC, and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * 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 org.jboss.arquillian.drone.webdriver.factory.remote.reusable; import java.net.MalformedURLException; import java.net.URL; import java.util.List; import java.util.Map; import org.jboss.arquillian.config.descriptor.api.ArquillianDescriptor; import org.jboss.arquillian.config.descriptor.api.ExtensionDef; import org.jboss.arquillian.core.api.Event; import org.jboss.arquillian.core.api.Injector; import org.jboss.arquillian.core.api.Instance; import org.jboss.arquillian.core.api.annotation.ApplicationScoped; import org.jboss.arquillian.core.api.annotation.Inject; import org.jboss.arquillian.core.spi.ServiceLoader; import org.jboss.arquillian.drone.webdriver.binary.handler.SeleniumServerBinaryHandler; import org.jboss.arquillian.drone.webdriver.binary.process.SeleniumServerExecutor; import org.jboss.arquillian.drone.webdriver.binary.process.StartSeleniumServer; import org.jboss.arquillian.drone.webdriver.configuration.WebDriverConfiguration; import org.jboss.arquillian.drone.webdriver.factory.RemoteWebDriverFactory; import org.jboss.arquillian.test.spi.event.suite.AfterSuite; import org.jboss.arquillian.test.spi.event.suite.BeforeSuite; import org.jboss.arquillian.test.test.AbstractTestTestBase; import org.junit.After; import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.openqa.selenium.Capabilities; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.Mockito.when; /** * @author Lukas Fryc */ @RunWith(MockitoJUnitRunner.class) public class TestRemoteWebDriverFactorySessionStoring extends AbstractTestTestBase { @Inject Event<PersistReusedSessionsEvent> persistEvent; @Mock private ServiceLoader serviceLoader; @Mock private WebDriverConfiguration configuration; @Inject private Instance<ReusedSessionStore> sessionStore; @Inject private Instance<Injector> injector; private Capabilities desiredCapabilities; private URL hubUrl; private MockReusedSessionPermanentStorage permanentStorage; private InitializationParameter initializationParameter; @BeforeClass public static void skipIfEdgeBrowser() { Assume.assumeFalse(System.getProperty("browser", "phantomjs").equals("edge")); } @Override protected void addExtensions(List<Class<?>> extensions) { extensions.add(ReusableRemoteWebDriverExtension.class); extensions.add(SeleniumServerExecutor.class); } @Before public void setupMocks() { // set browser capabilities to be the same as defined in arquillian.xml - webdriver-reusable configuration MockBrowserCapabilitiesRegistry registry = MockBrowserCapabilitiesRegistry.createSingletonRegistry(); desiredCapabilities = new DesiredCapabilities(registry.getAllBrowserCapabilities().iterator().next() .getRawCapabilities()); permanentStorage = new MockReusedSessionPermanentStorage(); when(serviceLoader.onlyOne(ReusedSessionPermanentStorage.class)).thenReturn(permanentStorage); bind(ApplicationScoped.class, ServiceLoader.class, serviceLoader); try { hubUrl = new URL("http://localhost:5555/wd/hub/"); } catch (MalformedURLException e) { throw new IllegalStateException(e); } runSeleniumServer(); initializationParameter = new InitializationParameter(hubUrl, desiredCapabilities); when(configuration.getBrowser()).thenReturn("xyz"); when(configuration.isRemoteReusable()).thenReturn(true); when(configuration.getCapabilities()).thenReturn(desiredCapabilities); when(configuration.getRemoteAddress()).thenReturn(hubUrl); configuration.setSeleniumServerArgs("-debug true"); } private void runSeleniumServer() { try { String browser = (String) desiredCapabilities.getCapability("browserName"); DesiredCapabilities selServerCaps = new DesiredCapabilities(desiredCapabilities); String seleniumServerArgs = System.getProperty("seleniumServerArgs"); // use selenium server version defined in arquillian.xml String selSerVersion = getSeleniumServerVersion(MockBrowserCapabilitiesRegistry.getArquillianDescriptor()); if (!Validate.empty(selSerVersion)) { selServerCaps .setCapability(SeleniumServerBinaryHandler.SELENIUM_SERVER_VERSION_PROPERTY, selSerVersion); } String seleniumServerBinary = new SeleniumServerBinaryHandler(selServerCaps).downloadAndPrepare().toString(); fire(new StartSeleniumServer(seleniumServerBinary, browser, selServerCaps, hubUrl, seleniumServerArgs)); } catch (Exception e) { throw new IllegalStateException(e); } } private String getSeleniumServerVersion(ArquillianDescriptor arquillian) { ExtensionDef webdriver = arquillian.extension("webdriver-reusable"); Map<String, String> props = webdriver.getExtensionProperties(); return props.get("seleniumServerVersion"); } @After public void stopServer() { fire(new AfterSuite()); } @Test public void when_reusable_session_is_created_then_is_can_be_pulled_from_session_store() throws Exception { // having RemoteWebDriverFactory factory1 = new MockRemoteWebDriverFactory(); injector.get().inject(factory1); // when fire(new BeforeSuite()); RemoteWebDriver webdriver1 = factory1.createInstance(configuration); factory1.destroyInstance(webdriver1); webdriver1.quit(); // then ReusedSession reusedSession = sessionStore.get().pull(initializationParameter); assertNotNull("reusedSession must be stored", reusedSession); } @Test public void when_session_is_created_and_persisted_but_nonreusable_then_next_creation_should_remove_it_from_list_of_reusable_sessions() throws Exception { // having RemoteWebDriverFactory factory1 = new MockRemoteWebDriverFactory(); RemoteWebDriverFactory factory2 = new MockRemoteWebDriverFactory(); injector.get().inject(factory1); injector.get().inject(factory2); // when fire(new BeforeSuite()); // creates new session RemoteWebDriver webdriver1 = factory1.createInstance(configuration); // persists session into store factory1.destroyInstance(webdriver1); // makes driver non-reusable webdriver1.quit(); // new suite fire(new BeforeSuite()); // pulls non-reusable session from store, so creates new session RemoteWebDriver webdriver2 = factory2.createInstance(configuration); // quit newly created session factory2.destroyInstance(webdriver2); webdriver2.quit(); // persists available sessions (none should be available) // persistEvent.fire(new PersistReusedSessionsEvent()); // new suite fire(new BeforeSuite()); // pulls session - should *NOT* be empty ReusedSession reusedSession = sessionStore.get().pull(initializationParameter); assertNotNull("reusedSession must be stored", reusedSession); // pulls session - should be empty - it was cleared by last pull reusedSession = sessionStore.get().pull(initializationParameter); assertNull("reusedSession must not be stored", reusedSession); } public static class MockReusedSessionPermanentStorage implements ReusedSessionPermanentStorage { private byte[] stored; @Override public ReusedSessionStore loadStore() { if (stored == null) { return null; } try { return SerializationUtils.deserializeFromBytes(ReusedSessionStoreImpl.class, stored); } catch (Exception e) { throw new IllegalStateException(e); } } @Override public void writeStore(ReusedSessionStore store) { try { stored = SerializationUtils.serializeToBytes(store); } catch (Exception e) { throw new IllegalStateException(e); } } } public class MockRemoteWebDriverFactory extends RemoteWebDriverFactory { @Override protected RemoteWebDriver createRemoteDriver(URL remoteAddress, Capabilities desiredCapabilities) { return new RemoteWebDriver(hubUrl, desiredCapabilities); } } }