Skip to content

Commit

Permalink
Implement device settings [+semver: feature] (#21)
Browse files Browse the repository at this point in the history
* Implement device settings

* Fix pipeline and review comment

* Fix tests

* Change android emulator in pipeline

* Change Android emulator in pipeline

* Change android sdk id for emulator

* Update pipeline
  • Loading branch information
paveliam authored May 9, 2020
1 parent a5426cb commit c245fb2
Show file tree
Hide file tree
Showing 14 changed files with 290 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
<Copyright>Copyright 2020 Aquality Automation</Copyright>
<IsPackable>true</IsPackable>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DocumentationFile>Aquality.Appium.Mobile.xml</DocumentationFile>
<NoWarn>1701;1702;1591</NoWarn>
</PropertyGroup>
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Aquality.Selenium.Core.Configurations;
using Aquality.Selenium.Core.Logging;
using Aquality.Selenium.Core.Utilities;
using OpenQA.Selenium.Appium;
using System.Collections.Generic;
using System.Linq;

namespace Aquality.Appium.Mobile.Configurations
{
public class DeviceSettings : IDeviceSettings
{
private readonly ISettingsFile settingsFile;
private readonly string deviceKey;

public DeviceSettings(string deviceKey)
{
settingsFile = GetDevicesSettings();
this.deviceKey = deviceKey;
}

private ISettingsFile GetDevicesSettings()
{
var deviceProfileName = EnvironmentConfiguration.GetVariable("devicesProfile");
var devicesProfile = deviceProfileName == null
? "devices.json"
: $"devices.{deviceProfileName}.json";
Logger.Instance.Debug($"Get devices settings from: {devicesProfile}");
return new JsonSettingsFile(devicesProfile);
}

public AppiumOptions AppiumOptions
{
get
{
var deviceOptions = new AppiumOptions();
Capabilities.ToList().ForEach(capability => deviceOptions.AddAdditionalCapability(capability.Key, capability.Value));
return deviceOptions;
}
}

private IDictionary<string, object> Capabilities => settingsFile.GetValueOrNew<Dictionary<string, object>>($"{deviceKey}.capabilities");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public class DriverSettings : IDriverSettings
{
private const string ApplicationPathKey = "applicationPath";
private const string AppCapabilityKey = "app";
private const string DeviceKeyKey = "deviceKey";

private readonly ISettingsFile settingsFile;
private readonly PlatformName platformName;

Expand Down Expand Up @@ -42,10 +44,21 @@ public AppiumOptions AppiumOptions
{
options.AddAdditionalCapability(AppCapabilityKey, ApplicationPath);
}
DeviceOptions.ToDictionary().ToList().ForEach(capability => options.AddAdditionalCapability(capability.Key, capability.Value));
return options;
}
}

public string ApplicationPath => Path.GetFullPath(settingsFile.GetValue<string>(ApplicationPathJPath));

private AppiumOptions DeviceOptions
{
get
{
var deviceKey = settingsFile.GetValueOrDefault<string>($"{DriverSettingsPath}.{DeviceKeyKey}");
var deviceSettings = new DeviceSettings(deviceKey);
return deviceSettings.AppiumOptions;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using OpenQA.Selenium.Appium;

namespace Aquality.Appium.Mobile.Configurations
{
/// <summary>
/// Describes desired device settings.
/// </summary>
public interface IDeviceSettings
{
/// <summary>
/// Options (capabilities) related to desired device.
/// </summary>
AppiumOptions AppiumOptions { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"iOS_Simulator": {
"capabilities": {
"platformVersion": "<iOS_platform_version>",
"deviceName": "<iOS_simulator_name>"
}
},
"iPhone_NAME": {
"capabilities": {
"platformVersion": "<iOS_platform_version>",
"deviceName": "<iOS_device_name>",
"udid": "<iOS_device_udidi>",
"wdaLocalPort": "<wda_local_port>"
}
},
"Android_Emulator": {
"capabilities": {
"deviceName": "<Android_emulator_name>"
}
},
"Android_NAME": {
"capabilities": {
"deviceName": "<Android_device_name>",
"udid": "<Android_device_udid>",
"systemPort": "<appium_system_port>"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@

"driverSettings": {
"android": {
"deviceKey": "<KEY_OF_ANDROID_DEVICE_FROM_DEVICES_JSON>",
"applicationPath": "./Resources/Apps/ApiDemos-debug.apk",
"capabilities": {
"deviceName": "Android Emulator"
"platformName": "Android",
"automationName": "UiAutomator2"
}
},
"ios": {
"deviceKey": "<KEY_OF_IOS_DEVICE_FROM_DEVICES_JSON>",
"applicationPath": "./Resources/Apps/TestApp.app.zip",
"capabilities": {
"deviceName": "iOS Simulator",
"automationName": "XCUITest",
"platformName": "iOS",
"udid": "<SIMULATOR_ID/DEVICE_ID>"
"automationName": "XCUITest"
}
}
},
Expand All @@ -42,6 +43,6 @@
"language": "en"
},
"elementCache": {
"isEnabled": false
"isEnabled": true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
<None Update="Resources\Apps\ApiDemos-debug.apk">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Resources\devices.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Resources\devices.test.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Resources\settings.androidwebsession.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using Aquality.Appium.Mobile.Applications;
using Aquality.Appium.Mobile.Configurations;
using Castle.Core.Internal;
using NUnit.Framework;
using System;

namespace Aquality.Appium.Mobile.Tests.Integration
{
public class DeviceSettingsTests
{
private const string PlatformNamePropertyKey = "platformName";
private const string DevicesProfilePropertyKey = "devicesProfile";
private const string DevicesKeyPropertyKey = "driverSettings.android.deviceKey";

[Test]
public void Should_BePossible_ToGetDeviceCapabilities()
{
var deviceSettings = new DeviceSettings("iPhone_11");
var options = deviceSettings.AppiumOptions;
Assert.IsNotNull(options);
Assert.IsFalse(options.ToDictionary().IsNullOrEmpty());
}

[Test]
public void Should_BePossible_ToGetEmptyCapabilitiesWhenDeviceKeyIsNull()
{
var deviceSettings = new DeviceSettings(null);
var options = deviceSettings.AppiumOptions;
Assert.IsNotNull(options);
Assert.IsTrue(options.ToDictionary().IsNullOrEmpty());
}

[Test]
public void Should_BePossible_ToUseDifferentDevicesProfiles()
{
Environment.SetEnvironmentVariable(DevicesProfilePropertyKey, "test");
var deviceSettings = new DeviceSettings("iPhone_11");
var options = deviceSettings.AppiumOptions;
Assert.AreEqual("iPhone 11 test", options.ToDictionary()["deviceName"]);

Environment.SetEnvironmentVariable(DevicesProfilePropertyKey, null);
deviceSettings = new DeviceSettings("iPhone_11");
options = deviceSettings.AppiumOptions;
Assert.AreEqual("iPhone 11", options.ToDictionary()["deviceName"]);
}

[Test]
public void Should_BePossible_ToGetDefaultDeviceSettingsForIosPlatform()
{
Environment.SetEnvironmentVariable(PlatformNamePropertyKey, "ios");
Environment.SetEnvironmentVariable(DevicesKeyPropertyKey, "iPhone_11");
var options = AqualityServices.Get<IApplicationProfile>().DriverSettings.AppiumOptions;
Assert.AreEqual("iPhone 11", options.ToDictionary()["deviceName"]);
}

[Test]
public void Should_BePossible_ToGetDefaultDeviceSettingsForAndroidPlatform()
{
Environment.SetEnvironmentVariable(PlatformNamePropertyKey, "android");
Environment.SetEnvironmentVariable(DevicesKeyPropertyKey, "Nexus");
var options = AqualityServices.Get<IApplicationProfile>().DriverSettings.AppiumOptions;
Assert.AreEqual("Nexus", options.ToDictionary()["deviceName"]);
}

[Test]
public void Should_BePossible_ToOverrideDefaultDevice()
{
Environment.SetEnvironmentVariable(PlatformNamePropertyKey, "android");
Environment.SetEnvironmentVariable(DevicesKeyPropertyKey, "Samsung_Galaxy");
var options = AqualityServices.Get<IApplicationProfile>().DriverSettings.AppiumOptions;
Assert.AreEqual("Samsung Galaxy", options.ToDictionary()["deviceName"]);
}

[TearDown]
public void TearDown()
{
Environment.SetEnvironmentVariable(PlatformNamePropertyKey, null);
Environment.SetEnvironmentVariable(DevicesProfilePropertyKey, null);
Environment.SetEnvironmentVariable(DevicesKeyPropertyKey, null);
AqualityServices.SetStartup(new MobileStartup());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"iOS_Simulator": {
"capabilities": {
"platformVersion": "13.3",
"deviceName": "iPhone 11"
}
},
"iPhone_11": {
"capabilities": {
"platformVersion": "13.3",
"deviceName": "iPhone 11",
"udid": "device_udid",
"wdaLocalPort": "8081"
}
},
"Android_Emulator": {
"capabilities": {
"deviceName": "Android Emulator"
}
},
"Nexus": {
"capabilities": {
"deviceName": "Nexus",
"udid": "device_udid",
"systemPort": "8082"
}
},
"Samsung_Galaxy": {
"capabilities": {
"deviceName": "Samsung Galaxy",
"udid": "device_udid",
"systemPort": "8082"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"iPhone_11": {
"capabilities": {
"platformVersion": "13.3",
"deviceName": "iPhone 11 test",
"udid": "device_udid",
"wdaLocalPort": "8085"
}
},
"Nexus": {
"capabilities": {
"deviceName": "Nexus test",
"udid": "device_udid",
"systemPort": "8082"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@

"driverSettings": {
"android": {
"deviceKey": "Android_Emulator",
"applicationPath": "./Resources/Apps/ApiDemos-debug.apk",
"capabilities": {
"deviceName": "Android Emulator",
"platformName": "Android",
"automationName": "UIAutomator2",
"eventTimings": true,
"uiautomator2ServerInstallTimeout": 30000
}
},
"ios": {
"deviceKey": "iOS_Simulator",
"applicationPath": "./Resources/Apps/TestApp.app.zip",
"capabilities": {
"deviceName": "iOS Simulator",
"automationName": "XCUITest",
"platformName": "iOS",
"udid": "<SIMULATOR_ID/DEVICE_ID>"
"automationName": "XCUITest"
}
}
},
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,5 +145,15 @@ var loginScreen = AqualityServices.ScreenFactory.GetScreen<ILoginScreen>();

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

### Devices

Our library allows you to run tests on different devices and store their settings (like udid, name, etc.) in JSON files.

You have to add [devices.json](Aquality.Appium.Mobile/src/Aquality.Appium.Mobile/Resources/devices.json) file to resources where you can define a set of devices which you use to run tests.

It is possible to set default device for each platform in [settings.json](Aquality.Appium.Mobile/src/Aquality.Appium.Mobile/Resources/settings.json) by defining `deviceKey` property which is a key of device settings from `devices.json` file.

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 environment variable `devicesProfile: set1`.

### License
Library's source code is made available under the [Apache 2.0 license](LICENSE).
Loading

0 comments on commit c245fb2

Please sign in to comment.