@umbraco/playwright-testhelpers
Version:
Test helpers for making playwright tests for Umbraco solutions
548 lines • 22.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BasePage = void 0;
const test_1 = require("@playwright/test");
const ConstantHelper_1 = require("./ConstantHelper");
/**
* Base page class providing common UI interaction methods.
* All methods follow best practices for reliability:
* - click: Always checks element visibility before clicking
* - enterText: Always clears before filling text
* - select: Waits for element visibility before selecting
*
* @example
* ```typescript
* class MyPage extends BasePage {
* readonly submitBtn: Locator;
*
* constructor(page: Page) {
* super(page);
* this.submitBtn = page.getByRole('button', {name: 'Submit'});
* }
*
* async submit() {
* await this.click(this.submitBtn);
* }
* }
* ```
*/
class BasePage {
page;
constructor(page) {
this.page = page;
}
/**
* Clicks an element after verifying it is visible.
* @param locator - The element to click
* @param options - Optional click configuration
*/
async click(locator, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.long });
await locator.click({ force: options?.force });
}
/**
* Double-clicks an element after verifying it is visible.
* @param locator - The element to double-click
* @param options - Optional configuration
*/
async doubleClick(locator, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await locator.dblclick({ force: options?.force });
}
/**
* Right-clicks an element after verifying it is visible.
* @param locator - The element to right-click
* @param options - Optional configuration
*/
async rightClick(locator, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await locator.click({ button: 'right', force: options?.force });
}
/**
* Clicks an element using JavaScript (bypasses actionability checks).
* Use when standard click doesn't work due to overlapping elements.
* @param locator - The element to click
*/
async javascriptClick(locator) {
await locator.evaluate((el) => el.click());
}
/**
* Enters text into an input field after clearing it.
* Verifies element visibility before interaction.
* @param locator - The input element
* @param text - The text to enter
* @param options - Optional configuration
*/
async enterText(locator, text, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
if (options?.clearFirst !== false) {
await locator.clear();
}
await locator.fill(text);
if (options?.verify) {
await (0, test_1.expect)(locator).toHaveValue(text);
}
}
/**
* Types text character by character (simulates real typing).
* Useful when fill() doesn't trigger necessary events.
* @param locator - The input element
* @param text - The text to type
* @param options - Optional configuration
*/
async typeText(locator, text, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
if (options?.clearFirst !== false) {
await locator.clear();
}
await locator.pressSequentially(text, { delay: options?.delay ?? 50 });
if (options?.verify) {
await (0, test_1.expect)(locator).toHaveValue(text);
}
}
/**
* Clears an input field.
* @param locator - The input element to clear
* @param options - Optional configuration
*/
async clearText(locator, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await locator.clear();
}
/**
* Presses a keyboard key while focused on an element.
* @param locator - The element to focus
* @param key - The key to press (e.g., 'Enter', 'Tab', 'Escape')
*/
async pressKey(locator, key, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await locator.press(key);
}
/**
* Selects an option from a dropdown by value.
* @param locator - The select element
* @param value - The option value to select
*/
async selectByValue(locator, value, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await locator.selectOption({ value });
}
/**
* Selects an option from a dropdown by visible text.
* @param locator - The select element
* @param text - The option text to select
*/
async selectByText(locator, text, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await locator.selectOption({ label: text });
}
/**
* Selects an option from a dropdown by index.
* @param locator - The select element
* @param index - The option index to select (0-based)
*/
async selectByIndex(locator, index, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await locator.selectOption({ index });
}
/**
* Selects multiple options from a multi-select dropdown.
* @param locator - The select element
* @param values - Array of option values to select
*/
async selectMultiple(locator, values, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await locator.selectOption(values);
}
/**
* Checks a checkbox if it's not already checked.
* @param locator - The checkbox element
*/
async check(locator, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await locator.check({ force: options?.force });
}
/**
* Unchecks a checkbox if it's currently checked.
* @param locator - The checkbox element
*/
async uncheck(locator, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await locator.uncheck({ force: options?.force });
}
/**
* Sets a checkbox to a specific state.
* @param locator - The checkbox element
* @param checked - Whether the checkbox should be checked
*/
async setChecked(locator, checked, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await locator.setChecked(checked, { force: options?.force });
}
/**
* Hovers over an element.
* @param locator - The element to hover over
*/
async hover(locator, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await locator.hover({ force: options?.force });
}
/**
* Focuses on an element.
* @param locator - The element to focus
*/
async focus(locator, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await locator.focus();
}
/**
* Hovers over one element and clicks another (for menus that appear on hover).
* @param hoverLocator - The element to hover over
* @param clickLocator - The element to click after hover
*/
async hoverAndClick(hoverLocator, clickLocator, options) {
await (0, test_1.expect)(hoverLocator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await hoverLocator.hover();
await (0, test_1.expect)(clickLocator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await clickLocator.click({ force: options?.force });
}
/**
* Waits for an element to be visible.
* @param locator - The element to wait for
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForVisible(locator, timeout) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Waits for an element to be hidden.
* @param locator - The element to wait for
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForHidden(locator, timeout) {
await (0, test_1.expect)(locator).toBeHidden({ timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Waits for an element to be attached to the DOM.
* @param locator - The element to wait for
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForAttached(locator, timeout) {
await locator.waitFor({ state: 'attached', timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Waits for an element to be detached from the DOM.
* @param locator - The element to wait for
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForDetached(locator, timeout) {
await locator.waitFor({ state: 'detached', timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Waits for the page to finish loading (network idle).
*/
async waitForPageLoad() {
await this.page.waitForLoadState('networkidle');
}
/**
* Waits for the DOM to be fully loaded.
*/
async waitForDOMContentLoaded() {
await this.page.waitForLoadState('domcontentloaded');
}
/**
* Waits for all network requests to complete.
*/
async waitForLoadState() {
await this.page.waitForLoadState();
}
/**
* Waits for an element to be enabled.
* @param locator - The element to wait for
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForEnabled(locator, timeout) {
await (0, test_1.expect)(locator).toBeEnabled({ timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Waits for an element to be disabled.
* @param locator - The element to wait for
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForDisabled(locator, timeout) {
await (0, test_1.expect)(locator).toBeDisabled({ timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Waits for an element to contain specific text.
* @param locator - The element to wait for
* @param text - The text to wait for
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForText(locator, text, timeout) {
await (0, test_1.expect)(locator).toContainText(text, { timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Waits for an input to have a specific value.
* @param locator - The input element to wait for
* @param value - The value to wait for
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForValue(locator, value, timeout) {
await (0, test_1.expect)(locator).toHaveValue(value, { timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Waits for an element to have a specific attribute value.
* @param locator - The element to wait for
* @param name - The attribute name
* @param value - The expected attribute value
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForAttribute(locator, name, value, timeout) {
await (0, test_1.expect)(locator).toHaveAttribute(name, value, { timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Waits for an element to have a specific CSS class.
* @param locator - The element to wait for
* @param className - The CSS class to wait for
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForClass(locator, className, timeout) {
await (0, test_1.expect)(locator).toHaveClass(className, { timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Waits for an element to be editable.
* @param locator - The element to wait for
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForEditable(locator, timeout) {
await (0, test_1.expect)(locator).toBeEditable({ timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Waits for an element to be checked.
* @param locator - The checkbox/radio element to wait for
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForChecked(locator, timeout) {
await (0, test_1.expect)(locator).toBeChecked({ timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Waits for an element to be unchecked.
* @param locator - The checkbox/radio element to wait for
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForUnchecked(locator, timeout) {
await (0, test_1.expect)(locator).not.toBeChecked({ timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Waits for a specific URL or URL pattern.
* @param url - The URL string or regex pattern to wait for
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForURL(url, timeout) {
await this.page.waitForURL(url, { timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.navigation });
}
/**
* Waits for a navigation to complete.
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForNavigation(timeout) {
await this.page.waitForLoadState('load', { timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.navigation });
}
/**
* Waits for a specific time (use sparingly, prefer explicit waits).
* @param milliseconds - Time to wait in milliseconds
*/
async waitForTimeout(milliseconds) {
await this.page.waitForTimeout(milliseconds);
}
/**
* Waits for a network request to a specific URL.
* @param urlOrPredicate - URL string, regex, or predicate function
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForRequest(urlOrPredicate, timeout) {
return await this.page.waitForRequest(urlOrPredicate, { timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.navigation });
}
/**
* Waits for a network response from a specific URL.
* @param urlOrPredicate - URL string, regex, or predicate function
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForResponse(urlOrPredicate, timeout) {
return await this.page.waitForResponse(urlOrPredicate, { timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.navigation });
}
/**
* Waits for an element to be focused.
* @param locator - The element to wait for
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForFocused(locator, timeout) {
await (0, test_1.expect)(locator).toBeFocused({ timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Waits for an element to be empty (no text content).
* @param locator - The element to wait for
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForEmpty(locator, timeout) {
await (0, test_1.expect)(locator).toBeEmpty({ timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Waits for a function to return true.
* @param predicate - Function that returns a boolean or Promise<boolean>
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForFunction(predicate, timeout) {
await this.page.waitForFunction(predicate, { timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.navigation });
}
/**
* Waits for an element to have a specific CSS property value.
* @param locator - The element to wait for
* @param property - The CSS property name
* @param value - The expected CSS property value
* @param timeout - Maximum time to wait in milliseconds
*/
async waitForCSS(locator, property, value, timeout) {
await (0, test_1.expect)(locator).toHaveCSS(property, value, { timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Asserts that an element is visible.
* @param locator - The element to check
* @param isVisible - Whether the element should be visible (default: true)
*/
async isVisible(locator, isVisible = true, timeout) {
await (0, test_1.expect)(locator).toBeVisible({ visible: isVisible, timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Asserts that an element is enabled.
* @param locator - The element to check
*/
async isEnabled(locator, timeout) {
await (0, test_1.expect)(locator).toBeEnabled({ timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Asserts that an element is disabled.
* @param locator - The element to check
*/
async isDisabled(locator, timeout) {
await (0, test_1.expect)(locator).toBeDisabled({ timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Asserts that an element contains specific text.
* @param locator - The element to check
* @param text - The text to look for
*/
async containsText(locator, text, timeout) {
await (0, test_1.expect)(locator).toContainText(text, { timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Asserts that an element has specific text.
* @param locator - The element to check
* @param text - The exact text expected
*/
async hasText(locator, text, timeout) {
await (0, test_1.expect)(locator).toHaveText(text, { timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Asserts that an input has a specific value.
* @param locator - The input element to check
* @param value - The expected value
*/
async hasValue(locator, value, timeout) {
await (0, test_1.expect)(locator).toHaveValue(value, { timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Asserts that an element has a specific attribute value.
* @param locator - The element to check
* @param name - The attribute name
* @param value - The expected attribute value
*/
async hasAttribute(locator, name, value, timeout) {
await (0, test_1.expect)(locator).toHaveAttribute(name, value, { timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Asserts that a specific number of elements exist.
* @param locator - The locator to count
* @param count - The expected count
*/
async hasCount(locator, count, timeout) {
await (0, test_1.expect)(locator).toHaveCount(count, { timeout: timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
}
/**
* Gets the text content of an element.
* @param locator - The element to get text from
* @returns The text content
*/
async getText(locator, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
return await locator.textContent() ?? '';
}
/**
* Gets the value of an input element.
* @param locator - The input element
* @returns The input value
*/
async getValue(locator, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
return await locator.inputValue();
}
/**
* Gets an attribute value from an element.
* @param locator - The element
* @param attributeName - The attribute name
* @returns The attribute value or null
*/
async getAttribute(locator, attributeName, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
return await locator.getAttribute(attributeName);
}
/**
* Checks if an element is currently visible.
* @param locator - The element to check
* @returns True if visible, false otherwise
*/
async checkIsVisible(locator) {
return await locator.isVisible();
}
/**
* Checks if a checkbox is checked.
* @param locator - The checkbox element
* @returns True if checked, false otherwise
*/
async isChecked(locator) {
return await locator.isChecked();
}
/**
* Scrolls an element into view.
* @param locator - The element to scroll to
*/
async scrollIntoView(locator, options) {
await (0, test_1.expect)(locator).toBeVisible({ timeout: options?.timeout ?? ConstantHelper_1.ConstantHelper.timeout.medium });
await locator.scrollIntoViewIfNeeded();
}
/**
* Sets files on a file input element.
* @param locator - The file input element
* @param filePath - Path to the file(s) to set
*/
async setInputFiles(locator, filePath) {
await locator.setInputFiles(filePath);
}
/**
* Clears files from a file input.
* @param locator - The file input element
*/
async clearInputFiles(locator) {
await locator.setInputFiles([]);
}
/**
* Drags an element and drops it on another element.
* @param source - The element to drag
* @param target - The element to drop on
*/
async dragTo(source, target, options) {
await source.dragTo(target, options);
}
}
exports.BasePage = BasePage;
//# sourceMappingURL=BasePage.js.map