Playwright addon
Realistic fixtures for Playwright
The fakeData fixture pulls realistic synthetic data straight into your tests — seeded, reproducible, and typed end to end. One line per record, zero client wiring.
Install
Add the package as a dev dependency alongside @playwright/test. Requires Node 18+ for global fetch.
pnpm add -D @przeslijmi/real-fake-data-playwrightQuick start
Point the fixture at a Real Fake Data API instance with test.use, then pull data inside any test. test and expect are the standard Playwright exports, extended with the fakeData fixture — use them exactly as you would @playwright/test.
import { test, expect } from '@przeslijmi/real-fake-data-playwright';
test.use({ realFakeData: { baseUrl: 'https://realfakedata-api.onrender.com' } });
test('registers a new customer', async ({ page, fakeData }) => {
const person = await fakeData.plPerson({ sex: 'f' });
await page.goto('/signup');
await page.getByLabel('First name').fill(person.name);
await page.getByLabel('Surname').fill(person.surname);
await page.getByLabel('PESEL').fill(person.pesel);
await page.getByRole('button', { name: 'Create account' }).click();
await expect(page.getByText(person.surname)).toBeVisible();
});Seeded and reproducible
Each test derives a stable seed from its title, so a failing test replays the exact same data on the next run — no flakiness, trivial repro. Within a test, the Nth call uses seed + N, keeping calls distinct yet deterministic. Set seed explicitly only when you want to pin a file to a known fixed dataset.
test.use({ realFakeData: { baseUrl, seed: 42 } }); // pin this file to a fixed datasetGenerators
Each generator exposes a singular method returning one record and a plural taking count as its first argument and returning an array. Method names are locale-prefixed (plPesel, plCompany, …); locale-agnostic generators (email, lorem) carry no prefix. Every method accepts optional constraints.
| Singular | Plural | Returns | Common options |
|---|---|---|---|
| plPesel | plPesels | { value, birthDate, sex } | sex, atAge, olderThan, …, invalid |
| plPerson | plPeople | { name, surname, initials, birthDate, pesel } | same as plPesel |
| plAddress | plAddresses | { buildingNumber, postalCode, cityName, … } | teryt |
| plNip | plNips | { value, digits } | format, invalid |
| plIban | plIbans | { value, electronicFormat, bankCode, bankName } | format, bankCode, bankName, invalid |
| plRegon | plRegons | { value, variant } | variant, invalid |
| plCompany | plCompanies | { name, legalForm, nip, regon } | strategy, legalForm, …, invalid |
| plVehicleRegistration | plVehicleRegistrations | { value, prefix, individualPart, type, … } | type, voivodeship, … |
| emails | { value, localPart, domain, pattern, plusTag } | domain, pattern, … | |
| lorem | lorems | { value, words, chars, bytes, paragraphs } | bytes, chars, words, paragraphs |
Testing your validators
Every checksum generator accepts invalid: true to produce a value with a deliberately wrong check digit — the rest stays well-formed — so you can assert that your own validators reject bad input.
const bad = await fakeData.plNip({ invalid: true });
await expect(submitNip(bad.value)).rejects.toThrow('invalid checksum');Error handling
A non-2xx API response throws a RealFakeDataError carrying status (HTTP code), code (the API’s machine error code), and details (per-field validation messages).
import { RealFakeDataError } from '@przeslijmi/real-fake-data-playwright';
try {
await fakeData.plAddress({ teryt: 'not-digits' });
} catch (error) {
if (error instanceof RealFakeDataError) {
console.log(error.status, error.code, error.details);
}
}Ready to drop it into your suite?
Grab an API key, point the fixture at it, and start pulling realistic data into your tests today.