UNPKG

playwright-cucumber-ts-steps

Version:

A collection of reusable Playwright step definitions for Cucumber in TypeScript, designed to streamline end-to-end testing across web, API, and mobile applications.

430 lines (406 loc) 12 kB
// e2e/step_definitions/common/actions/clickSteps.ts import { When, DataTable } from "@cucumber/cucumber"; import { parseClickOptions } from "../helpers/utils/optionsUtils"; import { CustomWorld } from "../helpers/world"; /** * Clicks on the previously stored element. * * ```gherkin * When I click * ``` * * @example * ```gherkin * When I click * ``` * @remarks * Requires a previous step that stores an element. * @category Click Steps */ export async function When_I_click(this: CustomWorld, ...rest: any[]) { const maybeTable = rest[0]; const options = maybeTable?.rowsHash ? parseClickOptions(maybeTable) : {}; if (!this.element) throw new Error("❌ No stored element to click."); await this.element.click(options); this.log?.("🖱️ Clicked on stored element"); } When("I click", When_I_click); /** * Clicks on an element matching the given selector. * * ```gherkin * When I click on element {string} * ``` * * @example * ```gherkin * When I click on element ".my-class" * ``` * @remarks * Stores the clicked element for later use. * @category Click Steps */ export async function When_I_click_on_element(this: CustomWorld, selector: string, ...rest: any[]) { const maybeTable = rest[0]; const options = maybeTable?.rowsHash ? parseClickOptions(maybeTable) : {}; const element = this.getLocator(selector); await element.click(options); this.element = element; this.log?.(`🖱️ Clicked on element "${selector}"`); } When("I click on element {string}", When_I_click_on_element); /** * Clicks on a button with the given label. * * ```gherkin * When I click on button {string} * ``` * * @example * ```gherkin * When I click on button "Submit" * ``` * @remarks * Stores the clicked button for later use. * @category Click Steps */ export async function When_I_click_on_button(this: CustomWorld, label: string, ...rest: any[]) { const maybeTable = rest[0]; const options = maybeTable?.rowsHash ? parseClickOptions(maybeTable) : {}; const button = await this.page.getByRole("button", { name: label }); await button.click(options); this.element = button; this.log?.(`🖱️ Clicked on button "${label}"`); } When("I click on button {string}", When_I_click_on_button); /** * Clicks on a link with the given text. * * ```gherkin * When I click on link {string} * ``` * * @example * ```gherkin * When I click on link "Home" * ``` * @remarks * Stores the clicked link for later use. * @category Click Steps */ export async function When_I_click_on_link(this: CustomWorld, text: string, ...rest: any[]) { const maybeTable = rest[0]; const options = maybeTable?.rowsHash ? parseClickOptions(maybeTable) : {}; const link = await this.page.getByRole("link", { name: text }); await link.click(options); this.element = link; this.log?.(`✅ Clicked on link "${text}"`); } When("I click on link {string}", When_I_click_on_link); /** * Clicks on a label with the given text. * * ```gherkin * When I click on label {string} * ``` * * @example * ```gherkin * When I click on label "Username" * ``` * @remarks * Stores the clicked label for later use. * @category Click Steps */ export async function When_I_click_on_label(this: CustomWorld, labelText: string, ...rest: any[]) { const maybeTable = rest[0]; const options = maybeTable?.rowsHash ? parseClickOptions(maybeTable) : {}; const label = await this.page.getByLabel(labelText); await label.click(options); this.element = label; this.log?.(`🏷️ Clicked on label "${labelText}"`); } When("I click on label {string}", When_I_click_on_label); /** * Clicks on an element containing the given text (not exact match). Supports aliasing with @alias. * * ```gherkin * When I click on text {string} * ``` * * @example * ```gherkin * When I click on text "Welcome" * When I click on text "@username" * ``` * @remarks * Stores the clicked element for later use. * @category Click Steps */ export async function When_I_click_on_text(this: CustomWorld, rawText: string, ...rest: any[]) { const maybeTable = rest[0]; const options = maybeTable?.rowsHash ? parseClickOptions(maybeTable) : {}; let text = rawText; if (rawText.startsWith("@")) { const alias = rawText.slice(1); text = this.data[alias]; if (!text) throw new Error(`❌ No value found for alias "@${alias}"`); } const locator = this.page.getByText(text, { exact: false }); await locator.first().waitFor({ state: "visible", timeout: 5000 }); await locator.first().click(options); this.element = locator.first(); this.log?.(`🖱️ Clicked on text "${text}"`); } When("I click on text {string}", When_I_click_on_text); /** * Clicks on an element containing the exact given text. * * ```gherkin * When I click on exact text {string} * ``` * * @example * ```gherkin * When I click on exact text "Log out" * ``` * @remarks * Stores the clicked element for later use. * @category Click Steps */ export async function When_I_click_on_exact_text( this: CustomWorld, exactText: string, ...rest: any[] ) { const maybeTable = rest[0]; const options = maybeTable?.rowsHash ? parseClickOptions(maybeTable) : {}; const locator = this.page.getByText(exactText, { exact: true }); await locator.waitFor({ state: "visible", timeout: 5000 }); await locator.click(options); this.element = locator; this.log?.(`🖱️ Clicked on exact text "${exactText}"`); } When("I click on exact text {string}", When_I_click_on_exact_text); /** * Clicks all previously stored elements. * * ```gherkin * When I click all * ``` * * @example * ```gherkin * When I click all * ``` * @remarks * Requires a previous step that stores elements. * @category Click Steps */ export async function When_I_click_all(this: CustomWorld, ...rest: any[]) { const maybeTable = rest[0]; const options = maybeTable?.rowsHash ? parseClickOptions(maybeTable) : {}; if (!this.elements) throw new Error("❌ No stored elements to click."); const count = await this.elements.count(); if (count === 0) throw new Error("⚠️ No elements found to click."); for (let i = 0; i < count; i++) { const el = this.elements.nth(i); await el.waitFor({ state: "visible", timeout: 5000 }); await el.click(options); this.log?.(`🖱️ Clicked element #${i + 1}`); } this.log?.(`✅ Clicked all ${count} elements.`); } When("I click all", When_I_click_all); /** * Double-clicks on an element containing the given text. * * ```gherkin * When I double click on text {string} * ``` * * @example * ```gherkin * When I double click on text "Edit" * ``` * @remarks * Uses the previously stored element if available. * @category Click Steps */ export async function When_I_double_click_on_text(this: CustomWorld, text: string, ...rest: any[]) { const maybeTable = rest[0]; const options = maybeTable?.rowsHash ? parseClickOptions(maybeTable) : {}; const element = this.element || this.page.getByText(text); await element.dblclick(options); this.log?.(`🖱️ Double-clicked on text "${text}"`); } When("I double click on text {string}", When_I_double_click_on_text); /** * Double-clicks at the given page coordinates. * * ```gherkin * When I double click position {int} {int} * ``` * * @example * ```gherkin * When I double click position 100 200 * ``` * @category Click Steps */ export async function When_I_double_click_position( this: CustomWorld, x: number, y: number, ...rest: any[] ) { const maybeTable = rest[0]; const options = maybeTable?.rowsHash ? parseClickOptions(maybeTable) : {}; await this.page.mouse.dblclick(x, y, options); this.log?.(`🖱️ Double-clicked at (${x}, ${y})`); } When("I double click position {int} {int}", When_I_double_click_position); /** * Double-clicks on the previously stored element. * * ```gherkin * When I double click * ``` * * @example * ```gherkin * When I double click * ``` * @remarks * Requires a previous step that stores an element. * @category Click Steps */ export async function When_I_double_click(this: CustomWorld, ...rest: any[]) { const maybeTable = rest[0]; const options = maybeTable?.rowsHash ? parseClickOptions(maybeTable) : {}; if (!this.element) throw new Error("❌ No stored element to double-click."); await this.element.dblclick(options); this.log?.("🖱️ Double-clicked on stored element"); } When("I double click", When_I_double_click); /** * Right-clicks on the previously stored element. * * ```gherkin * When I right click * ``` * * @example * ```gherkin * When I right click * ``` * @remarks * Requires a previous step that stores an element. * @category Click Steps */ export async function When_I_right_click(this: CustomWorld, ...rest: any[]) { const maybeTable = rest[0]; const options = maybeTable?.rowsHash ? parseClickOptions(maybeTable) : {}; if (!this.element) throw new Error("❌ No stored element to right-click."); await this.element.click({ button: "right", ...options }); this.log?.("🖱️ Right-clicked on stored element"); } When("I right click", When_I_right_click); /** * Right-clicks on an element containing the given text. * * ```gherkin * When I right click on text {string} * ``` * * @example * ```gherkin * When I right click on text "Options" * ``` * @category Click Steps */ export async function When_I_right_click_on_text(this: CustomWorld, text: string, ...rest: any[]) { const maybeTable = rest[0]; const options = maybeTable?.rowsHash ? parseClickOptions(maybeTable) : {}; const element = this.page.getByText(text); await element.click({ button: "right", ...options }); this.log?.(`🖱️ Right-clicked on text "${text}"`); } When("I right click on text {string}", When_I_right_click_on_text); /** * Right-clicks at the given page coordinates. * * ```gherkin * When I right click position {int} {int} * ``` * * @example * ```gherkin * When I right click position 50 50 * ``` * @category Click Steps */ export async function When_I_right_click_position( this: CustomWorld, x: number, y: number, ...rest: any[] ) { const maybeTable = rest[0]; const options = maybeTable?.rowsHash ? parseClickOptions(maybeTable) : {}; await this.page.mouse.click(x, y, { button: "right", ...options }); this.log?.(`🖱️ Right-clicked at (${x}, ${y})`); } When("I right click position {int} {int}", When_I_right_click_position); /** * Clicks all stored elements (alternative signature). * * ```gherkin * When I click all * ``` * * @example * ```gherkin * When I click all * ``` * @remarks * Requires a previous step that stores elements. * @category Click Steps */ export async function When_I_click_all_alt(this: CustomWorld, dataTable?: DataTable) { const options = parseClickOptions(dataTable); if (!this.elements) { throw new Error("❌ No elements stored. Use a 'find' step before 'I click all'."); } const count = await this.elements.count(); if (count === 0) { throw new Error("⚠️ Stored elements are empty. Nothing to click."); } for (let i = 0; i < count; i++) { const element = this.elements.nth(i); await element.waitFor({ state: "visible", timeout: 5000 }); await element.click(options); this.log?.(`🖱️ Clicked element #${i + 1}`); } this.log?.(`✅ Clicked all ${count} stored elements.`); } When("I click all", When_I_click_all_alt); /** * Clicks on an element matching the given selector (regex step). * * ```gherkin * When I click on selector {string} * ``` * * @example * ```gherkin * When I click on selector ".my-selector" * ``` * @category Click Steps */ export async function When_I_click_on_selector(this: CustomWorld, selector: string) { const locator = this.getLocator(selector); await locator.click(); this.log?.(`🖱️ Clicked on selector: ${selector}`); } When(/^I click on selector "([^"]+)"$/, When_I_click_on_selector);