UNPKG

@umbraco/playwright-testhelpers

Version:

Test helpers for making playwright tests for Umbraco solutions

548 lines 22.9 kB
"use strict"; 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