UNPKG

@applitools/spec-driver-selenium

Version:
402 lines (401 loc) 17.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.build = exports.switchWorld = exports.getWorlds = exports.getCurrentWorld = exports.takeScreenshot = exports.performAction = exports.visit = exports.getUrl = exports.getTitle = exports.getCookies = exports.getSystemBars = exports.setOrientation = exports.getOrientation = exports.setWindowSize = exports.getWindowSize = exports.getCapabilities = exports.getDriverInfo = exports.childContext = exports.parentContext = exports.mainContext = exports.click = exports.hover = exports.getElementText = exports.setElementText = exports.getElementAttribute = exports.getElementRegion = exports.waitForSelector = exports.findElements = exports.findElement = exports.executeScript = exports.toSimpleCommonSelector = exports.toSelector = exports.toDriver = exports.isStaleElementError = exports.isEqualElements = exports.isSelector = exports.isElement = exports.isDriver = void 0; const command_1 = require("selenium-webdriver/lib/command"); const Selenium = __importStar(require("selenium-webdriver")); const utils = __importStar(require("@applitools/utils")); function extractElementId(element) { return isElement(element) ? element.getId() : element['shadow-6066-11e4-a52e-4f735466cecf']; } function transformShadowRoot(driver, shadowRoot) { return utils.types.has(shadowRoot, 'shadow-6066-11e4-a52e-4f735466cecf') ? new Selenium.WebElement(driver, shadowRoot['shadow-6066-11e4-a52e-4f735466cecf']) : shadowRoot; } const byHash = ['className', 'css', 'id', 'js', 'linkText', 'name', 'partialLinkText', 'tagName', 'xpath']; function isByHashSelector(selector) { return byHash.includes(Object.keys(selector)[0]); } async function executeCustomCommand(driver, command) { return process.env.APPLITOOLS_FRAMEWORK_MAJOR_VERSION === '3' ? driver.schedule(command) : driver.execute(command); } function isDriver(driver) { return utils.types.instanceOf(driver, 'WebDriver'); } exports.isDriver = isDriver; function isElement(element) { return utils.types.instanceOf(element, 'WebElement'); } exports.isElement = isElement; function isSelector(selector) { if (!selector) return false; return (utils.types.has(selector, ['using', 'value']) || isByHashSelector(selector) || utils.types.isFunction(selector) || utils.types.instanceOf(selector, 'RelativeBy')); } exports.isSelector = isSelector; async function isEqualElements(_driver, element1, element2) { if (!element1 || !element2) return false; const elementId1 = await extractElementId(element1); const elementId2 = await extractElementId(element2); return elementId1 === elementId2; } exports.isEqualElements = isEqualElements; function isStaleElementError(error) { if (!error) return false; error = error.originalError || error; return error instanceof Error && error.name === 'StaleElementReferenceError'; } exports.isStaleElementError = isStaleElementError; function toDriver(driver) { driver.getExecutor().defineCommand('getOrientation', 'GET', '/session/:sessionId/orientation'); driver.getExecutor().defineCommand('getSystemBars', 'GET', '/session/:sessionId/appium/device/system_bars'); driver.getExecutor().defineCommand('getWindowSize', 'GET', '/session/:sessionId/window/current/size'); driver.getExecutor().defineCommand('setWindowSize', 'POST', '/session/:sessionId/window/current/size'); driver.getExecutor().defineCommand('setWindowPosition', 'POST', '/session/:sessionId/window/current/position'); driver.getExecutor().defineCommand('performTouch', 'POST', '/session/:sessionId/touch/perform'); driver.getExecutor().defineCommand('executeCdp', 'POST', '/session/:sessionId/chromium/send_command_and_get_result'); driver.getExecutor().defineCommand('setOrientation', 'POST', '/session/:sessionId/orientation'); driver.getExecutor().defineCommand('getCurrentContext', 'GET', '/session/:sessionId/context'); driver.getExecutor().defineCommand('getContexts', 'GET', '/session/:sessionId/contexts'); driver.getExecutor().defineCommand('switchToContext', 'POST', '/session/:sessionId/context'); if (process.env.APPLITOOLS_FRAMEWORK_MAJOR_VERSION === '3') { driver.getExecutor().defineCommand('switchToParentFrame', 'POST', '/session/:sessionId/frame/parent'); } return driver; } exports.toDriver = toDriver; function toSelector(selector) { if (utils.types.isString(selector)) { return { css: selector }; } else if (utils.types.has(selector, 'selector')) { if (!utils.types.isString(selector.selector)) return selector.selector; if (!utils.types.has(selector, 'type') || !selector.type) return { css: selector.selector }; if (selector.type === 'css') return { css: selector.selector }; else return { using: selector.type, value: selector.selector }; } return selector; } exports.toSelector = toSelector; function toSimpleCommonSelector(selector) { if (utils.types.instanceOf(selector, 'RelativeBy') || utils.types.isFunction(selector)) { return null; } else if (isByHashSelector(selector)) { const [[how, what]] = Object.entries(selector); if (how === 'js') return null; selector = Selenium.By[how](what); } if (utils.types.has(selector, ['using', 'value'])) { return { type: selector.using === 'css selector' ? 'css' : selector.using, selector: selector.value }; } return selector; } exports.toSimpleCommonSelector = toSimpleCommonSelector; async function executeScript(driver, script, arg) { return driver.executeScript(script, arg); } exports.executeScript = executeScript; async function findElement(driver, selector, parent) { try { const root = parent ? transformShadowRoot(driver, parent) : driver; return await root.findElement(selector); } catch (err) { if (err.name === 'NoSuchElementError') return null; else throw err; } } exports.findElement = findElement; async function findElements(driver, selector, parent) { const root = parent ? transformShadowRoot(driver, parent) : driver; return root.findElements(selector); } exports.findElements = findElements; async function waitForSelector(driver, selector, _parent, options) { if ((options === null || options === void 0 ? void 0 : options.state) === 'visible') { const element = await driver.findElement(selector); return driver.wait(Selenium.until.elementIsVisible(element), options === null || options === void 0 ? void 0 : options.timeout); } else { return driver.wait(Selenium.until.elementLocated(selector), options === null || options === void 0 ? void 0 : options.timeout); } } exports.waitForSelector = waitForSelector; async function getElementRegion(_driver, element) { if (utils.types.isFunction(element.getRect)) { return element.getRect(); } else { const { x, y } = await element.getLocation(); const { width, height } = await element.getSize(); return { x, y, width, height }; } } exports.getElementRegion = getElementRegion; async function getElementAttribute(_driver, element, attr) { return element.getAttribute(attr); } exports.getElementAttribute = getElementAttribute; async function setElementText(_driver, element, keys) { await element.clear(); await element.sendKeys(keys); } exports.setElementText = setElementText; async function getElementText(_driver, element) { return element.getText(); } exports.getElementText = getElementText; async function hover(driver, element) { if (process.env.APPLITOOLS_FRAMEWORK_MAJOR_VERSION === '3') { let frameworkPath; try { frameworkPath = require.resolve('selenium-webdriver', { paths: [`${process.cwd()}/node_modules`] }); } catch { frameworkPath = 'selenium-webdriver'; } const { ActionSequence } = require(frameworkPath); const action = new ActionSequence(driver); await action.mouseMove(element).perform(); } else { await driver.actions().move({ origin: element }).perform(); } } exports.hover = hover; async function click(_driver, element) { await element.click(); } exports.click = click; async function mainContext(driver) { await driver.switchTo().defaultContent(); return driver; } exports.mainContext = mainContext; async function parentContext(driver) { if (process.env.APPLITOOLS_FRAMEWORK_MAJOR_VERSION === '3') { await executeCustomCommand(driver, new command_1.Command('switchToParentFrame')); return driver; } await driver.switchTo().parentFrame(); return driver; } exports.parentContext = parentContext; async function childContext(driver, element) { await driver.switchTo().frame(element); return driver; } exports.childContext = childContext; async function getDriverInfo(driver) { const session = await driver.getSession(); return { sessionId: session.getId() }; } exports.getDriverInfo = getDriverInfo; async function getCapabilities(driver) { return await driver .getCapabilities() .then(capabilities => Array.from(capabilities.keys()).reduce((obj, key) => Object.assign(obj, { [key]: capabilities.get(key) }), {})); } exports.getCapabilities = getCapabilities; async function getWindowSize(driver) { try { const rect = await driver.manage().window().getRect(); return { width: rect.width, height: rect.height }; } catch { const size = driver.manage().window().getSize ? await driver.manage().window().getSize() : await executeCustomCommand(driver, new command_1.Command('getWindowSize')); return { width: size.width, height: size.height }; } } exports.getWindowSize = getWindowSize; async function setWindowSize(driver, size) { try { await driver.manage().window().setRect({ x: 0, y: 0, width: size.width, height: size.height }); } catch { if (driver.manage().window().setPosition) await driver.manage().window().setPosition(0, 0); else await executeCustomCommand(driver, new command_1.Command('setWindowPosition').setParameters({ x: 0, y: 0 })); if (driver.manage().window().setSize) await driver.manage().window().setSize(size.width, size.height); else await executeCustomCommand(driver, new command_1.Command('setWindowSize').setParameters({ ...size })); } } exports.setWindowSize = setWindowSize; async function getOrientation(driver) { const orientation = await executeCustomCommand(driver, new command_1.Command('getOrientation')); return orientation.toLowerCase(); } exports.getOrientation = getOrientation; async function setOrientation(driver, orientation) { await executeCustomCommand(driver, new command_1.Command('setOrientation').setParameters({ orientation })); } exports.setOrientation = setOrientation; async function getSystemBars(driver) { return executeCustomCommand(driver, new command_1.Command('getSystemBars')); } exports.getSystemBars = getSystemBars; async function getCookies(driver, context) { if (context) return driver.manage().getCookies(); let cookies; if (utils.types.isFunction(driver, 'sendAndGetDevToolsCommand')) { const response = await driver.sendAndGetDevToolsCommand('Network.getAllCookies'); cookies = response.cookies; } else { const response = await executeCustomCommand(driver, new command_1.Command('executeCdp').setParameter('cmd', 'Network.getAllCookies').setParameter('params', {})); cookies = response.cookies; } return cookies.map((cookie) => { const copy = { ...cookie, expiry: cookie.expires }; delete copy.expires; delete copy.size; delete copy.priority; delete copy.session; delete copy.sameParty; delete copy.sourceScheme; delete copy.sourcePort; return copy; }); } exports.getCookies = getCookies; async function getTitle(driver) { return driver.getTitle(); } exports.getTitle = getTitle; async function getUrl(driver) { return driver.getCurrentUrl(); } exports.getUrl = getUrl; async function visit(driver, url) { await driver.get(url); } exports.visit = visit; async function performAction(driver, steps) { await executeCustomCommand(driver, new command_1.Command('performTouch').setParameters({ actions: steps.map(({ action, ...options }) => ({ action, options })), })); } exports.performAction = performAction; async function takeScreenshot(driver) { return driver.takeScreenshot(); } exports.takeScreenshot = takeScreenshot; async function getCurrentWorld(driver) { return executeCustomCommand(driver, new command_1.Command('getCurrentContext')); } exports.getCurrentWorld = getCurrentWorld; async function getWorlds(driver) { return executeCustomCommand(driver, new command_1.Command('getContexts')); } exports.getWorlds = getWorlds; async function switchWorld(driver, name) { return executeCustomCommand(driver, new command_1.Command('switchToContext').setParameters({ name })); } exports.switchWorld = switchWorld; const browserOptionsNames = { chrome: 'goog:chromeOptions', firefox: 'moz:firefoxOptions', }; /* * Spawn a browser with a given configuration (INTERNAL USE ONLY) * * NOTE: * This function is intended for internal use only. As a result it relies on some dev dependencies. * When wiring the spec-driver up to an SDK and calling this function, if you don't have the same dev deps * installed in the SDK, then this function will error. */ async function build(env) { var _a; let frameworkPath; try { frameworkPath = require.resolve('selenium-webdriver', { paths: [`${process.cwd()}/node_modules`] }); } catch { frameworkPath = 'selenium-webdriver'; } const { Builder } = require(frameworkPath); const parseEnv = require('@applitools/test-utils/src/parse-env'); const { browser, capabilities, url, attach, proxy, configurable = true, appium = false, args = [], headless, } = parseEnv({ ...env, legacy: (_a = env.legacy) !== null && _a !== void 0 ? _a : process.env.APPLITOOLS_FRAMEWORK_MAJOR_VERSION === '3' }); const desiredCapabilities = { ...capabilities }; if (configurable) { const browserOptionsName = browserOptionsNames[browser || desiredCapabilities.browserName]; if (browserOptionsName) { const browserOptions = desiredCapabilities[browserOptionsName] || {}; browserOptions.args = [...(browserOptions.args || []), ...args]; if (headless) browserOptions.args.push('headless'); if (attach) { browserOptions.debuggerAddress = attach === true ? 'localhost:9222' : attach; } desiredCapabilities[browserOptionsName] = browserOptions; } } if (browser === 'chrome') { if (appium) { desiredCapabilities['appium:chromeOptions'] = { w3c: false, ...desiredCapabilities['appium:chromeOptions'] }; } else if (process.env.APPLITOOLS_FRAMEWORK_MAJOR_VERSION === '3') { desiredCapabilities['goog:chromeOptions'] = { w3c: false, ...desiredCapabilities['goog:chromeOptions'] }; } } const builder = new Builder().withCapabilities(desiredCapabilities); if (url && !attach) builder.usingServer(url.href); if (proxy) { builder.setProxy({ proxyType: 'manual', httpProxy: proxy.http || proxy.server, sslProxy: proxy.https || proxy.server, ftpProxy: proxy.ftp, noProxy: proxy.bypass, }); } const driver = await builder.build(); driver.__serverUrl = url; return [driver, () => driver.quit()]; } exports.build = build;