Skip to content

Commit

Permalink
Add support for Appium locate strategies. (nightwatchjs#3620)
Browse files Browse the repository at this point in the history
  • Loading branch information
garg3133 authored and harshit-bs committed Mar 16, 2023
1 parent ad2ab3f commit 0150220
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 22 deletions.
8 changes: 3 additions & 5 deletions lib/element/appium-locator.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const {By, RelativeBy} = require('selenium-webdriver');

const LocateElement = require('./locator.js');
const {AVAILABLE_LOCATORS} = LocateElement;
const LocateStrategy = require('./strategy.js');

class AppiumLocator extends LocateElement {
/**
Expand All @@ -20,11 +20,9 @@ class AppiumLocator extends LocateElement {

const elementInstance = LocateElement.createElementInstance(element);

if (elementInstance.locateStrategy === 'id') {
return new By(elementInstance.locateStrategy, elementInstance.selector);
}
LocateStrategy.validate(elementInstance.locateStrategy);

return By[AVAILABLE_LOCATORS[elementInstance.locateStrategy]](elementInstance.selector);
return new By(elementInstance.locateStrategy, elementInstance.selector);
}
}

Expand Down
21 changes: 21 additions & 0 deletions lib/element/locator-factory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const {By, RelativeBy} = require('selenium-webdriver');

const Locator = require('./locator.js');
const AppiumLocator = require('./appium-locator.js');

class NightwatchLocator {
/**
* @param {object|string} element
* @param {boolean} isAppiumClient
* @return {By|RelativeBy}
*/
static create(element, isAppiumClient) {
if (isAppiumClient) {
return AppiumLocator.create(element);
}

return Locator.create(element);
}
}

module.exports = NightwatchLocator;
1 change: 0 additions & 1 deletion lib/element/locator.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,4 +337,3 @@ class NoSuchElementError extends Error {

module.exports = LocateElement;
module.exports.NoSuchElementError = NoSuchElementError;
module.exports.AVAILABLE_LOCATORS = AVAILABLE_LOCATORS;
11 changes: 9 additions & 2 deletions lib/element/strategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@ class LocateStrategy {
return {
ID: 'id',
CSS_SELECTOR: 'css selector',
LINK_TEST: 'link text',
LINK_TEXT: 'link text',
PARTIAL_LINK_TEXT: 'partial link text',
TAG_NAME: 'tag name',
XPATH: 'xpath'
XPATH: 'xpath',
NAME: 'name',
CLASS_NAME: 'class name',
// Appium-specific strategies
ACCESSIBILITY_ID: 'accessibility id',
ANDROID_UIAUTOMATOR: '-android uiautomator',
IOS_PREDICATE_STRING: '-ios predicate string',
IOS_CLASS_CHAIN: '-ios class chain'
};
}

Expand Down
11 changes: 3 additions & 8 deletions lib/transport/selenium-webdriver/method-mappings.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const {WebElement, WebDriver, Origin, By} = require('selenium-webdriver');
const {Locator} = require('../../element');
const AppiumLocator = require('../../element/appium-locator.js');
const NightwatchLocator = require('../../element/locator-factory.js');
const {isString} = require('../../utils');
const fs = require('fs');
const cdp = require('./cdp.js');
Expand Down Expand Up @@ -356,7 +356,7 @@ module.exports = class MethodMappings {
// Elements
///////////////////////////////////////////////////////////
async locateSingleElement(element) {
const locator = Locator.create(element);
const locator = NightwatchLocator.create(element, this.transport.api.isAppiumClient());
const webElement = await this.driver.findElement(locator);
const elementId = await webElement.getId();

Expand All @@ -368,12 +368,7 @@ module.exports = class MethodMappings {
},

async locateMultipleElements(element) {
let locator;
if (this.transport.api.isAppiumClient()) {
locator = AppiumLocator.create(element);
} else {
locator = Locator.create(element);
}
const locator = NightwatchLocator.create(element, this.transport.api.isAppiumClient());
const resultValue = await this.driver.findElements(locator);

if (Array.isArray(resultValue) && resultValue.length === 0) {
Expand Down
11 changes: 9 additions & 2 deletions lib/utils/locatestrategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@ class LocateStrategy {
return {
ID: 'id',
CSS_SELECTOR: 'css selector',
LINK_TEST: 'link text',
LINK_TEXT: 'link text',
PARTIAL_LINK_TEXT: 'partial link text',
TAG_NAME: 'tag name',
XPATH: 'xpath'
XPATH: 'xpath',
NAME: 'name',
CLASS_NAME: 'class name',
// Appium-specific strategies
ACCESSIBILITY_ID: 'accessibility id',
ANDROID_UIAUTOMATOR: '-android uiautomator',
IOS_PREDICATE_STRING: '-ios predicate string',
IOS_CLASS_CHAIN: '-ios class chain'
};
}

Expand Down
4 changes: 3 additions & 1 deletion test/apidemos/appium/appiumTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ describe('appium api demo', function () {

it('Search for Nightwatch', async function() {
app // available globally
.click('id', 'com.app:id/search')
.waitForElementPresent({selector: 'Search Wikipedia', locateStrategy: 'accessibility id'})
.click('accessibility id', 'Search Wikipedia')
.element('class name', 'android.widget.ImageButton')
.sendKeys('id', 'com.app:id/search', 'Nightwatch');
});
});
32 changes: 29 additions & 3 deletions test/src/apidemos/appium/testAppiumAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ describe('appium api demos', function () {
.addMock({
url: '/wd/hub/session/13521-10219-202/elements',
postdata: {
using: 'id',
value: 'com.app:id/search'
using: 'accessibility id',
value: 'Search Wikipedia'
},
method: 'POST',
response: JSON.stringify({
Expand All @@ -56,6 +56,32 @@ describe('appium api demos', function () {
value: [{'element-6066-11e4-a52e-4f735466cecf': '0'}]
})
}, true, true)
.addMock({
url: '/wd/hub/session/13521-10219-202/element',
postdata: {
using: 'class name',
value: 'android.widget.ImageButton'
},
method: 'POST',
response: JSON.stringify({
status: 0,
state: 'success',
value: {'element-6066-11e4-a52e-4f735466cecf': '1'}
})
}, true)
.addMock({
url: '/wd/hub/session/13521-10219-202/elements',
postdata: {
using: 'id',
value: 'com.app:id/search'
},
method: 'POST',
response: JSON.stringify({
status: 0,
state: 'success',
value: [{'element-6066-11e4-a52e-4f735466cecf': '2'}]
})
}, true)
.addMock({
url: '/wd/hub/session/13521-10219-202/element/0/click',
method: 'POST',
Expand All @@ -64,7 +90,7 @@ describe('appium api demos', function () {
})
}, true)
.addMock({
url: '/wd/hub/session/13521-10219-202/element/0/value',
url: '/wd/hub/session/13521-10219-202/element/2/value',
method: 'POST',
postdata: JSON.stringify({
text: 'Nightwatch',
Expand Down

0 comments on commit 0150220

Please sign in to comment.