/*
* 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());
}
}