UNPKG

systelab-components-wdio-test

Version:
464 lines (460 loc) 16.5 kB
import * as tmp from "tmp"; import fs from "fs"; import { LocatorType } from "./locator.js"; import { AutomationEnvironment, BrowserType } from "./automation-environment.js"; import { Constants } from "../constants.js"; import { ElementFinderRemote } from "../remote/client/element-finder-remote.js"; export class ElementFinder { constructor(locator, parent = null) { this.locator = locator; this.parent = parent; } getLocator() { return this.locator; } getLocatorsChain() { let locators = []; if (this.parent) { locators = this.parent.getLocatorsChain(); } locators.push(this.locator); return locators; } byId(id) { return new ElementFinder({ type: LocatorType.ElementSelector, selector: `#${id}` }, this); } byTagName(tagName) { return new ElementFinder({ type: LocatorType.ElementSelector, selector: `<${tagName}>` }, this); } byClassName(className) { return new ElementFinder({ type: LocatorType.ElementSelector, selector: `.${className}` }, this); } byCSS(cssExpression) { return new ElementFinder({ type: LocatorType.ElementSelector, selector: cssExpression }, this); } byButtonText(text) { return this.byElementText('button', text); } byElementText(tagName, text) { return new ElementFinder({ type: LocatorType.ElementSelector, selector: `${tagName}*=${text}` }, this); } bySystelabTestId(systelabTestId) { return new ElementFinder({ type: LocatorType.ElementSelector, selector: `[${Constants.SYSTELAB_TEST_ID_ATTRIBUTE}='${systelabTestId}']` }, this); } allByTagName(tagName) { return new ElementArrayFinder({ type: LocatorType.ArraySelector, selector: `<${tagName}>` }, this); } allByClassName(className) { return new ElementArrayFinder({ type: LocatorType.ArraySelector, selector: `.${className}` }, this); } allByCSS(cssExpression) { return new ElementArrayFinder({ type: LocatorType.ArraySelector, selector: cssExpression }, this); } allBySystelabTestId(systelabTestId) { return new ElementArrayFinder({ type: LocatorType.ArraySelector, selector: `[${Constants.SYSTELAB_TEST_ID_ATTRIBUTE}='${systelabTestId}']` }, this); } async isPresent() { if (AutomationEnvironment.isLocalMode()) { return (await this.findElement()).isExisting(); } else { return this.findRemoteElement().isPresent(); } } async isDisplayed() { if (AutomationEnvironment.isLocalMode()) { return (await this.findElement()).isDisplayed(); } else { return this.findRemoteElement().isDisplayed(); } } async isClickable() { if (AutomationEnvironment.isLocalMode()) { return (await this.findElement()).isClickable(); } else { return this.findRemoteElement().isClickable(); } } async isEnabled() { if (AutomationEnvironment.isLocalMode()) { return (await this.findElement()).isEnabled(); } else { return this.findRemoteElement().isEnabled(); } } async isSelected() { if (AutomationEnvironment.isLocalMode()) { return (await this.findElement()).isSelected(); } else { return this.findRemoteElement().isSelected(); } } async isFocused() { if (AutomationEnvironment.isLocalMode()) { return (await this.findElement()).isFocused(); } else { return this.findRemoteElement().isFocused(); } } async getText() { if (AutomationEnvironment.isLocalMode()) { const browserType = AutomationEnvironment.getBrowserType(); if (browserType === BrowserType.TauriApp || browserType === BrowserType.WebKitGTK) { return (await this.findElement()).getHTML(false); } else { return (await this.findElement()).getText(); } } else { return this.findRemoteElement().getText(); } } async getValue() { if (AutomationEnvironment.isLocalMode()) { return (await this.findElement()).getValue(); } else { return this.findRemoteElement().getValue(); } } async getHTML(includeSelectorTag) { if (AutomationEnvironment.isLocalMode()) { return (await this.findElement()).getHTML(includeSelectorTag); } else { return this.findRemoteElement().getHTML(includeSelectorTag); } } async getAttribute(name) { if (AutomationEnvironment.isLocalMode()) { return (await this.findElement()).getAttribute(name); } else { return this.findRemoteElement().getAttribute(name); } } async getCSSProperty(name, pseudoElement) { if (AutomationEnvironment.isLocalMode()) { return (await (await this.findElement()).getCSSProperty(name, pseudoElement)).value; } else { return this.findRemoteElement().getCSSProperty(name, pseudoElement); } } async getProperty(name) { if (AutomationEnvironment.isLocalMode()) { return (await this.findElement()).getProperty(name); } else { return this.findRemoteElement().getProperty(name); } } async getBoundingRect() { if (AutomationEnvironment.isLocalMode()) { const position = await this.getPosition(); const size = await this.getSize(); return { ...position, ...size }; } else { return this.findRemoteElement().getBoundingRect(); } } async getPosition() { if (AutomationEnvironment.isLocalMode()) { return (await this.findElement()).getLocation(); } else { return this.findRemoteElement().getPosition(); } } async getSize() { if (AutomationEnvironment.isLocalMode()) { return (await this.findElement()).getSize(); } else { return this.findRemoteElement().getSize(); } } async click() { if (AutomationEnvironment.isLocalMode()) { const element = await this.findElement(); if (AutomationEnvironment.getBrowserType() === BrowserType.TauriApp) { return AutomationEnvironment.getWorkingBrowser().execute('arguments[0].click()', element); } else { return element.click(); } } else { return this.findRemoteElement().click(); } } async moveTo() { if (AutomationEnvironment.isLocalMode()) { const element = await this.findElement(); if (AutomationEnvironment.getBrowserType() === BrowserType.TauriApp) { return AutomationEnvironment.getWorkingBrowser().execute(` const el = arguments[0]; const rect = el.getBoundingClientRect(); const x = rect.left + (rect.width / 2); const y = rect.top + (rect.height / 2); const mouseMove = new MouseEvent('mousemove', { view: window, bubbles: true, cancelable: true, clientX: x, clientY: y }); const mouseOver = new MouseEvent('mouseover', { view: window, bubbles: true, cancelable: true, clientX: x, clientY: y }); el.dispatchEvent(mouseMove); el.dispatchEvent(mouseOver); `, element); } else { return element.moveTo(); } } else { return this.findRemoteElement().moveTo(); } } async clear() { if (AutomationEnvironment.isLocalMode()) { const element = await this.findElement(); if (AutomationEnvironment.getBrowserType() === BrowserType.TauriApp) { return AutomationEnvironment.getWorkingBrowser().execute(` const el = arguments[0]; el.value=""; el.dispatchEvent(new Event("input", { bubbles: true })); `, element); } else { return element.clearValue(); } } else { return this.findRemoteElement().clear(); } } async write(text) { if (AutomationEnvironment.isLocalMode()) { const element = await this.findElement(); if (AutomationEnvironment.getBrowserType() === BrowserType.TauriApp) { return AutomationEnvironment.getWorkingBrowser().execute((element, newValue) => { element.value = newValue; element.dispatchEvent(new Event("input", { bubbles: true })); element.dispatchEvent(new KeyboardEvent("keyup", { bubbles: true })); }, element, text); } else { return element.setValue(text); } } else { return this.findRemoteElement().write(text); } } async tap() { if (AutomationEnvironment.isLocalMode()) { const element = await this.findElement(); await AutomationEnvironment.getWorkingBrowser().execute((element) => { const touchPoint = new Touch({ identifier: Date.now(), target: element, clientX: 0, clientY: 0, pageX: 0, pageY: 0, screenX: 0, screenY: 0 }); const touchStartEvent = new TouchEvent('touchstart', { cancelable: true, bubbles: true, touches: [touchPoint], targetTouches: [], changedTouches: [touchPoint] }); element.dispatchEvent(touchStartEvent); const touchEndEvent = new TouchEvent('touchend', { cancelable: true, bubbles: true, touches: [touchPoint], targetTouches: [], changedTouches: [touchPoint] }); element.dispatchEvent(touchEndEvent); }, element); } else { return this.findRemoteElement().tap(); } } async scrollToElement(options = { behavior: 'auto', block: 'center', inline: 'nearest' }) { if (AutomationEnvironment.isLocalMode()) { const element = await this.findElement(); return element.scrollIntoView(options); } else { return this.findRemoteElement().scrollToElement(options); } } async waitToBePresent(timeout = 500) { if (AutomationEnvironment.isLocalMode()) { await (await this.findElement()).waitForExist({ timeout }); } else { await this.findRemoteElement().waitToBePresent(timeout); } } async waitToBeDisplayed(timeout = 500) { if (AutomationEnvironment.isLocalMode()) { await (await this.findElement()).waitForDisplayed({ timeout }); } else { await this.findRemoteElement().waitToBeDisplayed(timeout); } } async waitToBeClickable(timeout = 500) { if (AutomationEnvironment.isLocalMode()) { await (await this.findElement()).waitForClickable({ timeout }); } else { await this.findRemoteElement().waitToBeClickable(timeout); } } async waitToBeEnabled(timeout = 500) { if (AutomationEnvironment.isLocalMode()) { await (await this.findElement()).waitForEnabled({ timeout }); } else { await this.findRemoteElement().waitToBeEnabled(timeout); } } async waitUntil(condition, timeout = 5000) { if (AutomationEnvironment.isLocalMode()) { await (await this.findElement()).waitUntil(condition, { timeout }); } else { await this.findRemoteElement().waitUntil(condition, timeout); } } async takeScreenshot() { if (AutomationEnvironment.isLocalMode()) { const tempFilepath = tmp.tmpNameSync({ postfix: '.png' }); const screenshotBuffer = await (await this.findElement()).saveScreenshot(tempFilepath); fs.unlinkSync(tempFilepath); return screenshotBuffer.toString('base64'); } else { return this.findRemoteElement().takeScreenshot(); } } async saveScreenshot(filepath) { if (AutomationEnvironment.isLocalMode()) { await (await this.findElement()).saveScreenshot(filepath); } else { return this.findRemoteElement().saveScreenshot(filepath); } } async findElement() { if (this.parent) { if (this.parent.getLocator().type == LocatorType.ElementSelector || this.parent.getLocator().type == LocatorType.ArrayItem) { return await (await this.parent.findElement()).$(this.locator.selector); } else if (this.parent.getLocator().type == LocatorType.ArraySelector) { return (await this.parent.findElements())[this.locator.index]; } else { throw 'Unsupported locator type for parent item: ' + this.parent.getLocator().type; } } else { return AutomationEnvironment.getWorkingBrowser().$(this.locator.selector); } } findRemoteElement() { const locators = this.getLocatorsChain(); const remoteApplication = AutomationEnvironment.getWorkingRemoteApplication(); return new ElementFinderRemote(remoteApplication, locators); } } export class ElementArrayFinder { constructor(locator, parent = null) { this.locator = locator; this.parent = parent; } getLocator() { return this.locator; } getLocatorsChain() { let locators = []; if (this.parent) { locators = this.parent.getLocatorsChain(); } locators.push(this.locator); return locators; } get(index) { return new ElementFinder({ type: LocatorType.ArrayItem, index }, this); } async count() { if (AutomationEnvironment.isLocalMode()) { return (await this.findElements()).length; } else { return this.findRemoteElement().count(); } } async findElements() { if (this.parent) { return (await (await this.parent.findElement()).$$(this.locator.selector)); } else { return AutomationEnvironment.getWorkingBrowser().$$(this.locator.selector); } } findRemoteElement() { const locators = this.getLocatorsChain(); const remoteApplication = AutomationEnvironment.getWorkingRemoteApplication(); return new ElementFinderRemote(remoteApplication, locators); } } export class ElementFinderBuilder { static build(locators) { if (locators.length === 0) { return null; } const parent = ElementFinderBuilder.build(locators.slice(0, locators.length - 1)); const lastLocator = locators[locators.length - 1]; if (lastLocator.type === LocatorType.ElementSelector || lastLocator.type === LocatorType.ArrayItem) { return new ElementFinder(lastLocator, parent); } else if (lastLocator.type === LocatorType.ArraySelector) { return new ElementArrayFinder(lastLocator, parent); } else { throw 'Unsupported locator type: ' + lastLocator.type; } } }