"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.findStrategy = void 0; const fs_1 = __importDefault(require("fs")); const lodash_isplainobject_1 = __importDefault(require("lodash.isplainobject")); const constants_1 = require("../constants"); 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 (lodash_isplainobject_1.default(selector)) { if (JSON.stringify(selector).indexOf('test.espresso.matcher.ViewMatchers') < 0) return '-android datamatcher'; return '-android viewmatcher'; } const stringSelector = selector; if (stringSelector.match(DIRECT_SELECTOR_REGEXP)) { return 'directly'; } if (IMAGEPATH_MOBILE_SELECTORS_ENDSWITH.some(path => stringSelector.toLowerCase().endsWith(path))) { return '-image'; } if (XPATH_SELECTORS_START.some(option => stringSelector.startsWith(option))) { return 'xpath'; } if (stringSelector.startsWith('=')) { return 'link text'; } if (stringSelector.startsWith('*=')) { return 'partial link text'; } if (stringSelector.startsWith('id=')) { return 'id'; } if (stringSelector.startsWith('android=')) { return '-android uiautomator'; } if (stringSelector.startsWith('ios=')) { return '-ios uiautomation'; } if (stringSelector.startsWith('~')) { return 'accessibility id'; } if (NAME_MOBILE_SELECTORS_START.some(option => stringSelector.toLowerCase().startsWith(option))) { return 'class name'; } if (stringSelector.search(/<[0-9a-zA-Z-]+( \/)*>/g) >= 0) { return 'tag name'; } if (stringSelector.search(/^\[name=("|')([a-zA-z0-9\-_.@=[\] ']+)("|')]$/) >= 0) { return 'name'; } if (selector === '..' || selector === '.') { return 'xpath'; } if (stringSelector.match(new RegExp(XPATH_SELECTOR_REGEXP.map(rx => rx.source).join('')))) { return 'xpath extended'; } }; exports.findStrategy = function (selector, isW3C, isMobile) { const stringSelector = selector; let using = DEFAULT_STRATEGY; let value = selector; switch (defineStrategy(selector)) { case 'directly': { const match = stringSelector.match(DIRECT_SELECTOR_REGEXP); if (!match || !isMobile && isW3C && !constants_1.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 = stringSelector.slice(3); break; } case 'link text': { using = 'link text'; value = stringSelector.slice(1); break; } case 'partial link text': { using = 'partial link text'; value = stringSelector.slice(2); break; } case '-android uiautomator': { using = '-android uiautomator'; value = stringSelector.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 = stringSelector.slice(4); break; } case 'accessibility id': { using = 'accessibility id'; value = stringSelector.slice(1); break; } case 'class name': { using = 'class name'; break; } case 'tag name': { using = 'tag name'; value = stringSelector.replace(/<|>|\/|\s/g, ''); break; } case 'name': { if (isMobile || !isW3C) { const match = stringSelector.match(/^\[name=("|')([a-zA-z0-9\-_.@=[\] ']+)("|')]$/); if (!match) { throw new Error(`InvalidSelectorMatch. Strategy 'name' has failed to match '${stringSelector}'`); } using = 'name'; value = match[2]; } break; } case 'xpath extended': { using = 'xpath'; const match = stringSelector.match(new RegExp(XPATH_SELECTOR_REGEXP.map(rx => rx.source).join(''))); if (!match) { throw new Error(`InvalidSelectorMatch: Strategy 'xpath extended' has failed to match '${stringSelector}'`); } 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'; value = fs_1.default.readFileSync(stringSelector, { encoding: 'base64' }); break; } } if (!isMobile && isW3C && !constants_1.W3C_SELECTOR_STRATEGIES.includes(using)) { throw new Error('InvalidSelectorStrategy'); } return { using, value }; };