/* * Copyright 2012-2014 eBay Software Foundation and selendroid committers. * * 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 io.selendroid.standalone.server.model; import static io.selendroid.standalone.server.model.SelendroidStandaloneDriverFixture.getAndroidApkServerBuilder; import static io.selendroid.standalone.server.model.SelendroidStandaloneDriverFixture.getDeviceManager; import static io.selendroid.standalone.server.model.SelendroidStandaloneDriverFixture.getSelendroidStandaloneDriver; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import io.selendroid.common.SelendroidCapabilities; import io.selendroid.common.device.DeviceTargetPlatform; import io.selendroid.server.common.SelendroidResponse; import io.selendroid.server.common.exceptions.SelendroidException; import io.selendroid.standalone.SelendroidConfiguration; import io.selendroid.standalone.android.AndroidApp; import io.selendroid.standalone.exceptions.DeviceStoreException; import io.selendroid.standalone.server.model.DeviceStore; import io.selendroid.standalone.server.model.SelendroidStandaloneDriver; import io.selendroid.standalone.server.support.DeviceForTest; import io.selendroid.standalone.server.support.TestSessionListener; import java.io.File; import java.util.Map; import java.util.Properties; import java.util.Random; import java.util.UUID; import org.json.JSONObject; import org.junit.Assert; import org.junit.Test; import org.openqa.selenium.remote.BrowserType; public class SelendroidStandaloneDriverTest { public static final String TEST_APP_ID = "io.selendroid.testapp:0.4-SNAPSHOT"; private static final String TEST_APP_LAUNCH_ACTIVITY = "HomeScreenActivity"; public static final String APK_FILE = "src/test/resources/selendroid-test-app.apk"; public static final String INVALID_APK_FILE = "src/test/resources/selendroid-test-app-invalid.apk"; private static final Integer EMULATOR_PORT = 5560; @Test public void shouldInitDriver() throws Exception { SelendroidConfiguration conf = new SelendroidConfiguration(); conf.addSupportedApp(new File(APK_FILE).getAbsolutePath()); SelendroidStandaloneDriver driver = getSelendroidStandaloneDriver(); driver.initApplicationsUnderTest(conf); assertThatTestAppHasBeenSuccessfullyRegistered(driver); } @Test public void shouldInitDriverAndIgnoreInvalidEntry() throws Exception { SelendroidConfiguration conf = new SelendroidConfiguration(); conf.addSupportedApp(new File(APK_FILE).getAbsolutePath()); conf.addSupportedApp(new File(INVALID_APK_FILE).getAbsolutePath()); SelendroidStandaloneDriver driver = getSelendroidStandaloneDriver(); driver.initApplicationsUnderTest(conf); assertThatTestAppHasBeenSuccessfullyRegistered(driver); } @Test public void shouldInitDriverWithoutAnyConfig() throws Exception { SelendroidStandaloneDriver driver = getSelendroidStandaloneDriver(); try { driver.initApplicationsUnderTest(new SelendroidConfiguration()); } catch (SelendroidException e) { Assert.assertEquals("Configuration error - no apps has been configured.", e.getMessage()); } } @Test public void shouldInitDriverIfNoValidAppIsAvailable() throws Exception { SelendroidConfiguration conf = new SelendroidConfiguration(); SelendroidStandaloneDriver driver = getSelendroidStandaloneDriver(getAndroidApkServerBuilder()); driver.initApplicationsUnderTest(conf); Assert.assertTrue("Expecting only one app to be configured", driver.getConfiguredApps().size() == 1); Assert.assertEquals("Expecting AndroidDriver app to be configured", driver.getConfiguredApps() .get(BrowserType.ANDROID).getAppId(), BrowserType.ANDROID); } protected void assertThatTestAppHasBeenSuccessfullyRegistered(SelendroidStandaloneDriver driver) { Map<String, AndroidApp> apps = driver.getConfiguredApps(); Assert.assertTrue("expecting 2 test app has been registered but was " + apps.size(), apps.size() == 2); Assert.assertTrue("expecting test app has been registered with the right key", apps.containsKey(TEST_APP_ID)); } @Test public void shouldCreateNewTestSession() throws Exception { SelendroidConfiguration conf = new SelendroidConfiguration(); conf.addSupportedApp(new File(APK_FILE).getAbsolutePath()); SelendroidCapabilities caps = new SelendroidCapabilities(); caps.setAut(TEST_APP_ID); createTestSession(conf, caps); } @Test public void shouldCreateNewTestSessionIfNoApkPassed() throws Exception { SelendroidCapabilities caps = new SelendroidCapabilities(); caps.setAut(TEST_APP_ID); caps.setLaunchActivity(TEST_APP_LAUNCH_ACTIVITY); createTestSession(new SelendroidConfiguration(), caps); } private void createTestSession(SelendroidConfiguration conf, SelendroidCapabilities caps) throws Exception{ // Setting up driver with test app and device stub SelendroidStandaloneDriver driver = getSelendroidStandaloneDriver(); driver.initApplicationsUnderTest(conf); DeviceStore store = new DeviceStore(EMULATOR_PORT, getDeviceManager()); DeviceForTest emulator = new DeviceForTest(DeviceTargetPlatform.ANDROID16); Random random = new Random(); final UUID definedSessionId = new UUID(random.nextLong(), random.nextLong()); emulator.testSessionListener = new TestSessionListener(definedSessionId.toString(), "test") { @Override public SelendroidResponse executeSelendroidRequest(Properties params) { return null; } }; store.addDeviceToStore(emulator); driver.setDeviceStore(store); // testing new session creation caps.setPlatformVersion(DeviceTargetPlatform.ANDROID16); try { String sessionId = driver.createNewTestSession(new JSONObject(caps.asMap()), 0); Assert.assertNotNull(UUID.fromString(sessionId)); } finally { // this will also stop the http server emulator.stop(); } } @Test public void shouldIdentifyStartedAndStoppedEmulators() throws Exception { // Setting up driver with test app and device stub SelendroidStandaloneDriver driver = getSelendroidStandaloneDriver(); SelendroidConfiguration conf = new SelendroidConfiguration(); conf.addSupportedApp(new File(APK_FILE).getAbsolutePath()); driver.initApplicationsUnderTest(conf); driver.initAndroidDevices(); } @Test public void shouldRetrySessionCreationTheConfiguredAmountOfTimesOnFailure() throws Exception { SelendroidStandaloneDriver driver = getSelendroidStandaloneDriver(); // Configure a few retries SelendroidConfiguration conf = new SelendroidConfiguration(); int configuredRetries = 5; conf.setServerStartRetries(configuredRetries); driver.initApplicationsUnderTest(conf); DeviceStore deviceStore = swapWithFailingDeviceDriver(driver); try { driver.createNewTestSession(createCapabilities()); } catch (Exception e) { } verify(deviceStore, times(configuredRetries + 1)) .findAndroidDevice(any(SelendroidCapabilities.class)); } @Test public void shouldTryAtLeastOneTimeIfNoRetriesConfigured() throws Exception { SelendroidStandaloneDriver driver = getSelendroidStandaloneDriver(); // Configure a few retries SelendroidConfiguration conf = new SelendroidConfiguration(); conf.setServerStartRetries(0); driver.initApplicationsUnderTest(conf); DeviceStore deviceStore = swapWithFailingDeviceDriver(driver); try { driver.createNewTestSession(createCapabilities()); } catch (Exception e) { } verify(deviceStore, times(1)) .findAndroidDevice(any(SelendroidCapabilities.class)); } private DeviceStore swapWithFailingDeviceDriver(SelendroidStandaloneDriver driver) throws Exception { //count the amount of calls to DeviceStore to check how many times it was retried DeviceStore deviceStore = mock(DeviceStore.class); // throw to simulate failure, triggering a retry when(deviceStore.findAndroidDevice(any(SelendroidCapabilities.class))) .thenThrow(new DeviceStoreException("Empty store")); driver.setDeviceStore(deviceStore); return deviceStore; } private JSONObject createCapabilities() { SelendroidCapabilities caps = new SelendroidCapabilities(); caps.setAut(TEST_APP_ID); caps.setLaunchActivity(TEST_APP_LAUNCH_ACTIVITY); return new JSONObject(caps.asMap()); } }