@o3r/testing
Version:
The module provides testing (e2e, unit test) utilities to help you build your own E2E pipeline integrating visual testing.
176 lines • 7.97 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.O3rComponentFixture = void 0;
const index_1 = require("../../errors/index");
const helpers_1 = require("../helpers");
const element_1 = require("./element");
/**
* Implementation of the fixture dedicated to Playwright, hence using the webdriver to interact with the dom.
*/
class O3rComponentFixture {
/**
* Root element of this fixture.
* All further queries will be applied to the element tree if any, otherwise they will be applied to the whole DOM.
* @param rootElement
*/
constructor(rootElement) {
this.rootElement = rootElement;
}
/**
* Throws an exception if the element is undefined.
* Otherwise returns the element.
* @param element ElementProfile to test
* @param timeout specific timeout that will throw when reach
*/
async throwOnUndefinedElement(element, timeout) {
if (!element) {
throw new Error('Element not found in ' + this.constructor.name);
}
await element.sourceElement.element.first().waitFor({ state: 'attached', timeout });
return element;
}
/**
* Throws an exception if the element is undefined.
* Otherwise returns the element.
* @param element ElementProfile to test
* @param timeout specific timeout that will throw when reach
*/
throwOnUndefined(element, timeout) {
return (0, helpers_1.withTimeout)((async () => {
const el = await element;
await el.sourceElement.element.first().waitFor({ state: 'attached' });
return el;
})(), timeout);
}
/**
* Get the element associated to the selector if present
* @param selector Selector to access the element
* @param elementConstructor Constructor that will be used to create the Element, defaults to O3rElement
* @param options Options supported
* @param options.index index Select the element associated to the index
* @param options.shouldThrowIfNotPresent If set to true the function will throw if the element is not present
* @param options.timeout Duration to wait for the element to be present before it throws
*/
async queryWithOptions(selector, elementConstructor, options = {}) {
const element = await (options.index === undefined ? this.query(selector, elementConstructor) : this.queryNth(selector, options.index, elementConstructor));
if (options.shouldThrowIfNotPresent) {
return this.throwOnUndefinedElement(element, options.timeout);
}
return element;
}
/**
* Get text from the element associated to the given selector, or undefined if the element is not found or not visible
* @param selector Selector to access the element
* @param options Options supported
* @param options.elementConstructor Constructor that will be used to create the Element, defaults to O3rElement
* @param options.index index Select the element associated to the index
* @param options.shouldThrowIfNotPresent If set to true the function will throw if the element is not present
* @param options.timeout Duration to wait for the element
*/
async getText(selector, options = {}) {
const element = await this.queryWithOptions(selector, options.elementConstructor, options);
return await element.getText();
}
/**
* Check if the element associated to the given selector is visible
* @param selector Selector to access the element
* @param options Options supported
* @param options.elementConstructor Constructor that will be used to create the Element, defaults to O3rElement
* @param options.index index Select the element associated to the index
* @param options.shouldThrowIfNotPresent If set to true the function will throw if the element is not present
* @param options.timeout Duration to wait for the element
*/
async isVisible(selector, options = {}) {
const element = await this.queryWithOptions(selector, options.elementConstructor, options);
if (options.timeout) {
try {
await element.sourceElement.element.waitFor({
state: 'visible',
timeout: options.timeout
});
return true;
}
catch {
return false;
}
}
return element.isVisible();
}
/**
* Click on the element associated to the given selector if it exists and is visible
* @param selector Selector to access the element
* @param options Options supported
* @param options.elementConstructor Constructor that will be used to create the Element, defaults to O3rElement
* @param options.index index Select the element associated to the index
* @param options.shouldThrowIfNotPresent If set to true the function will throw if the element is not present
* @param options.timeout Duration to wait for the element to be present before it throws
*/
async click(selector, options = {}) {
const element = await this.queryWithOptions(selector, options.elementConstructor, options);
await element.click();
}
query(selector, returnType) {
const elements = this.rootElement.sourceElement.element.locator(selector);
const element = elements.first();
const selectedElement = {
element: element,
page: this.rootElement.sourceElement.page
};
return Promise.resolve(new (returnType || element_1.O3rElement)(selectedElement));
}
queryNth(selector, index, returnType) {
const elements = this.rootElement.sourceElement.element.locator(selector);
const element = elements.nth(index);
const selectedElement = {
element: element,
page: this.rootElement.sourceElement.page
};
return Promise.resolve(new (returnType || element_1.O3rElement)(selectedElement));
}
async queryAll(selector, returnType, groupType, timeout = 5000) {
try {
const sourceElement = this.rootElement.sourceElement.element;
const pElements = sourceElement.locator(selector);
// Mandatory because count is not reliable if we don't wait for the list to be attached
await pElements.first().waitFor({ state: 'attached', timeout });
const pElementsCount = await pElements.count();
const elements = [];
for (let i = 0; i < pElementsCount; i++) {
const selectedElement = {
element: pElements.nth(i),
page: this.rootElement.sourceElement.page
};
elements.push(returnType ? new returnType(selectedElement) : new element_1.O3rElement(selectedElement));
}
if (groupType) {
const group = new groupType(elements);
const isValid = await group.isValidGroup();
if (!isValid) {
throw new index_1.FixtureUsageError('invalid group of items');
}
return group;
}
return elements;
}
catch (err) {
// eslint-disable-next-line no-console -- no other logger available
console.warn(`Failed to query all ${selector}`, err);
return Promise.resolve([]);
}
}
/** @inheritdoc */
getElement() {
return this.rootElement;
}
/** @inheritdoc */
getSubComponents() {
return Promise.resolve({ block: [this] });
}
/** @inheritDoc */
queryNotPresent(selector) {
const element = this.rootElement.sourceElement.element.locator(selector).first();
return element.isHidden();
}
}
exports.O3rComponentFixture = O3rComponentFixture;
//# sourceMappingURL=component-fixture.js.map