@przeslijmi/real-fake-data-playwright
Playwright fixtures for Real Fake Data — 190 generators of realistic, synthetic test data, one typed method per record:
- Person and company names across 27 EU countries —
dePersonName,itCompanyName,frPersonName, … in the local script and inflection, plus multi-countrypersonName/companyNamethat draw from any mix of countries. - National identifiers and VAT / company numbers for every EU member state — French
frNir/frSiren, ItalianitCodiceFiscale, SpanishesDni/esNie, DanishdkCpr, SwedishsePersonnummer, DutchnlBsn, GermandeSteuerId/deUstIdnr, and 60+ more — each with correct checksums and the sameinvalid/edgetriggers. - One-call whole people and companies for every EU country —
dkPerson,frPerson, … return a consistent name + national number;dkCompany,deCompany,nlCompany, … return a consistent trading name, legal form, and the country's register / tax / VAT numbers, all from one seed. - The full Polish national set — valid PESELs (correct checksums), NIPs, REGONs, IBANs, KRS and land-register numbers, ID cards, passports, driving licences, addresses drawn from real cities and streets, and vehicle plates.
- Locale-agnostic — emails, lorem ipsum, and
customRegex(a random string matching any regex you supply; Pro plan and above).
Output looks real but is fake — safe for staging, demos, and seed data.
- Seeded and reproducible by default. 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.
- Typed end to end. Two methods per generator (one record, or a batch), fully typed inputs and results.
- Zero ceremony. A
fakeDatafixture; no manual client wiring.
Install
npm install -D @przeslijmi/real-fake-data-playwright
# or: pnpm add -D @przeslijmi/real-fake-data-playwrightRequires @playwright/test (peer dependency) and Node 18+ (for global fetch).
Quick start
Point the fixture at a Real Fake Data API instance, then pull data inside any test:
import { test, expect } from '@przeslijmi/real-fake-data-playwright';
test.use({ realFakeData: { baseUrl: 'https://api.real-fake-data.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();
});test and expect are the standard Playwright exports, extended with the fakeData fixture — use them exactly as you would @playwright/test.
Configuration
Set options with test.use({ realFakeData: { … } }), at any scope (file, describe, or project, via your Playwright config).
| Option | Type | Description |
|---|---|---|
baseUrl |
string (required) |
Base URL of the Real Fake Data API, e.g. https://api.real-fake-data.com. |
seed |
number |
Base seed for the test. Omit to derive a stable seed from the test title (reproducible-by-default). |
headers |
Record<string, string> |
Extra headers sent with every request (e.g. an API key once your plan requires one). |
Determinism
With a base seed in play, the Nth call within a test uses seed + N — so calls are reproducible across runs yet distinct from one another. Because the default seed comes from the test title, every test is already deterministic without configuring anything; set seed explicitly only when you want to pin a test 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 of that many. Method names are locale-prefixed (plPesel, dePersonName, …) so generators for different countries never collide; locale-agnostic generators (email, lorem) and the multi-country aggregates (personName, companyName) carry no prefix.
Every method accepts optional constraints. Pass seed on any call to override that call's automatic seed.
Names across 27 EU countries
Every country listed below exposes <cc>PersonName/<cc>PersonNames, <cc>CompanyName/<cc>CompanyNames, and <cc>Company/<cc>Companies, where <cc> is its ISO 3166 code: at, be, bg, cy, cz, de, dk, ee, es, fi, fr, gr, hr, hu, ie, it, lt, lu, lv, mt, nl, pl, pt, ro, se, si, sk.
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
<cc>PersonName(opts?) |
<cc>PersonNames(count, opts?) |
{ name, surname, initials, sex } |
sex, edge, caseStrict |
<cc>CompanyName(opts?) |
<cc>CompanyNames(count, opts?) |
{ value, legalForm, strategy } |
strategy, legalForm, edge |
<cc>Company(opts?) |
<cc>Companies(count, opts?) |
{ name, legalForm, …national ids } |
strategy, legalForm, invalid, edge |
personName(opts?) |
personNames(count, opts?) |
{ name, surname, initials, sex, country } |
sex, edge, caseStrict, countries |
companyName(opts?) |
companyNames(count, opts?) |
{ value, legalForm, strategy, country } |
strategy, edge, countries |
const ceo = await fakeData.dePersonName({ sex: 'f' }); // German given name + surname
const vendor = await fakeData.itCompanyName({ edge: true }); // edge-case Italian company name
const eu = await fakeData.personName({ countries: ['pl', 'sk', 'it'] }); // drawn from one of the threecountries (on the prefix-less personName/companyName only) is an array of ISO codes; each record is generated by one country picked from the list. Omit it to draw from all 27. The per-country legalForm values differ by country (e.g. GmbH, S.r.l., S.A.), so they are typed as string; pass 'any' for a weighted-random one or 'none' to omit it.
Polish national generators
| Singular | Plural | Returns (singular) | Common options |
|---|---|---|---|
plPesel(opts?) |
plPesels(count, opts?) |
{ value, birthDate, sex } |
sex, atAge, olderThan, youngerThan, bornOn/Before/After, invalid |
plPerson(opts?) |
plPeople(count, opts?) |
{ name, surname, initials, birthDate, pesel } |
same as plPesel |
plAddress(opts?) |
plAddresses(count, opts?) |
{ buildingNumber, postalCode, cityName, …, terytCodes } |
teryt (1–7 digit prefix) |
plNip(opts?) |
plNips(count, opts?) |
{ value, digits } |
format, invalid |
plIban(opts?) |
plIbans(count, opts?) |
{ value, electronicFormat, bankCode, bankName } |
format, bankCode, bankName, invalid |
plRegon(opts?) |
plRegons(count, opts?) |
{ value, variant } |
variant (short/long/any), invalid |
plCompany(opts?) |
plCompanies(count, opts?) |
{ name, legalForm, nip, regon, krs } |
strategy, legalForm, activityPrefix, format, edge, invalid |
plCompanyName(opts?) |
plCompanyNames(count, opts?) |
{ value, legalForm, strategy } |
strategy, legalForm, activityPrefix, edge |
plIdCard(opts?) |
plIdCards(count, opts?) |
{ value, series, number, expirationDate } |
format, expired, invalid |
plPassport(opts?) |
plPassports(count, opts?) |
{ value, series, number } |
format, invalid |
plKrs(opts?) |
plKrsNumbers(count, opts?) |
{ value, number } |
format |
plLandRegister(opts?) |
plLandRegisters(count, opts?) |
{ value, courtCode, number, checkDigit, court? } |
format, court, invalid |
plDrivingLicense(opts?) |
plDrivingLicenses(count, opts?) |
{ value, serial, year, suffix } |
format, year |
plVehicleRegistration(opts?) |
plVehicleRegistrations(count, opts?) |
{ value, prefix, individualPart, type, … } |
type, voivodeship, county, format |
A Polish person name on its own (no PESEL/birth date) is plPersonName — part of the 27-country table above.
EU national identifiers
Every EU member state exposes its core national-person identifier and its business / VAT numbers. Numbers that encode a birth date and/or sex accept the same person constraints as plPesel (sex, atAge, olderThan, youngerThan, bornOn/bornBefore/bornAfter); the rest expose only their own knobs. Every checksum-bearing number takes invalid (deliberately wrong check digit) and edge (rare-corner values); generators with a VAT/intra-EU rendering take format: 'national' | 'vat' (some use a generator-specific enum — see each row).
France (fr)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
frSiren(opts?) |
frSirens(count, opts?) |
{ value, digits } |
format, invalid, edge |
frNir(opts?) |
frNirs(count, opts?) |
{ value, digits, sex, birthYear, birthMonth } |
sex, age/birth filters, invalid, edge |
frPerson(opts?) |
frPeople(count, opts?) |
{ name, surname, initials, birthDate, nir } |
sex, age/birth filters, invalid, edge, caseStrict |
Austria (at)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
atSvnr(opts?) |
atSvnrs(count, opts?) |
{ value, digits, birthDate } |
age/birth filters, invalid, edge |
atPerson(opts?) |
atPeople(count, opts?) |
{ name, surname, initials, birthDate, svnr } |
sex, age/birth filters, invalid, edge, caseStrict |
atUid(opts?) |
atUids(count, opts?) |
{ value, digits } |
format, invalid, edge |
atFirmenbuchnummer(opts?) |
atFirmenbuchnummers(count, opts?) |
{ value, number, letter } |
invalid, edge |
atSteuernummer(opts?) |
atSteuernummers(count, opts?) |
{ value, digits } |
edge |
Belgium (be)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
beRijksregisternummer(opts?) |
beRijksregisternummers(count, opts?) |
{ value, digits, birthDate, sex } |
sex, age/birth filters, kind, invalid, edge |
bePerson(opts?) |
bePeople(count, opts?) |
{ name, surname, initials, birthDate, rijksregisternummer } |
sex, age/birth filters, invalid, edge, caseStrict |
beOndernemingsnummer(opts?) |
beOndernemingsnummers(count, opts?) |
{ value, digits } |
format, invalid, edge |
Bulgaria (bg)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
bgEgn(opts?) |
bgEgns(count, opts?) |
{ value, digits, birthDate, sex } |
sex, age/birth filters, invalid, edge |
bgPerson(opts?) |
bgPeople(count, opts?) |
{ name, surname, initials, birthDate, egn } |
sex, age/birth filters, invalid, edge, caseStrict |
bgEik(opts?) |
bgEiks(count, opts?) |
{ value, digits } |
format, invalid, edge |
Croatia (hr)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
hrOib(opts?) |
hrOibs(count, opts?) |
{ value, digits } |
format, invalid, edge |
hrJmbg(opts?) |
hrJmbgs(count, opts?) |
{ value, digits, birthDate, sex } |
sex, age/birth filters, invalid, edge |
hrPerson(opts?) |
hrPeople(count, opts?) |
{ name, surname, initials, birthDate, jmbg } |
sex, age/birth filters, invalid, edge, caseStrict |
Cyprus (cy)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
cyTic(opts?) |
cyTics(count, opts?) |
{ value, digits, letter } |
format, invalid, edge |
cyPerson(opts?) |
cyPeople(count, opts?) |
{ name, surname, initials, birthDate, tic } |
sex, age/birth filters, invalid, edge, caseStrict |
Czechia (cz)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
czRodneCislo(opts?) |
czRodneCislos(count, opts?) |
{ value, digits, birthDate, sex } |
sex, age/birth filters, format, invalid, edge |
czPerson(opts?) |
czPeople(count, opts?) |
{ name, surname, initials, birthDate, rodneCislo } |
sex, age/birth filters, invalid, edge, caseStrict |
czIco(opts?) |
czIcos(count, opts?) |
{ value, digits } |
format, invalid, edge |
Denmark (dk)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
dkCpr(opts?) |
dkCprs(count, opts?) |
{ value, digits, birthDate, sex } |
sex, age/birth filters, checksum, format, invalid, edge |
dkPerson(opts?) |
dkPeople(count, opts?) |
{ name, surname, initials, birthDate, cpr } |
same as dkCpr, plus caseStrict |
dkCvr(opts?) |
dkCvrs(count, opts?) |
{ value, digits } |
format, invalid, edge |
Estonia (ee)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
eeIsikukood(opts?) |
eeIsikukoods(count, opts?) |
{ value, digits, birthDate, sex } |
sex, age/birth filters, invalid, edge |
eePerson(opts?) |
eePeople(count, opts?) |
{ name, surname, initials, birthDate, isikukood } |
sex, age/birth filters, invalid, edge, caseStrict |
eeRegistrikood(opts?) |
eeRegistrikoods(count, opts?) |
{ value, digits } |
invalid, edge |
eeKmkr(opts?) |
eeKmkrs(count, opts?) |
{ value, digits } |
format, invalid, edge |
Finland (fi)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
fiHenkilotunnus(opts?) |
fiHenkilotunnuss(count, opts?) |
{ value, digits, birthDate, sex } |
sex, age/birth filters, invalid, edge |
fiPerson(opts?) |
fiPeople(count, opts?) |
{ name, surname, initials, birthDate, henkilotunnus } |
sex, age/birth filters, invalid, edge, caseStrict |
fiYTunnus(opts?) |
fiYTunnuss(count, opts?) |
{ value, digits } |
format, invalid, edge |
Germany (de)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
deSteuerId(opts?) |
deSteuerIds(count, opts?) |
{ value, digits } |
invalid, edge |
dePerson(opts?) |
dePeople(count, opts?) |
{ name, surname, initials, birthDate, steuerId } |
sex, age/birth filters, invalid, edge, caseStrict |
deUstIdnr(opts?) |
deUstIdnrs(count, opts?) |
{ value, digits } |
format, invalid, edge |
deHandelsregisternummer(opts?) |
deHandelsregisternummers(count, opts?) |
{ value, division, court, number } |
division, edge |
deWirtschaftsIdnr(opts?) |
deWirtschaftsIdnrs(count, opts?) |
{ value, digits, suffix } |
suffix, invalid, edge |
dePersonalausweis(opts?) |
dePersonalausweiss(count, opts?) |
{ value, serial, checkDigit } |
invalid, edge |
Greece (gr)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
grAmka(opts?) |
grAmkas(count, opts?) |
{ value, digits, birthDate, sex } |
sex, age/birth filters, invalid, edge |
grPerson(opts?) |
grPeople(count, opts?) |
{ name, surname, initials, birthDate, amka } |
sex, age/birth filters, invalid, edge, caseStrict |
grAfm(opts?) |
grAfms(count, opts?) |
{ value, digits } |
format, invalid, edge |
Hungary (hu)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
huAdoazonositoJel(opts?) |
huAdoazonositoJels(count, opts?) |
{ value, digits, birthDate } |
age/birth filters, invalid, edge |
huTaj(opts?) |
huTajs(count, opts?) |
{ value, digits } |
invalid, edge |
huSzemelyiAzonosito(opts?) |
huSzemelyiAzonositos(count, opts?) |
{ value, digits, birthDate, sex, standard } |
sex, age/birth filters, standard, invalid, edge |
huPerson(opts?) |
huPeople(count, opts?) |
{ name, surname, initials, birthDate, szemelyiAzonosito } |
sex, age/birth filters, invalid, edge, caseStrict |
huAdoszam(opts?) |
huAdoszams(count, opts?) |
{ value, digits } |
format, invalid, edge |
huCegjegyzekszam(opts?) |
huCegjegyzekszams(count, opts?) |
{ value, court, form, serial, digits } |
edge |
Ireland (ie)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
iePpsn(opts?) |
iePpsns(count, opts?) |
{ value, digits, checkLetter, secondLetter? } |
standard, invalid, edge |
iePerson(opts?) |
iePeople(count, opts?) |
{ name, surname, initials, birthDate, ppsn } |
sex, age/birth filters, invalid, edge, caseStrict |
ieVat(opts?) |
ieVats(count, opts?) |
{ value, digits } |
format, standard, invalid, edge |
ieCro(opts?) |
ieCros(count, opts?) |
{ value, digits } |
edge |
Italy (it)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
itCodiceFiscale(opts?) |
itCodiceFiscales(count, opts?) |
{ value, surnameCode, nameCode, birthDate, sex } |
sex, age/birth filters, surname, name, invalid, edge |
itPerson(opts?) |
itPeople(count, opts?) |
{ name, surname, initials, birthDate, codiceFiscale } |
sex, age/birth filters, invalid, edge, caseStrict |
itPartitaIva(opts?) |
itPartitaIvas(count, opts?) |
{ value, digits } |
format, invalid, edge |
Latvia (lv)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
lvPersonasKods(opts?) |
lvPersonasKodss(count, opts?) |
{ value, digits, birthDate? } |
age/birth filters, standard, format, invalid, edge |
lvPerson(opts?) |
lvPeople(count, opts?) |
{ name, surname, initials, birthDate, personasKods } |
sex, age/birth filters, invalid, edge, caseStrict |
lvRegistracijasNumurs(opts?) |
lvRegistracijasNumurss(count, opts?) |
{ value, digits } |
format, invalid, edge |
Lithuania (lt)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
ltAsmensKodas(opts?) |
ltAsmensKodass(count, opts?) |
{ value, digits, birthDate, sex } |
sex, age/birth filters, invalid, edge |
ltPerson(opts?) |
ltPeople(count, opts?) |
{ name, surname, initials, birthDate, asmensKodas } |
sex, age/birth filters, invalid, edge, caseStrict |
ltImonesKodas(opts?) |
ltImonesKodass(count, opts?) |
{ value, digits } |
invalid, edge |
ltPvm(opts?) |
ltPvms(count, opts?) |
{ value, digits } |
format, invalid, edge |
Luxembourg (lu)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
luMatricule(opts?) |
luMatricules(count, opts?) |
{ value, digits, birthDate } |
age/birth filters, invalid, edge |
luPerson(opts?) |
luPeople(count, opts?) |
{ name, surname, initials, birthDate, matricule } |
sex, age/birth filters, invalid, edge, caseStrict |
luTva(opts?) |
luTvas(count, opts?) |
{ value, digits } |
format, invalid, edge |
Malta (mt)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
mtIdCard(opts?) |
mtIdCards(count, opts?) |
{ value, digits, category } |
category, edge |
mtPerson(opts?) |
mtPeople(count, opts?) |
{ name, surname, initials, birthDate, idCard } |
sex, age/birth filters, invalid, edge, caseStrict |
mtVat(opts?) |
mtVats(count, opts?) |
{ value, digits } |
format, invalid, edge |
Netherlands (nl)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
nlBsn(opts?) |
nlBsns(count, opts?) |
{ value, digits } |
invalid, edge |
nlPerson(opts?) |
nlPeople(count, opts?) |
{ name, surname, initials, birthDate, bsn } |
sex, age/birth filters, invalid, edge, caseStrict |
nlRsin(opts?) |
nlRsins(count, opts?) |
{ value, digits } |
invalid, edge |
nlBtwId(opts?) |
nlBtwIds(count, opts?) |
{ value, digits, standard } |
standard, invalid, edge |
nlKvk(opts?) |
nlKvks(count, opts?) |
{ value, digits } |
edge |
Portugal (pt)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
ptNif(opts?) |
ptNifs(count, opts?) |
{ value, digits, entity } |
entity, format, invalid, edge |
ptCartaoCidadao(opts?) |
ptCartaoCidadaos(count, opts?) |
{ value, nic, version } |
invalid, edge |
ptPerson(opts?) |
ptPeople(count, opts?) |
{ name, surname, initials, birthDate, cartaoCidadao } |
sex, age/birth filters, invalid, edge, caseStrict |
Romania (ro)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
roCnp(opts?) |
roCnps(count, opts?) |
{ value, digits, birthDate, sex, county } |
sex, age/birth filters, invalid, edge |
roPerson(opts?) |
roPeople(count, opts?) |
{ name, surname, initials, birthDate, cnp } |
sex, age/birth filters, invalid, edge, caseStrict |
roCui(opts?) |
roCuis(count, opts?) |
{ value, digits } |
format, invalid, edge |
Slovakia (sk)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
skRodneCislo(opts?) |
skRodneCislos(count, opts?) |
{ value, digits, birthDate, sex } |
sex, age/birth filters, format, invalid, edge |
skPerson(opts?) |
skPeople(count, opts?) |
{ name, surname, initials, birthDate, rodneCislo } |
sex, age/birth filters, invalid, edge, caseStrict |
skIco(opts?) |
skIcos(count, opts?) |
{ value, digits } |
invalid, edge |
skIcDph(opts?) |
skIcDphs(count, opts?) |
{ value, digits } |
format, invalid, edge |
Slovenia (si)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
siEmso(opts?) |
siEmsos(count, opts?) |
{ value, digits, birthDate, sex } |
sex, age/birth filters, invalid, edge |
siPerson(opts?) |
siPeople(count, opts?) |
{ name, surname, initials, birthDate, emso } |
sex, age/birth filters, invalid, edge, caseStrict |
siDavcnaStevilka(opts?) |
siDavcnaStevilkas(count, opts?) |
{ value, digits } |
format, invalid, edge |
Spain (es)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
esDni(opts?) |
esDnis(count, opts?) |
{ value, digits, letter } |
invalid, edge |
esPerson(opts?) |
esPeople(count, opts?) |
{ name, surname, initials, birthDate, dni } |
sex, age/birth filters, invalid, edge, caseStrict |
esNie(opts?) |
esNies(count, opts?) |
{ value, prefix, digits, letter } |
invalid, edge |
esCif(opts?) |
esCifs(count, opts?) |
{ value, digits } |
format, invalid, edge |
Sweden (se)
| Singular | Plural | Returns (singular) | Options |
|---|---|---|---|
sePersonnummer(opts?) |
sePersonnummers(count, opts?) |
{ value, digits, birthDate, sex } |
sex, age/birth filters, format, kind, invalid, edge |
sePerson(opts?) |
sePeople(count, opts?) |
{ name, surname, initials, birthDate, personnummer } |
sex, age/birth filters, invalid, edge, caseStrict |
seOrganisationsnummer(opts?) |
seOrganisationsnummers(count, opts?) |
{ value, digits } |
format, invalid, edge |
Locale-agnostic
| Singular | Plural | Returns (singular) | Common options |
|---|---|---|---|
email(opts?) |
emails(count, opts?) |
{ value, localPart, domain, pattern, plusTag } |
domain, domainCategory, pattern, plusTag, exotic |
lorem(opts?) |
lorems(count, opts?) |
{ value, words, chars, bytes, paragraphs, startedWithLorem } |
bytes, chars, words, paragraphs, startWithLorem |
customRegex(opts) |
customRegexes(count, opts) |
{ value, pattern } |
pattern (required), maxRepetition — Pro plan and above |
Generating many records at once
Every plural takes count as its first argument and returns an array. The bound (10 by default, raised by paid tiers) is enforced by the API — an out-of-range count throws a RealFakeDataError (HTTP 400), never a silent clamp. A plural is a single request seeded once, so it consumes one slot of the per-test seed sequence just like a singular call.
const team = await fakeData.plPeople(5, { sex: 'f' }); // PolishPersonData[] of length 5
const inboxes = await fakeData.emails(3); // EmailData[] of length 3Special triggers
Three opt-in flags steer generators toward the cases real-world data throws at your code:
invalid: true— on every checksum generator (plPesel,plNip,plRegon,plIban,plCompany,plIdCard,plPassport,plLandRegister), produces a value with a deliberately wrong check digit while the rest stays well-formed. For asserting that your own validators reject bad input. When set, the responsemeta.invalidistrueso a batch can tell the broken record apart.edge: true— on the name generators (<cc>PersonName,<cc>CompanyName,personName,companyName,plCompany), biases toward edge-case shapes: second given names, double-barrelled surnames, very short names, punctuation-heavy or unusually long company names. The corners that break naïve form validation and layout.caseStrict: false— on the person-name generators, deliberately mangles the casing of name and surname (all-lower, all-upper, or random); initials stay proper uppercase. Defaults totrue(proper casing). For testing case-insensitive matching and normalisation.
const bad = await fakeData.plNip({ invalid: true });
await expect(submitNip(bad.value)).rejects.toThrow('invalid checksum');
const messy = await fakeData.dePersonName({ caseStrict: false }); // e.g. { name: 'hANS', surname: 'müller' }
const tricky = await fakeData.itCompanyName({ edge: true }); // punctuation-heavy / long-form nameError 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);
// 400 'VALIDATION_ERROR' [{ path: 'teryt', message: 'teryt must be 1–7 digits' }]
}
}Advanced: using the client without the fixture
The fixture is a thin wrapper over a provider and a facade you can use directly — handy in global setup, scripts, or non-Playwright code:
import { CloudFakeDataProvider, createFakeData } from '@przeslijmi/real-fake-data-playwright';
const provider = new CloudFakeDataProvider({ baseUrl: 'https://api.real-fake-data.com' });
const fakeData = createFakeData(provider, { seed: 42 });
const company = await fakeData.plCompanyName({ legalForm: 'S.A.' });The FakeDataProvider interface is the swap point: the cloud provider talks HTTP to the hosted API, and the same facade can run against other backends.
License
MIT
This repository is auto-generated from a private upstream monorepo. Open issues here, but code changes are made upstream and re-synced — pull requests against this repo are applied upstream, not merged directly.