UNPKG

@testim/testim-cli

Version:

Command line interface for running Testing on you CI

114 lines (89 loc) 4.17 kB
var ErrorHandler = require('../utils/ErrorHandler.js'); module.exports = function findStrategy() { var value = arguments[0], relative = (arguments.length > 1 ? arguments[1] : false), using, query, tag, classOrId, classOrIdName, xpathPrefix; if (relative) { xpathPrefix = './'; } else { xpathPrefix = '//'; } if (typeof value !== 'string') { throw new ErrorHandler.ProtocolError('selector needs to be typeof `string`'); } if (arguments.length === 3) { return { using: arguments[0], value: arguments[1] }; } // check value type // use id strategy if value starts with # and doesnt contain any other CSS selector-relevant character if (value.indexOf('#') === 0 && value.search(/(\s|>|\.|[|])/) === -1) { using = 'id'; value = value.slice(1); // use xPath strategy if value starts with // } else if (value.indexOf('/') === 0 || value.indexOf('(') === 0 || value.indexOf('../') === 0 || value.indexOf('./') === 0 || value.indexOf('*/') === 0) { using = 'xpath'; // use link text startegy if value startes with = } else if (value.indexOf('=') === 0) { using = 'link text'; value = value.slice(1); // use partial link text startegy if value startes with *= } else if (value.indexOf('*=') === 0) { using = 'partial link text'; value = value.slice(2); // use tag name strategy if value contains a tag // e.g. "<div>" or "<div />" } else if (value.search(/<[a-zA-Z\-]+( \/)*>/g) >= 0) { using = 'tag name'; value = value.replace(/<|>|\/|\s/g, ''); // use name strategy if value queries elements with name attributes // e.g. "[name='myName']" or '[name="myName"]' } else if (value.search(/^\[name=("|')([a-zA-z0-9\-_ ]+)("|')\]$/) >= 0) { using = 'name'; value = value.match(/^\[name=("|')([a-zA-z0-9\-_ ]+)("|')\]$/)[2]; // any element with given text e.g. h1=Welcome } else if (value.search(/^[a-z0-9]*=(.)+$/) >= 0) { query = value.split(/=/); tag = query.shift(); using = 'xpath'; value = xpathPrefix + (tag.length ? tag : '*') + '[normalize-space() = "' + query.join('=') + '"]'; // any element containing given text } else if (value.search(/^[a-z0-9]*\*=(.)+$/) >= 0) { query = value.split(/\*=/); tag = query.shift(); using = 'xpath'; value = xpathPrefix + (tag.length ? tag : '*') + '[contains(., "' + query.join('*=') + '")]'; // any element with certian class or id + given content } else if (value.search(/^[a-z0-9]*(\.|#)-?[_a-zA-Z]+[_a-zA-Z0-9-]*=(.)+$/) >= 0) { query = value.split(/=/); tag = query.shift(); classOrId = tag.substr(tag.search(/(\.|#)/), 1) === '#' ? 'id' : 'class'; classOrIdName = tag.slice(tag.search(/(\.|#)/) + 1); tag = tag.substr(0, tag.search(/(\.|#)/)); using = 'xpath'; value = xpathPrefix + (tag.length ? tag : '*') + '[contains(@' + classOrId + ', "' + classOrIdName + '") and normalize-space() = "' + query.join('=') + '"]'; // any element with certian class or id + has certain content } else if (value.search(/^[a-z0-9]*(\.|#)-?[_a-zA-Z]+[_a-zA-Z0-9-]*\*=(.)+$/) >= 0) { query = value.split(/\*=/); tag = query.shift(); classOrId = tag.substr(tag.search(/(\.|#)/), 1) === '#' ? 'id' : 'class'; classOrIdName = tag.slice(tag.search(/(\.|#)/) + 1); tag = tag.substr(0, tag.search(/(\.|#)/)); using = 'xpath'; value = xpathPrefix + (tag.length ? tag : '*') + '[contains(@' + classOrId + ', "' + classOrIdName + '") and contains(., "' + query.join('*=') + '")]'; // allow to move up to the parent or select current element } else if (value === '..' || value === '.') { using = 'xpath'; // if nothing fits with the supported strategies we fall back to the css selector strategy } else { using = 'css selector'; } return { using: using, value: value }; };