UNPKG

e2ed

Version:

E2E testing framework over Playwright

234 lines (233 loc) 9.22 kB
"use strict"; /* eslint-disable max-lines, @typescript-eslint/naming-convention, @typescript-eslint/no-non-null-assertion */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Selector = void 0; const node_util_1 = require("node:util"); const internal_1 = require("../../constants/internal"); const frameContext_1 = require("../../context/frameContext"); const createLocator_1 = require("../../createLocator"); const useContext_1 = require("../../useContext"); const getAttributeCssSelector_1 = require("./getAttributeCssSelector"); const setRetryData = (promise, retryData) => { // eslint-disable-next-line no-param-reassign promise[internal_1.RETRY_KEY] = retryData; }; function toJSON() { return JSON.stringify(this); } /** * Selector. */ class Selector { description; args; cssString; kind; locator; parameterAttributePrefix; parentSelector; testIdAttribute; testIdSeparator; constructor({ args, cssString, kind = 'css', parameterAttributePrefix, parentSelector, testIdAttribute, testIdSeparator, }) { this.args = args; this.cssString = cssString; this.description = kind === 'css' ? cssString : `${parentSelector.description}.${kind}(${args?.join(', ')})`; this.kind = kind; this.locator = (0, createLocator_1.createTestLocator)({ attributesOptions: { parameterAttributePrefix, testIdAttribute, testIdSeparator }, createLocatorByCssSelector: (selector) => selector, supportWildcardsInCssSelectors: true, }).locator; this.parameterAttributePrefix = parameterAttributePrefix; this.parentSelector = parentSelector; this.testIdAttribute = testIdAttribute; this.testIdSeparator = testIdSeparator; } get boundingClientRect() { const result = this.getPlaywrightLocator() .boundingBox() .then((box) => { const { height, width, x, y } = box ?? { height: 0, width: 0, x: 0, y: 0 }; const bottom = height + y; const right = width + x; return { bottom, height, left: x, right, toJSON, top: y, width, x, y }; }); setRetryData(result, { property: 'boundingClientRect', selector: this }); return result; } get checked() { const result = this.getPlaywrightLocator() .isChecked() .catch(() => null); setRetryData(result, { property: 'checked', selector: this }); return result; } get count() { const result = this.getPlaywrightLocator().count(); setRetryData(result, { property: 'count', selector: this }); return result; } get exists() { const result = this.getPlaywrightLocator() .count() .then((count) => count > 0); setRetryData(result, { property: 'exists', selector: this }); return result; } get scrollHeight() { const result = this.getPlaywrightLocator().evaluate((element) => element.scrollHeight); setRetryData(result, { property: 'scrollHeight', selector: this }); return result; } get scrollLeft() { const result = this.getPlaywrightLocator().evaluate((element) => element.scrollLeft); setRetryData(result, { property: 'scrollLeft', selector: this }); return result; } get scrollTop() { const result = this.getPlaywrightLocator().evaluate((element) => element.scrollTop); setRetryData(result, { property: 'scrollTop', selector: this }); return result; } get scrollWidth() { const result = this.getPlaywrightLocator().evaluate((element) => element.scrollWidth); setRetryData(result, { property: 'scrollWidth', selector: this }); return result; } get textContent() { const result = this.getPlaywrightLocator() .textContent() .then((content) => content ?? ''); setRetryData(result, { property: 'textContent', selector: this }); return result; } get value() { const result = this.getPlaywrightLocator() .inputValue() .catch(() => null); setRetryData(result, { property: 'value', selector: this }); return result; } get visible() { const result = this.getPlaywrightLocator().isVisible(); setRetryData(result, { property: 'visible', selector: this }); return result; } static create({ cssString, parameterAttributePrefix, testIdAttribute, testIdSeparator, }) { return new Selector({ cssString, parameterAttributePrefix, testIdAttribute, testIdSeparator }); } createSelector(cssString) { const { parameterAttributePrefix, testIdAttribute, testIdSeparator } = this; return new Selector({ cssString, parameterAttributePrefix, testIdAttribute, testIdSeparator }); } filter(cssSelectorString) { return this.createChildSelector('filter', [cssSelectorString]); } filterByLocatorParameter(parameter, value) { return this.filter((0, getAttributeCssSelector_1.getAttributeCssSelector)(this.getParameterAttribute(parameter), value)); } filterByTestId(...args) { return this.filter(this.locator(...args)); } find(cssSelectorString) { return this.createChildSelector('find', [cssSelectorString]); } findByLocatorParameter(parameter, value) { return this.find((0, getAttributeCssSelector_1.getAttributeCssSelector)(this.getParameterAttribute(parameter), value)); } findByTestId(...args) { return this.find(this.locator(...args)); } getAttribute(attributeName) { const result = this.getPlaywrightLocator().getAttribute(attributeName); setRetryData(result, { args: [attributeName], property: 'getAttribute', selector: this }); return result; } getLocatorParameter(parameter) { return this.getAttribute(this.getParameterAttribute(parameter)); } getPlaywrightLocator() { const args = this.args; const selector = this.parentSelector; switch (this.kind) { case 'css': return ((0, frameContext_1.getFrameContext)() ?? (0, useContext_1.getPlaywrightPage)()).locator(this.cssString); case 'filter': return selector.getPlaywrightLocator().and((0, useContext_1.getPlaywrightPage)().locator(String(args[0]))); case 'find': return selector .getPlaywrightLocator() .locator((0, useContext_1.getPlaywrightPage)().locator(String(args[0]))); case 'nth': return args[0] === -1 ? selector.getPlaywrightLocator().last() : selector.getPlaywrightLocator().nth(Number(args[0])); case 'parent': return selector.getPlaywrightLocator().locator('xpath=..'); case 'withText': return selector.getPlaywrightLocator().filter({ hasText: args[0] }); // no default } } getStyleProperty(propertyName) { const result = this.getPlaywrightLocator().evaluate((element, property) => getComputedStyle(element).getPropertyValue(property), propertyName); setRetryData(result, { args: [propertyName], property: 'getStyleProperty', selector: this }); return result; } getTestId() { return this.getAttribute(this.testIdAttribute); } hasAttribute(attributeName) { const result = this.getPlaywrightLocator() .getAttribute(attributeName) .then((attribute) => typeof attribute === 'string'); setRetryData(result, { args: [attributeName], property: 'hasAttribute', selector: this }); return result; } hasLocatorParameter(parameter) { return this.hasAttribute(this.getParameterAttribute(parameter)); } hasTestId() { return this.hasAttribute(this.testIdAttribute); } nth(index) { return this.createChildSelector('nth', [index]); } parent() { return this.createChildSelector('parent'); } toJSON() { return { description: this.description }; } /** * Custom string presentation of selector. */ toString() { return `Selector for ${this.description}`; } withText(textOrRegExp) { return this.createChildSelector('withText', [textOrRegExp]); } createChildSelector(kind, args) { const { cssString, parameterAttributePrefix, testIdAttribute, testIdSeparator } = this; return new Selector({ args, cssString, kind, parameterAttributePrefix, parentSelector: this, testIdAttribute, testIdSeparator, }); } getParameterAttribute(parameter) { return this.parameterAttributePrefix + parameter; } } exports.Selector = Selector; /** * Custom presentation of selector for `nodejs` `inspect`. */ // eslint-disable-next-line @typescript-eslint/unbound-method Selector.prototype[node_util_1.inspect.custom] = Selector.prototype.toString;