first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
# mock-clipboard
## Purpose
`mockClipboard` installs a deterministic, in-memory clipboard implementation on the navigator object for a Playwright page. The default clipboard shipped by Chromium headless requires explicit user-gesture permissions and does not work at all in some CI environments; this helper replaces it with a programmatic pair of `writeText` / `readText` that behaves identically in every environment.
## Features
- Installs via `page.addInitScript` so the mock is active before any app code runs
- In-memory state is per-page — different pages don't share clipboard state
- Matches the real `navigator.clipboard` API surface for `writeText` and `readText`
- Idempotent — calling twice on the same page just re-installs the same script
## Usage: Basic Example
```ts
import { mockClipboard } from "@suaveplan/testing-e2e/helpers";
await mockClipboard(page);
await page.goto("/settings");
await page.click("text=Copy API key");
const copied = await page.evaluate(() => navigator.clipboard.readText());
expect(copied).toMatch(/^sk_/);
```
## Usage: Advanced Example
```ts
import { mockClipboard } from "@suaveplan/testing-e2e/helpers";
import { expect } from "@playwright/test";
test("copy + paste round trip", async ({ page }) => {
await mockClipboard(page);
await page.goto("/notes/123");
await page.getByRole("button", { name: /copy link/i }).click();
const copied = await page.evaluate(() => navigator.clipboard.readText());
expect(copied).toBe("https://notes.example/123");
// Paste somewhere:
await page.goto("/notes/new");
await page.evaluate(async () => {
const text = await navigator.clipboard.readText();
(document.querySelector("textarea") as HTMLTextAreaElement).value = text;
});
await expect(page.locator("textarea")).toHaveValue("https://notes.example/123");
});
```
## API Reference
### `mockClipboard(page): Promise<void>`
- `page: Page` — Playwright page (must be called before any navigation for the init script to take effect)
- Returns `Promise<void>` that resolves after the init script is registered
## Implementation Notes
The init script defines `navigator.clipboard` using `Object.defineProperty` with `writable: true` so a test that wants to swap in a further spy can still do so. Because the mock is installed via `addInitScript`, it's reinstalled automatically on every navigation within the same page — tests don't need to reinstall after `page.goto`.
### Behaviour
`mockClipboard(page)` installs an `addInitScript` that replaces `navigator.clipboard.readText` / `writeText` with in-memory stubs whose state survives page navigations inside the same context. A companion `getClipboardValue(page)` reads the current mock value synchronously from the page's JS context so assertions do not need to await a clipboard-permissions prompt.