Fixtures
createFixtures() turns a map of constructors (or factory functions) into a Playwright Fixtures object. Pass the result to test.extend().
Basic usage — constructors
Section titled “Basic usage — constructors”import { test as base } from "@playwright/test";import { createFixtures } from "playwright-page-object";import { CheckoutPage } from "./page-objects/CheckoutPage";import { CartPage } from "./page-objects/CartPage";
export const test = base.extend<{ checkoutPage: CheckoutPage; cartPage: CartPage;}>( createFixtures({ checkoutPage: CheckoutPage, cartPage: CartPage, }),);
test("apply promo code", async ({ checkoutPage }) => { await checkoutPage.applyPromoCode("SAVE20");});Each fixture instantiates its class with new Class(page) and passes the instance to use().
Factory functions — extra arguments
Section titled “Factory functions — extra arguments”When a page object’s constructor needs more than page, supply an arrow function:
class AuthPage { constructor(readonly page: Page, readonly config: AuthConfig) {}}
export const test = base.extend<{ authPage: AuthPage }>( createFixtures({ authPage: (page) => new AuthPage(page, authConfig), }),);The library detects class-vs-function at runtime: classes (with a prototype) get new-called; arrow functions get called directly.
Mixed map
Section titled “Mixed map”Classes and factories can coexist in the same map:
export const test = base.extend<{ homePage: HomePage; authPage: AuthPage;}>( createFixtures({ homePage: HomePage, // class authPage: (page) => new AuthPage(page, authConfig), // factory }),);Manual instantiation is still valid
Section titled “Manual instantiation is still valid”Fixtures are optional. If your suite doesn’t already use Playwright fixtures, manual new works fine:
test("apply promo code", async ({ page }) => { const checkout = new CheckoutPage(page); await checkout.applyPromoCode("SAVE20");});Use fixtures when your suite already relies on them or when you want to share setup across many tests.
Gotchas
Section titled “Gotchas”- Regular (non-arrow) functions are detected as constructors because they have a
prototypeproperty. Use arrow functions for factories:(page) => new X(page, config). - Class with no constructor accepting
pagewill fail at runtime when instantiated. The library does not validate the signature — TypeScript catches this at compile time via theextend<>type parameter.
See also
Section titled “See also”- createFixtures API — full type and detection rules.