UNPKG

webdriverio

Version:

Next-gen browser and mobile automation test framework for Node.js

228 lines (183 loc) 5.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.findStrategy = void 0; var _constants = require("../constants"); var _lodash = _interopRequireDefault(require("lodash.isplainobject")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const DEFAULT_STRATEGY = 'css selector'; const DIRECT_SELECTOR_REGEXP = /^(id|css selector|xpath|link text|partial link text|name|tag name|class name|-android uiautomator|-android datamatcher|-android viewmatcher|-android viewtag|-ios uiautomation|-ios predicate string|-ios class chain|accessibility id):(.+)/; const XPATH_SELECTORS_START = ['/', '(', '../', './', '*/']; const NAME_MOBILE_SELECTORS_START = ['uia', 'xcuielementtype', 'android.widget', 'cyi']; const XPATH_SELECTOR_REGEXP = [/^([a-z0-9|-]*)/, /(?:(\.|#)(-?[_a-zA-Z]+[_a-zA-Z0-9-]*))?/, /(?:\[(-?[_a-zA-Z]+[_a-zA-Z0-9-]*)(?:=(?:"|')([a-zA-z0-9\-_. ]+)(?:"|'))?\])?/, /(\*)?=(.+)$/]; const IMAGEPATH_MOBILE_SELECTORS_ENDSWITH = ['.jpg', '.jpeg', '.gif', '.png', '.bmp', '.svg']; const defineStrategy = function (selector) { if ((0, _lodash.default)(selector)) { if (JSON.stringify(selector).indexOf('test.espresso.matcher.ViewMatchers') < 0) return '-android datamatcher'; return '-android viewmatcher'; } if (selector.match(DIRECT_SELECTOR_REGEXP)) { return 'directly'; } if (IMAGEPATH_MOBILE_SELECTORS_ENDSWITH.some(path => selector.toLowerCase().endsWith(path))) { return '-image'; } if (XPATH_SELECTORS_START.some(option => selector.startsWith(option))) { return 'xpath'; } if (selector.startsWith('=')) { return 'link text'; } if (selector.startsWith('*=')) { return 'partial link text'; } if (selector.startsWith('id=')) { return 'id'; } if (selector.startsWith('android=')) { return '-android uiautomator'; } if (selector.startsWith('ios=')) { return '-ios uiautomation'; } if (selector.startsWith('~')) { return 'accessibility id'; } if (NAME_MOBILE_SELECTORS_START.some(option => selector.toLowerCase().startsWith(option))) { return 'class name'; } if (selector.search(/<[0-9a-zA-Z-]+( \/)*>/g) >= 0) { return 'tag name'; } if (selector.search(/^\[name=("|')([a-zA-z0-9\-_.@=[\] ']+)("|')]$/) >= 0) { return 'name'; } if (selector === '..' || selector === '.') { return 'xpath'; } if (selector.match(new RegExp(XPATH_SELECTOR_REGEXP.map(rx => rx.source).join('')))) { return 'xpath extended'; } }; const findStrategy = function (selector, isW3C, isMobile) { let using = DEFAULT_STRATEGY; let value = selector; switch (defineStrategy(selector)) { case 'directly': { const match = selector.match(DIRECT_SELECTOR_REGEXP); if (!isMobile && isW3C && !_constants.W3C_SELECTOR_STRATEGIES.includes(match[1])) { throw new Error('InvalidSelectorStrategy'); } using = match[1]; value = match[2]; break; } case 'xpath': { using = 'xpath'; break; } case 'id': { using = 'id'; value = selector.slice(3); break; } case 'link text': { using = 'link text'; value = selector.slice(1); break; } case 'partial link text': { using = 'partial link text'; value = selector.slice(2); break; } case '-android uiautomator': { using = '-android uiautomator'; value = selector.slice(8); break; } case '-android datamatcher': { using = '-android datamatcher'; value = JSON.stringify(value); break; } case '-android viewmatcher': { using = '-android viewmatcher'; value = JSON.stringify(value); break; } case '-ios uiautomation': { using = '-ios uiautomation'; value = selector.slice(4); break; } case 'accessibility id': { using = 'accessibility id'; value = selector.slice(1); break; } case 'class name': { using = 'class name'; break; } case 'tag name': { using = 'tag name'; value = selector.replace(/<|>|\/|\s/g, ''); break; } case 'name': { if (isMobile || !isW3C) { using = 'name'; value = selector.match(/^\[name=("|')([a-zA-z0-9\-_.@=[\] ']+)("|')]$/)[2]; } break; } case 'xpath extended': { using = 'xpath'; const match = selector.match(new RegExp(XPATH_SELECTOR_REGEXP.map(rx => rx.source).join(''))); const PREFIX_NAME = { '.': 'class', '#': 'id' }; const conditions = []; const [tag, prefix, name, attrName, attrValue, partial, query] = match.slice(1); if (prefix) { conditions.push(`contains(@${PREFIX_NAME[prefix]}, "${name}")`); } if (attrName) { conditions.push(attrValue ? `contains(@${attrName}, "${attrValue}")` : `@${attrName}`); } conditions.push(partial ? `contains(., "${query}")` : `normalize-space() = "${query}"`); value = `.//${tag || '*'}[${conditions.join(' and ')}]`; break; } case '-image': { using = '-image'; break; } } if (!isMobile && isW3C && !_constants.W3C_SELECTOR_STRATEGIES.includes(using)) { throw new Error('InvalidSelectorStrategy'); } return { using, value }; }; exports.findStrategy = findStrategy;