Test Suite Organization
Relevant source files
The following files were used as context for generating this wiki page:
The playwright-page-object library organizes test suites by decoupling selector logic from test execution through a decorator-driven Page Object Model (POM). This structure transitions from raw Playwright page.locator() chains to a typed, composable graph of controls. The organization is designed for incremental adoption, allowing developers to mix raw locators, external control classes, and built-in base classes within the same suite.
Sources: README.md:1-20, skills/playwright-page-object/SKILL.md:85-100
Core Architectural Components
The test suite organization relies on three primary layers: Root Contexts, Child Locators, and Fixture Injection. This structure ensures that locators remain lazy and are only resolved when accessed during test execution.
Test Structure Layers
| Component | Responsibility | Relevant Classes/Decorators |
|---|---|---|
| Root Context | Establishes the top-level locator (e.g., "body" or a specific container). | @RootSelector, RootPageObject |
| Child Controls | Defines relative locators and nested components within a root. | @Selector, PageObject, ListPageObject |
| Fixture Layer | Injects instantiated page objects into Playwright tests automatically. | createFixtures |
Sources: README.md:46-75, skills/playwright-page-object/SKILL.md:12-25
Control Graph Hierarchy
The following diagram illustrates how the test suite organizes UI components into a typed graph, as demonstrated in the checkout example.
Sources: example/README.md:25-35, README.md:105-125
Dependency Injection and Fixtures
Tests are organized to receive page objects through Playwright's fixture system. The createFixtures utility eliminates manual instantiation of page objects within test files.
Implementation Example
Fixtures are extended from the base Playwright test object, allowing multiple page objects to coexist in a single test context.
export const test = base.extend<{
checkoutPage: CheckoutPage;
externalCheckoutPage: ExternalCheckoutPage;
}>(
createFixtures({
checkoutPage: CheckoutPage,
externalCheckoutPage: ExternalCheckoutPage,
}),
);
Sources: example/e2e/fixtures.ts:1-12
Selection and Verification Logic
Test logic is organized into repeatable methods within Page Objects, separating the "how" (selectors and actions) from the "what" (test assertions).
Built-in Wait and Assertion Helpers
The PageObject base class provides a standard set of wait methods used to organize synchronization logic.
| Method | Target State |
|---|---|
.waitVisible() | Visibility of the element |
.waitCount(n) | Number of elements matching the selector |
.waitText(text) | Exact text match |
.expect() | Access to Playwright expect(locator) API |
Sources: README.md:158-180, src/tests/page-objects/PageObject.spec.ts:135-180
List Management
Repeated elements are organized using ListPageObject, which supports async iteration and filtering. This allows tests to handle dynamic collections without manual index management.
// Iterating over organized items
for await (const item of checkoutPage.CartItems.items) {
await item.expect({ soft: true }).toBeVisible();
}
// Filtering by criteria
const widgetB = checkoutPage.CartItems.filterByText("Widget B");
await widgetB.RemoveButton.$.click();
Sources: example/README.md:50-65, example/e2e/checkout.spec.ts:40-55
Development Workflow and Scripting
The repository organizes its development lifecycle through standard NPM scripts, ensuring consistency in building, linting, and testing across the package and its examples.
| Script | Description |
|---|---|
npm run build | Compiles the source using tsup into CJS/ESM formats. |
npm run lint | Runs biome for code style enforcement. |
npm run test | Executes the unit test suite via vitest. |
npm run test:example | Packs the local package and runs E2E tests in the /example directory. |
Sources: package.json:15-28, CONTRIBUTING.md:30-45
The project uses Conventional Commits to organize releases, where feat: triggers minor versions and fix: triggers patch versions. Code style is enforced via Biome with Zero Config, integrated into a Husky pre-commit hook to ensure all tests and examples maintain structural integrity before submission.
Sources: CONTRIBUTING.md:47-65, biome.json:1-30