Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
# dismiss-dialog
## Purpose
`dismissDialog` attaches a one-shot handler to the next `page.on("dialog")` event, with the caller choosing between `accept` and `dismiss`. It's the small piece of glue that turns Playwright's event-driven dialog model into an imperative one-liner, which matches how most tests actually think about modal dialogs.
## Features
- Installs a single `page.on("dialog", …)` listener; auto-removes after it fires
- Choice of `accept` (OK/Allow) or `dismiss` (Cancel/Deny)
- Safe to register before the action that triggers the dialog
- Returns an unsubscribe function so the test can detach manually if the dialog never appears
## Usage: Basic Example
```ts
import { dismissDialog } from "@suaveplan/testing-e2e/helpers";
const off = dismissDialog(page, "accept");
await page.click("text=Delete");
// If a confirm() pops, it is accepted.
off(); // optional — the handler auto-removes after firing
```
## Usage: Advanced Example
```ts
import { dismissDialog } from "@suaveplan/testing-e2e/helpers";
import { expect } from "@playwright/test";
test("destructive action requires confirm", async ({ page }) => {
await page.goto("/account");
dismissDialog(page, "dismiss"); // cancel the confirm
await page.click("text=Delete account");
await expect(page.getByRole("alert")).toHaveText(/cancelled/i);
dismissDialog(page, "accept"); // now accept it
await page.click("text=Delete account");
await expect(page).toHaveURL("/goodbye");
});
```
## API Reference
### `dismissDialog(page, action): () => void`
- `page: Page` — Playwright page
- `action: "accept" | "dismiss"` — what to do when the dialog appears
- Returns an unsubscribe function; safe to call after the handler has already auto-removed
## Implementation Notes
Per the project-wide guidance around browser dialogs, tests should avoid triggering dialogs when possible — they block the entire Playwright event stream until dismissed. `dismissDialog` is for the cases where dismissal is unavoidable (e.g. testing a `beforeunload` prompt). The handler uses `{ once: true }` semantics so a stale handler from a prior test never intercepts the current one.
### Race Protection
`dismissDialog(page)` registers a one-shot `page.once("dialog", d => d.dismiss())` listener and immediately returns a disposer that removes the listener if the dialog never fires. Doing it as one-shot avoids leaking listeners across test boundaries — a repeated bug in the previous iteration. The helper also logs the dialog's `type` and `message` through the structured logger so trace viewers show exactly what was dismissed.