Skip to content

Commit 68e3311

Browse files
authored
Implement deviceSettings (#20)
* Implement deviceSettings * Move deviceKey to driverSettings in settings.json * Fix concatenation * Fix typo * Rename tests * Remove deviceName capability from settings.json * Fix pipeline * Add example of simulator/emulator capabilities * Fix tests * Update pipeline
1 parent d3c47cf commit 68e3311

File tree

12 files changed

+275
-46
lines changed

12 files changed

+275
-46
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,5 +147,15 @@ ILoginScreen loginScreen = AqualityServices.getScreenFactory().getScreen(ILoginS
147147

148148
You can find an example in [aquality-appium-mobile-java-template](https://github.com/aquality-automation/aquality-appium-mobile-java-template) repository.
149149

150+
### Devices
151+
152+
Our library allows you to run tests on different devices and store their settings (like udid, name, etc.) in JSON files.
153+
154+
You have to add [devices.json](./src/test/resources/devices.json) file to resources where you can define a set of devices which you use to run tests.
155+
156+
It is possible to set default device for each platform in [settings.json](./src/test/resources/settings.json) by defining `deviceKey` property which is a key of device settings from `devices.json` file.
157+
158+
You can also create several profiles with devices by adding files with suffixes `devices.<devicesProfile>.json` (like `devices.set1.json`) and then specify profile using maven args `-DdevicesProfile=set1`.
159+
150160
### License
151161
Library's source code is made available under the [Apache 2.0 license](https://github.com/aquality-automation/aquality-winappdriver-dotnet/blob/master/LICENSE).

azure-pipelines.yml

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ jobs:
5252

5353
variables:
5454
ANDROID_EMU_NAME: test
55-
ANDROID_EMU_ABI: x86
56-
ANDROID_EMU_TARGET: android-28
57-
ANDROID_EMU_TAG: google_apis
55+
ANDROID_SDK_ID: system-images;android-28;google_apis_playstore;x86
5856
XCODE_VERSION: 10.2
5957
IOS_PLATFORM_VERSION: 12.2
6058
IOS_DEVICE_NAME: iPhone X
@@ -65,22 +63,17 @@ jobs:
6563
inputs:
6664
script: |
6765
echo "Configuring Environment"
68-
echo $JAVA_HOME
69-
ls /Library/Java/JavaVirtualMachines/
70-
71-
ls $ANDROID_HOME/build-tools/
7266
export PATH=$PATH:$JAVA_HOME/bin
73-
7467
echo export "ANDROID_HOME=\$ANDROID_HOME" >> ~/.bash_profile
7568
export PATH=$PATH:$ANDROID_HOME
7669
77-
echo $ANDROID_HOME
78-
echo $JAVA_HOME
79-
echo $PATH
70+
echo "ANDROID_HOME: ${ANDROID_HOME}"
71+
echo "JAVA_HOME: ${JAVA_HOME}"
72+
echo "PATH: ${PATH}"
8073
81-
echo "y" | $ANDROID_HOME/tools/bin/sdkmanager --install 'system-images;$(ANDROID_EMU_TARGET);$(ANDROID_EMU_TAG);$(ANDROID_EMU_ABI)'
82-
echo "no" | $ANDROID_HOME/tools/bin/avdmanager create avd -n "$(ANDROID_EMU_NAME)" -k 'system-images;$(ANDROID_EMU_TARGET);$(ANDROID_EMU_TAG);$(ANDROID_EMU_ABI)' --force
83-
echo $ANDROID_HOME/emulator/emulator -list-avds
74+
echo "y" | $ANDROID_HOME/tools/bin/sdkmanager "$(ANDROID_SDK_ID)"
75+
echo "no" | $ANDROID_HOME/tools/bin/avdmanager create avd -n "$(ANDROID_EMU_NAME)" -k "$(ANDROID_SDK_ID)" -f
76+
$ANDROID_HOME/emulator/emulator -list-avds
8477
8578
echo "Starting emulator"
8679
nohup $ANDROID_HOME/emulator/emulator -avd "$(ANDROID_EMU_NAME)" -no-snapshot > /dev/null 2>&1 &
@@ -90,26 +83,21 @@ jobs:
9083
echo "Emulator started"
9184
9285
echo "Installing Appium"
93-
node --version
94-
npm -version
95-
npm list --depth 0
9686
npm install -g [email protected]
97-
# --chromedriver-skip-install
9887
ln -fs /usr/local/lib/node_modules/appium/build/lib/main.js /usr/local/bin/appium
9988
chmod +x /usr/local/bin/appium
10089
export PATH=$PATH:/usr/local/bin/appium
90+
appium --version
91+
echo "Appium installed"
10192
10293
echo "Installing and Running Appium doctor"
10394
npm install -g [email protected]
10495
npm install -g [email protected]
10596
ln -fs /usr/local/lib/node_modules/appium-doctor/appium-doctor.js /usr/local/bin/appium-doctor
10697
chmod +x /usr/local/bin/appium-doctor
10798
export PATH=$PATH:/usr/local/bin/appium-doctor
108-
109-
npm list --depth 0
110-
111-
appium --version
11299
appium-doctor
100+
echo "Appium doctor installed and executed"
113101
114102
#sudo xcode-select -s /Applications/Xcode_$(XCODE_VERSION).app/Contents/Developer
115103
#xcrun simctl list

pom.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
<groupId>com.github.aquality-automation</groupId>
88
<artifactId>aquality-appium-mobile</artifactId>
9-
<version>1.1.0</version>
9+
<version>1.2.0</version>
10+
1011
<packaging>jar</packaging>
1112
<name>Aquality Appium Mobile</name>
1213
<description>Library with core functions simplifying work with Appium-controlled applications.</description>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package aquality.appium.mobile.configuration;
2+
3+
import aquality.selenium.core.utilities.ISettingsFile;
4+
import aquality.selenium.core.utilities.JsonSettingsFile;
5+
import org.openqa.selenium.Capabilities;
6+
import org.openqa.selenium.remote.DesiredCapabilities;
7+
8+
import java.util.HashMap;
9+
import java.util.Map;
10+
11+
public class DeviceSettings implements IDeviceSettings {
12+
13+
private final ISettingsFile settingsFile;
14+
private final String deviceKey;
15+
16+
public DeviceSettings(String deviceKey) {
17+
this.settingsFile = getDevicesSettingsFile();
18+
this.deviceKey = deviceKey;
19+
}
20+
21+
private ISettingsFile getDevicesSettingsFile() {
22+
String devicesProfileName = System.getProperty("devicesProfile");
23+
String devicesProfile = devicesProfileName == null
24+
? "devices.json"
25+
: "devices.".concat(devicesProfileName).concat(".json");
26+
return new JsonSettingsFile(devicesProfile);
27+
}
28+
29+
@Override
30+
public Capabilities getCapabilities() {
31+
Map<String, Object> deviceCapabilities = getCapabilitiesFromSettings();
32+
DesiredCapabilities capabilities = new DesiredCapabilities();
33+
deviceCapabilities.forEach(capabilities::setCapability);
34+
return capabilities;
35+
}
36+
37+
private Map<String, Object> getCapabilitiesFromSettings() {
38+
Map<String, Object> deviceCapabilities = new HashMap<>();
39+
if (deviceKey != null) {
40+
String path = "/".concat(deviceKey).concat("/capabilities");
41+
deviceCapabilities = settingsFile.getMap(path);
42+
}
43+
return deviceCapabilities;
44+
}
45+
}

src/main/java/aquality/appium/mobile/configuration/DriverSettings.java

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,16 @@
99

1010
import java.io.File;
1111
import java.io.IOException;
12+
import java.util.Arrays;
1213
import java.util.Map;
14+
import java.util.stream.Collectors;
1315

1416
public class DriverSettings implements IDriverSettings {
1517

1618
private static final String APPLICATION_PATH_KEY = "applicationPath";
1719
private static final String APP_CAPABILITY_KEY = "app";
20+
private static final String DEVICE_KEY_KEY = "deviceKey";
21+
1822
private final ISettingsFile settingsFile;
1923
private final PlatformName platformName;
2024

@@ -28,21 +32,26 @@ public Capabilities getCapabilities() {
2832
Map<String, Object> capabilitiesFromSettings = getCapabilitiesFromSettings();
2933
DesiredCapabilities capabilities = new DesiredCapabilities();
3034
capabilitiesFromSettings.forEach(capabilities::setCapability);
31-
if(hasApplicationPath()) {
35+
if (hasApplicationPath()) {
3236
capabilities.setCapability(APP_CAPABILITY_KEY, getAbsolutePath(getApplicationPath()));
3337
}
34-
return capabilities;
38+
return capabilities.merge(getDeviceCapabilities());
3539
}
3640

37-
private Map<String, Object> getCapabilitiesFromSettings(){
41+
private Map<String, Object> getCapabilitiesFromSettings() {
3842
return settingsFile.getMap(getDriverCapabilitiesJsonPath());
3943
}
4044

45+
private String getDriverCapabilitiesJsonPath() {
46+
return getDriverSettingsPath("capabilities");
47+
}
48+
4149
private String getAbsolutePath(String relativePath) {
4250
try {
4351
return new File(relativePath).getCanonicalPath();
4452
} catch (IOException e) {
45-
String message = String.format(AqualityServices.get(ILocalizationManager.class).getLocalizedMessage("loc.file.reading_exception"),
53+
String message = String.format(
54+
AqualityServices.get(ILocalizationManager.class).getLocalizedMessage("loc.file.reading_exception"),
4655
relativePath);
4756
AqualityServices.getLogger().fatal(message, e);
4857
throw new IllegalArgumentException(message);
@@ -53,16 +62,19 @@ private boolean hasApplicationPath() {
5362
return settingsFile.getMap(getDriverSettingsPath()).containsKey(APPLICATION_PATH_KEY);
5463
}
5564

56-
@Override
57-
public String getApplicationPath() {
58-
return String.valueOf(settingsFile.getValue(getDriverSettingsPath() + "/" + APPLICATION_PATH_KEY));
65+
private Capabilities getDeviceCapabilities() {
66+
String deviceKey = (String) settingsFile.getValueOrDefault(getDriverSettingsPath(DEVICE_KEY_KEY), null);
67+
IDeviceSettings deviceSettings = new DeviceSettings(deviceKey);
68+
return deviceSettings.getCapabilities();
5969
}
6070

61-
private String getDriverCapabilitiesJsonPath(){
62-
return getDriverSettingsPath() + "/capabilities";
71+
@Override
72+
public String getApplicationPath() {
73+
return String.valueOf(settingsFile.getValue(getDriverSettingsPath(APPLICATION_PATH_KEY)));
6374
}
6475

65-
private String getDriverSettingsPath(){
66-
return String.format("/driverSettings/%1$s", platformName.toString().toLowerCase());
76+
private String getDriverSettingsPath(final String... paths) {
77+
String pathToDriverSettings = String.format("/driverSettings/%1$s", platformName.toString().toLowerCase());
78+
return pathToDriverSettings.concat(Arrays.stream(paths).map("/"::concat).collect(Collectors.joining()));
6779
}
6880
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package aquality.appium.mobile.configuration;
2+
3+
import org.openqa.selenium.Capabilities;
4+
5+
/**
6+
* Describes desired device settings.
7+
*/
8+
public interface IDeviceSettings {
9+
10+
/**
11+
* Capabilities related to desired device.
12+
* @return initialized {@link Capabilities}.
13+
*/
14+
Capabilities getCapabilities();
15+
}

src/main/resources/devices.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"iOS_Simulator": {
3+
"capabilities": {
4+
"platformVersion": "<iOS_platform_version>",
5+
"deviceName": "<iOS_simulator_name>"
6+
}
7+
},
8+
"iPhone_NAME": {
9+
"capabilities": {
10+
"platformVersion": "<iOS_platform_version>",
11+
"deviceName": "<iOS_device_name>",
12+
"udid": "<iOS_device_udidi>",
13+
"wdaLocalPort": "<wda_local_port>"
14+
}
15+
},
16+
"Android_Emulator": {
17+
"capabilities": {
18+
"deviceName": "<Android_emulator_name>"
19+
}
20+
},
21+
"Android_NAME": {
22+
"capabilities": {
23+
"deviceName": "<Android_device_name>",
24+
"udid": "<Android_device_udid>",
25+
"systemPort": "<appium_system_port>"
26+
}
27+
}
28+
}

src/main/resources/settings.json

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,19 @@
66

77
"driverSettings": {
88
"android": {
9+
"deviceKey": "<KEY_OF_ANDROID_DEVICE_FROM_DEVICES_JSON>",
910
"applicationPath": "./src/test/resources/apps/ApiDemos-debug.apk",
1011
"capabilities": {
11-
"deviceName": "Android Emulator"
12+
"platformName": "Android",
13+
"automationName": "UiAutomator2"
1214
}
1315
},
1416
"ios": {
17+
"deviceKey": "<KEY_OF_IOS_DEVICE_FROM_DEVICES_JSON>",
1518
"applicationPath": "./src/test/resources/apps/TestApp.app.zip",
1619
"capabilities": {
17-
"deviceName": "iOS Simulator",
18-
"automationName": "XCUITest",
1920
"platformName": "iOS",
20-
"udid": "<SIMULATOR_ID/DEVICE_ID>"
21+
"automationName": "XCUITest"
2122
}
2223
}
2324
},
@@ -29,10 +30,10 @@
2930
}
3031
},
3132
"timeouts": {
32-
"timeoutImplicit" : 0,
33-
"timeoutCondition" : 15,
33+
"timeoutImplicit": 0,
34+
"timeoutCondition": 15,
3435
"timeoutPollingInterval": 300,
35-
"timeoutCommand":120
36+
"timeoutCommand": 120
3637
},
3738
"retry": {
3839
"number": 2,
@@ -42,6 +43,6 @@
4243
"language": "en"
4344
},
4445
"elementCache": {
45-
"isEnabled": false
46+
"isEnabled": true
4647
}
4748
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package integration;
2+
3+
import aquality.appium.mobile.application.AqualityServices;
4+
import aquality.appium.mobile.configuration.DeviceSettings;
5+
import aquality.appium.mobile.configuration.IApplicationProfile;
6+
import aquality.appium.mobile.configuration.IDeviceSettings;
7+
import org.openqa.selenium.Capabilities;
8+
import org.testng.Assert;
9+
import org.testng.annotations.AfterClass;
10+
import org.testng.annotations.Test;
11+
12+
public class DeviceSettingsTest {
13+
14+
private static final String PLATFORM_NAME_PROPERTY_KEY = "platformName";
15+
private static final String DEVICES_PROFILE_PROPERTY_KEY = "devicesProfile";
16+
private static final String DEVICE_KEY_PROPERTY_KEY = "driverSettings.android.deviceKey";
17+
18+
@Test
19+
public void testShouldBePossibleToGetDeviceCapabilities() {
20+
IDeviceSettings deviceSettings = new DeviceSettings("iPhone_11");
21+
Capabilities capabilities = deviceSettings.getCapabilities();
22+
Assert.assertNotNull(capabilities);
23+
Assert.assertFalse(capabilities.getCapabilityNames().isEmpty());
24+
}
25+
26+
@Test
27+
public void testShouldBePossibleToGetEmptyCapabilitiesWhenDeviceKeyIsNull() {
28+
IDeviceSettings deviceSettings = new DeviceSettings(null);
29+
Capabilities capabilities = deviceSettings.getCapabilities();
30+
Assert.assertNotNull(capabilities);
31+
Assert.assertTrue(capabilities.getCapabilityNames().isEmpty());
32+
}
33+
34+
@Test
35+
public void testShouldBePossibleToUseDifferentDevicesProfiles() {
36+
System.setProperty(DEVICES_PROFILE_PROPERTY_KEY, "test");
37+
IDeviceSettings testDeviceSettings = new DeviceSettings("iPhone_11");
38+
Capabilities testCapabilities = testDeviceSettings.getCapabilities();
39+
Assert.assertEquals("iPhone 11 test", testCapabilities.getCapability("deviceName"));
40+
41+
System.clearProperty(DEVICES_PROFILE_PROPERTY_KEY);
42+
IDeviceSettings deviceSettings = new DeviceSettings("iPhone_11");
43+
Capabilities capabilities = deviceSettings.getCapabilities();
44+
Assert.assertEquals("iPhone 11", capabilities.getCapability("deviceName"));
45+
}
46+
47+
@Test
48+
public void testShouldBePossibleToGetDefaultDeviceSettingsForIosPlatform() {
49+
System.setProperty(PLATFORM_NAME_PROPERTY_KEY, "ios");
50+
System.setProperty(DEVICE_KEY_PROPERTY_KEY, "iPhone_11");
51+
Capabilities capabilities = AqualityServices.get(IApplicationProfile.class).getDriverSettings().getCapabilities();
52+
Assert.assertEquals("iPhone 11", capabilities.getCapability("deviceName"));
53+
}
54+
55+
@Test
56+
public void testShouldBePossibleToGetDefaultDeviceSettingsForAndroidPlatform() {
57+
System.setProperty(PLATFORM_NAME_PROPERTY_KEY, "android");
58+
System.setProperty(DEVICE_KEY_PROPERTY_KEY, "Nexus");
59+
Capabilities capabilities = AqualityServices.get(IApplicationProfile.class).getDriverSettings().getCapabilities();
60+
Assert.assertEquals("Nexus", capabilities.getCapability("deviceName"));
61+
}
62+
63+
@Test
64+
public void testShouldBePossibleToOverrideDefaultDevice() {
65+
System.setProperty(PLATFORM_NAME_PROPERTY_KEY, "android");
66+
System.setProperty(DEVICE_KEY_PROPERTY_KEY, "Samsung_Galaxy");
67+
Capabilities capabilities = AqualityServices.get(IApplicationProfile.class).getDriverSettings().getCapabilities();
68+
Assert.assertEquals("Samsung Galaxy", capabilities.getCapability("deviceName"));
69+
}
70+
71+
@AfterClass
72+
public void afterAll() {
73+
System.clearProperty(DEVICES_PROFILE_PROPERTY_KEY);
74+
System.clearProperty(DEVICE_KEY_PROPERTY_KEY);
75+
System.clearProperty(PLATFORM_NAME_PROPERTY_KEY);
76+
}
77+
}

0 commit comments

Comments
 (0)