Skip to content

Commit 4aa8450

Browse files
authored
feat: appium v2 support (#3622)
* feat: appium v2 support * Fix: Bump node version * fix: ubuntu bump * fix: try out another selenium version * try another php version * log webdriverio version * bump other wdio libs * fix: typo * fix: undefined error fix [1] Error | TypeError: Cannot read properties of undefined (reading 'restart') * fix: missing appiumV2 config * fix(docs): appium docs * fix: _convertedCaps logic
1 parent de8e0d4 commit 4aa8450

File tree

5 files changed

+99
-14
lines changed

5 files changed

+99
-14
lines changed

.github/workflows/webdriver.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ jobs:
2222
node-version: [16.x]
2323

2424
steps:
25-
- run: docker run -d --net=host --shm-size=2g selenium/standalone-chrome:3.141.59-oxygen
26-
- uses: actions/checkout@v3
25+
- run: docker run -d --net=host --shm-size=2g selenium/standalone-chrome:3.141.0
26+
- uses: actions/checkout@v1
2727
- name: Use Node.js ${{ matrix.node-version }}
2828
uses: actions/setup-node@v3
2929
with:
3030
node-version: ${{ matrix.node-version }}
3131
- uses: shivammathur/setup-php@v2
3232
with:
33-
php-version: 7.4
33+
php-version: 8.0
3434
- name: npm install
3535
run: |
3636
npm install --legacy-peer-deps

docs/helpers/Appium.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Launch the daemon: `appium`
2525

2626
This helper should be configured in codecept.conf.ts or codecept.conf.js
2727

28+
- `appiumV2`: set this to true if you want to run with Appiumv2
2829
- `app`: Application path. Local path or remote URL to an .ipa or .apk file, or a .zip containing one of these. Alias to desiredCapabilities.appPackage
2930
- `host`: (default: 'localhost') Appium host
3031
- `port`: (default: '4723') Appium port

docs/mobile.md

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,69 @@ To install Appium use npm:
4545
npm i -g appium
4646
```
4747

48+
To use Appium 2.x:
49+
```sh
50+
npm i -g appium@next
51+
```
52+
Appium 2x (still beta) reenvisions Appium as a platform where “drivers” and “plugins” can be easily created and shared independently.
53+
Install an Appium driver and its dependencies
54+
To install the Appium driver and its dependencies, we'll be using the uiautomator2 (Android), XCUITest (iOS) drivers.
55+
56+
```
57+
appium driver install xcuitest
58+
appium driver install uiautomator2
59+
```
60+
To make sure that all the drivers are installed successfully, run the following command:
61+
62+
```
63+
appium driver list
64+
65+
tth~$appium driver list
66+
✔ Listing available drivers
67+
- [email protected] [installed (NPM)]
68+
- [email protected] [installed (NPM)]
69+
- [email protected] [installed (NPM)]
70+
- mac2 [not installed]
71+
- safari [not installed]
72+
- gecko [not installed]
73+
- chromium [not installed]
74+
```
75+
4876
Then you need to prepare application for execution.
4977
It should be packed into apk (for Android) or .ipa (for iOS) or zip.
5078

51-
Next, is to launch the emulator or connect physical device.
79+
Next, is to launch the emulator or connect a physical device.
5280
Once they are prepared, launch Appium:
5381

5482
```sh
5583
appium
5684
```
5785

86+
To use Appium 2.x:
87+
```sh
88+
tth~$npx appium --base-path=/wd/hub
89+
[Appium] Welcome to Appium v2.0.0-beta.57 (REV 3e675c32ae71dc0b00749d5d29213e2ea5b53c5b)
90+
[Appium] Non-default server args:
91+
[Appium] {
92+
[Appium] basePath: '/wd/hub'
93+
[Appium] }
94+
[Appium] Attempting to load driver espresso...
95+
[debug] [Appium] Requiring driver at /Users/trung-thanh/Desktop/thanh-nguyen/task2/node_modules/appium-espresso-driver
96+
[Appium] Attempting to load driver uiautomator2...
97+
[debug] [Appium] Requiring driver at /Users/trung-thanh/Desktop/thanh-nguyen/task2/node_modules/appium-uiautomator2-driver
98+
[Appium] Appium REST http interface listener started on 0.0.0.0:4723
99+
[Appium] Available drivers:
100+
[Appium] - [email protected] (automationName 'Espresso')
101+
[Appium] - [email protected] (automationName 'UiAutomator2')
102+
[Appium] No plugins have been installed. Use the "appium plugin" command to install the one(s) you want to use.
103+
```
104+
58105
To run mobile test you need either an device emulator (available with Android SDK or iOS), real device connected for mobile testing. Alternatively, you may execute Appium with device emulator inside Docker container.
59106
60107
CodeceptJS should be installed with webdriverio support:
61108
62109
```bash
63-
npm install codeceptjs webdriverio --save
110+
npm install codeceptjs webdriverio@8.6.3 --save
64111
```
65112
66113
## Configuring

lib/helper/Appium.js

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ const supportedPlatform = {
1717
iOS: 'iOS',
1818
};
1919

20+
const vendorPrefix = {
21+
appium: 'appium',
22+
};
23+
2024
/**
2125
* Appium helper extends [Webriver](http://codecept.io/helpers/WebDriver/) helper.
2226
* It supports all browser methods and also includes special methods for mobile apps testing.
@@ -135,6 +139,9 @@ class Appium extends Webdriver {
135139
super(config);
136140

137141
this.isRunning = false;
142+
if (config.appiumV2 === true) {
143+
this.appiumV2 = true;
144+
}
138145
this.axios = axios.create();
139146

140147
webdriverio = require('webdriverio');
@@ -181,14 +188,22 @@ class Appium extends Webdriver {
181188

182189
config.baseUrl = config.url || config.baseUrl;
183190
if (config.desiredCapabilities && Object.keys(config.desiredCapabilities).length) {
184-
config.capabilities = config.desiredCapabilities;
191+
config.capabilities = this.appiumV2 === true ? this._convertAppiumV2Caps(config.desiredCapabilities) : config.desiredCapabilities;
192+
}
193+
194+
if (this.appiumV2) {
195+
config.capabilities[`${vendorPrefix.appium}:deviceName`] = config[`${vendorPrefix.appium}:device`] || config.capabilities[`${vendorPrefix.appium}:deviceName`];
196+
config.capabilities[`${vendorPrefix.appium}:browserName`] = config[`${vendorPrefix.appium}:browser`] || config.capabilities[`${vendorPrefix.appium}:browserName`];
197+
config.capabilities[`${vendorPrefix.appium}:app`] = config[`${vendorPrefix.appium}:app`] || config.capabilities[`${vendorPrefix.appium}:app`];
198+
config.capabilities[`${vendorPrefix.appium}:tunnelIdentifier`] = config[`${vendorPrefix.appium}:tunnelIdentifier`] || config.capabilities[`${vendorPrefix.appium}:tunnelIdentifier`]; // Adding the code to connect to sauce labs via sauce tunnel
199+
} else {
200+
config.capabilities.deviceName = config.device || config.capabilities.deviceName;
201+
config.capabilities.browserName = config.browser || config.capabilities.browserName;
202+
config.capabilities.app = config.app || config.capabilities.app;
203+
config.capabilities.tunnelIdentifier = config.tunnelIdentifier || config.capabilities.tunnelIdentifier; // Adding the code to connect to sauce labs via sauce tunnel
185204
}
186205

187-
config.capabilities.deviceName = config.device || config.capabilities.deviceName;
188-
config.capabilities.browserName = config.browser || config.capabilities.browserName;
189-
config.capabilities.app = config.app || config.capabilities.app;
190206
config.capabilities.platformName = config.platform || config.capabilities.platformName;
191-
config.capabilities.tunnelIdentifier = config.tunnelIdentifier || config.capabilities.tunnelIdentifier; // Adding the code to connect to sauce labs via sauce tunnel
192207
config.waitForTimeoutInSeconds = config.waitForTimeout / 1000; // convert to seconds
193208

194209
// [CodeceptJS compatible] transform host to hostname
@@ -203,13 +218,29 @@ class Appium extends Webdriver {
203218
}
204219

205220
this.platform = null;
221+
if (config.capabilities[`${vendorPrefix.appium}:platformName`]) {
222+
this.platform = config.capabilities[`${vendorPrefix.appium}:platformName`].toLowerCase();
223+
}
224+
206225
if (config.capabilities.platformName) {
207226
this.platform = config.capabilities.platformName.toLowerCase();
208227
}
209228

210229
return config;
211230
}
212231

232+
_convertAppiumV2Caps(capabilities) {
233+
const _convertedCaps = {};
234+
for (const [key, value] of Object.entries(capabilities)) {
235+
if (!key.startsWith(vendorPrefix.appium)) {
236+
_convertedCaps[`${vendorPrefix.appium}:${key}`] = value;
237+
} else {
238+
_convertedCaps[`${key}`] = value;
239+
}
240+
}
241+
return _convertedCaps;
242+
}
243+
213244
static _config() {
214245
return [{
215246
name: 'app',
@@ -229,6 +260,11 @@ class Appium extends Webdriver {
229260
}
230261

231262
async _startBrowser() {
263+
if (this.appiumV2 === true) {
264+
this.options.capabilities = this._convertAppiumV2Caps(this.options.capabilities);
265+
this.options.desiredCapabilities = this._convertAppiumV2Caps(this.options.desiredCapabilities);
266+
}
267+
232268
try {
233269
if (this.options.multiremote) {
234270
this.browser = await webdriverio.multiremote(this.options.multiremote);
@@ -445,6 +481,7 @@ class Appium extends Webdriver {
445481
*/
446482
async checkIfAppIsInstalled(bundleId) {
447483
onlyForApps.call(this, supportedPlatform.android);
484+
448485
return this.browser.isAppInstalled(bundleId);
449486
}
450487

@@ -481,7 +518,7 @@ class Appium extends Webdriver {
481518
async seeAppIsNotInstalled(bundleId) {
482519
onlyForApps.call(this, supportedPlatform.android);
483520
const res = await this.browser.isAppInstalled(bundleId);
484-
return truth(`app ${bundleId}`, 'to be installed').negate(res);
521+
return truth(`app ${bundleId}`, 'not to be installed').negate(res);
485522
}
486523

487524
/**

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@
9797
"@pollyjs/core": "^5.1.0",
9898
"@types/inquirer": "^0.0.35",
9999
"@types/node": "^8.10.66",
100-
"@wdio/sauce-service": "^5.22.5",
101-
"@wdio/selenium-standalone-service": "^5.16.10",
102-
"@wdio/utils": "^5.23.0",
100+
"@wdio/sauce-service": "^8.3.8",
101+
"@wdio/selenium-standalone-service": "^8.3.2",
102+
"@wdio/utils": "^8.3.0",
103103
"apollo-server-express": "^2.25.3",
104104
"chai-as-promised": "^7.1.1",
105105
"chai-subset": "^1.6.0",

0 commit comments

Comments
 (0)