From 0d506fe48a7df145a324198d434e091ea773a2ef Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Mon, 18 May 2026 12:34:17 +0100 Subject: [PATCH] Remove toasts fixture from playwright-common: use rejectToast etc. directly. --- packages/playwright-common/package.json | 2 +- .../playwright-common/src/fixtures/toasts.ts | 163 ------------------ .../playwright-common/src/fixtures/user.ts | 4 +- 3 files changed, 3 insertions(+), 166 deletions(-) delete mode 100644 packages/playwright-common/src/fixtures/toasts.ts diff --git a/packages/playwright-common/package.json b/packages/playwright-common/package.json index e2f8cbdf67d..943b8ae558a 100644 --- a/packages/playwright-common/package.json +++ b/packages/playwright-common/package.json @@ -1,7 +1,7 @@ { "name": "@element-hq/element-web-playwright-common", "type": "module", - "version": "4.1.0", + "version": "5.0.0", "license": "SEE LICENSE IN README.md", "repository": { "type": "git", diff --git a/packages/playwright-common/src/fixtures/toasts.ts b/packages/playwright-common/src/fixtures/toasts.ts deleted file mode 100644 index cf6f6c8bb29..00000000000 --- a/packages/playwright-common/src/fixtures/toasts.ts +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2026 Element Creations Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -import { expect, type Locator, type Page } from "@playwright/test"; - -// We want to avoid using `mergeTests` in index.ts because it drops useful type -// information about the fixtures. Instead, we add `services` into our fixture -// suite by using its `test` as a base, so that there is a linear hierarchy. -import { test as base } from "./services.js"; - -// This fixture provides convenient handling of Element Web's toasts. -export const test = base.extend<{ - /** - * Convenience functions for handling toasts. - */ - toasts: Toasts; -}>({ - toasts: async ({ page }, use) => { - const toasts = new Toasts(page); - await use(toasts); - }, -}); - -class Toasts { - public constructor(public readonly page: Page) {} - - /** - * Assert that no toasts exist. - */ - public async assertNoToasts(): Promise { - await expect(this.page.locator(".mx_Toast_toast")).not.toBeVisible(); - } - - /** - * Return the toast with the supplied title. Fail or return null if it does - * not exist. - * - * If `required` is false, you should supply a relatively short `timeout` - * (e.g. 2000, meaning 2 seconds) to prevent your test taking too long. - * - * @param title - Expected title of the toast. - * @param timeout - Time in ms before we give up and decide the toast does - * not exist. If `required` is true, defaults to `timeout` - * in `TestConfig.expect`. Otherwise, defaults to 2000 (2 - * seconds). - * @param required - If true, fail the test (throw an exception) if the - * toast is not visible. Otherwise, just return null if - * the toast is not visible. - * @returns the Locator for the matching toast, or null if it is not - * visible. (null will only be returned if `required` is false.) - */ - public async getToast(title: string, timeout?: number, required?: true): Promise; - public async getToast(title: string, timeout: number | undefined, required: false): Promise; - public async getToast(title: string, timeout?: number, required = true): Promise { - const toast = this.page.locator(".mx_Toast_toast", { hasText: title }).first(); - - if (required) { - await expect(toast).toBeVisible({ timeout }); - return toast; - } else { - // If we don't set a timeout, waitFor will wait forever. Since - // required is false, we definitely don't want to wait forever. - timeout = timeout ?? 2000; - - try { - await toast.waitFor({ state: "visible", timeout }); - return toast; - } catch { - return null; - } - } - } - - /** - * Accept the toast with the supplied title, or fail if it does not exist. - * - * Only works if this toast is at the top of the stack of toasts. - * - * @param title - Expected title of the toast. - */ - public async acceptToast(title: string): Promise { - return await clickToastButton(this, title, "primary"); - } - - /** - * Accept the toast with the supplied title, if it exists, or return after 2 - * seconds if it is not found. - * - * Only works if this toast is at the top of the stack of toasts. - * - * @param title - Expected title of the toast. - */ - public async acceptToastIfExists(title: string): Promise { - return await clickToastButton(this, title, "primary", 2000, false); - } - - /** - * Reject the toast with the supplied title, or fail if it does not exist. - * - * Only works if this toast is at the top of the stack of toasts. - * - * @param title - Expected title of the toast. - */ - public async rejectToast(title: string): Promise { - return await clickToastButton(this, title, "secondary"); - } - - /** - * Reject the toast with the supplied title, if it exists, or return after 2 - * seconds if it is not found. - * - * Only works if this toast is at the top of the stack of toasts. - * - * @param title - Expected title of the toast. - */ - public async rejectToastIfExists(title: string): Promise { - return await clickToastButton(this, title, "secondary", 2000, false); - } -} - -/** - * Find the toast with the supplied title and click a button on it. - * - * Only works if this toast is at the top of the stack of toasts. - * - * If `required` is false, you should supply a relatively short `timeout` - * (e.g. 2000, meaning 2 seconds) to prevent your test taking too long. - * - * @param toasts - A Toasts instance. - * @param title - Expected title of the toast. - * @param button - Which button to click on the toast. Allowed values are - * "primary", which will accept the toast, or "secondary", - * which will reject it. - * @param timeout - Time in ms before we give up and decide the toast does - * not exist. If `required` is true, defaults to `timeout` - * in `TestConfig.expect`. Otherwise, defaults to 2000 (2 - * seconds). - * @param required - If true, fail the test (throw an exception) if the - * toast is not visible. Otherwise, just return after - * `timeout` if the toast is not visible. - */ -async function clickToastButton( - toasts: Toasts, - title: string, - button: "primary" | "secondary", - timeout?: number, - required = true, -): Promise { - let toast: Locator | null; - if (required) { - toast = await toasts.getToast(title, timeout, true); - } else { - toast = await toasts.getToast(title, timeout, false); - } - - if (toast) { - await toast.locator(`.mx_Toast_buttons button[data-kind="${button}"]`).click(); - } -} diff --git a/packages/playwright-common/src/fixtures/user.ts b/packages/playwright-common/src/fixtures/user.ts index 61f8d701057..573a47ab609 100644 --- a/packages/playwright-common/src/fixtures/user.ts +++ b/packages/playwright-common/src/fixtures/user.ts @@ -10,9 +10,9 @@ import { type Page } from "@playwright/test"; import { sample, uniqueId } from "lodash-es"; // We want to avoid using `mergeTests` in index.ts because it drops useful type -// information about the fixtures. Instead, we add `toasts` into our fixture +// information about the fixtures. Instead, we add `services` into our fixture // suite by using its `test` as a base, so that there is a linear hierarchy. -import { test as base } from "./toasts.js"; +import { test as base } from "./services.js"; import { type Credentials } from "../utils/api.js"; /** Adds an initScript to the given page which will populate localStorage appropriately so that Element will use the given credentials. */