Initial Commit
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user