systelab-components-wdio-test
Version:
Widgets to be use in the E2E Tests based in WDIO
522 lines (518 loc) • 19.2 kB
JavaScript
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;
this.DEFAULT_LONG_PRESS_DURATION = 2000;
}
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) {
return (await this.findElement()).getHTML({ includeSelectorTag: 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: 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 rightClick() {
if (AutomationEnvironment.isLocalMode()) {
const element = await this.findElement();
await AutomationEnvironment.getWorkingBrowser().execute((element) => {
const event = new MouseEvent('contextmenu', {
bubbles: true,
cancelable: true,
view: window,
button: 2,
buttons: 2,
clientX: element.getBoundingClientRect().left + element.offsetWidth / 2,
clientY: element.getBoundingClientRect().top + element.offsetHeight / 2,
});
element.dispatchEvent(event);
}, element);
}
else {
return this.findRemoteElement().rightClick();
}
}
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 longPress(duration = this.DEFAULT_LONG_PRESS_DURATION) {
if (AutomationEnvironment.isLocalMode()) {
const element = await this.findElement();
if (AutomationEnvironment.isLocalMode()) {
const element = await this.findElement();
if (AutomationEnvironment.getBrowserType() === BrowserType.Chrome) {
await AutomationEnvironment.getWorkingBrowser().action('pointer', { parameters: { pointerType: 'touch' } })
.move({ origin: element, x: 0, y: 0 })
.down({ button: 0 })
.pause(duration)
.up({ button: 0 })
.perform();
}
else {
await this.rightClick();
}
}
else {
return this.findRemoteElement().longPress(duration);
}
}
}
async scrollToElement(scrollOptions = { behavior: 'auto', block: 'center', inline: 'nearest' }) {
if (AutomationEnvironment.isLocalMode()) {
const element = await this.findElement();
return AutomationEnvironment.getWorkingBrowser().execute((el, options) => el.scrollIntoView(options), element, scrollOptions);
}
else {
return this.findRemoteElement().scrollToElement(scrollOptions);
}
}
async uploadFile(name, content) {
if (AutomationEnvironment.isLocalMode()) {
const element = await this.findElement();
await AutomationEnvironment.getWorkingBrowser().execute((element, name, content) => {
const file = new File([content], name, { type: 'application/octet-stream' });
const dt = new DataTransfer();
dt.items.add(file);
element.files = dt.files;
element.dispatchEvent(new Event('change', { bubbles: true }));
}, element, name, content);
}
else {
return this.findRemoteElement().uploadFile(name, content);
}
}
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 this.parent.findElement()).$(this.locator.selector).getElement();
}
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).getElement();
}
}
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 this.parent.findElement()).$$(this.locator.selector).getElements();
}
else {
return AutomationEnvironment.getWorkingBrowser().$$(this.locator.selector).getElements();
}
}
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;
}
}
}