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,87 @@
# page-object
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`PageObject` is the abstract base class for Playwright Page Object Model implementations. It wires every subclass with a consistent `navigate` / `waitForReady` / `findByRole` / `findByLabel` / `findByText` surface so spec files stay declarative. Subclasses override the `path` and `waitForReady` specifics while inheriting the shared query conveniences.
## Features
- Abstract `path: string` — subclass declares the route
- `navigate(options?)` — delegates to `page.goto` with the configured path
- `waitForReady(options?)` — subclass overrides to assert page-specific readiness
- Query helpers: `findByRole`, `findByLabel`, `findByText` — thin wrappers over `page.getBy*`
- `exactOptionalPropertyTypes`-safe: `timeout` is forwarded only when set
## Usage: Basic Example
```ts
import { PageObject } from "@suaveplan/testing-e2e/page-objects";
class LoginPage extends PageObject {
public readonly path = "/login";
public async waitForReady(): Promise<void> {
await this.findByRole("heading", { name: /sign in/i });
}
}
// spec:
const login = new LoginPage(page);
await login.navigate();
await login.waitForReady();
```
## Usage: Advanced Example
```ts
import { PageObject } from "@suaveplan/testing-e2e/page-objects";
import { expect } from "@playwright/test";
class CheckoutPage extends PageObject {
public readonly path = "/checkout";
public async waitForReady({ timeoutMs }: { timeoutMs?: number } = {}): Promise<void> {
const headingFinder = this.findByRole("heading", { name: /checkout/i });
await expect(headingFinder).toBeVisible({
...(timeoutMs !== undefined ? { timeout: timeoutMs } : {}),
});
}
public async enterCardNumber(number: string): Promise<void> {
await this.findByLabel("Card number").fill(number);
}
public async submit(): Promise<void> {
await this.findByRole("button", { name: /pay now/i }).click();
}
}
// spec:
const checkout = new CheckoutPage(page);
await checkout.navigate({ timeoutMs: 10_000 });
await checkout.waitForReady();
await checkout.enterCardNumber("4242 4242 4242 4242");
await checkout.submit();
```
## API Reference
### `abstract class PageObject`
- `abstract readonly path: string`
- `constructor(page: Page)`
- `navigate(options?: { timeoutMs?: number }): Promise<void>`
- `waitForReady(options?: { timeoutMs?: number }): Promise<void>` — subclass override
- `findByRole(role, options?)` → `Locator`
- `findByLabel(label)` → `Locator`
- `findByText(text)` → `Locator`
## Implementation Notes
`navigate` calls `page.waitForLoadState("domcontentloaded", waitOptions)` where `waitOptions` is `undefined` when no timeout is supplied and `{ timeout }` when one is — this conditional construction is required by `exactOptionalPropertyTypes` which forbids passing `{ timeout: undefined }`. The class deliberately stays small; subclass-specific assertions belong on the subclass, not baked into a common helper that tries to anticipate every scenario.
### Base Class
`PageObject` is the minimal base class for Playwright page-object-model helpers. It carries a `page: Page` reference, a `baseUrl: string`, and exposes `goto(path?)` / `expectVisible(locator)` / `expectUrlMatches(regex)` helpers that every subclass uses. Subclasses narrow the locator surface to the page's specific components and keep tests focused on flows rather than selectors.