PL–01 / assertion evidence

Freeze the failure.
Keep the journey moving.

A tiny Playwright fixture that captures the visual, DOM, console, and network state at each failed soft assertion—not at the end of the test.

  • Local only
  • Scrubbed first
  • Zero runtime dependencies
Technical plan of a browser journey with one failed step circled and four evidence callouts
Fig. 01 Evidence is captured at the failure coordinate while the route continues.

01 / The evidence gap

The report shows where the test ended. You need where it broke.

A soft assertion lets a critical journey continue. That is useful—until the page changes three more times and the final trace no longer shows the broken cart, stale price, or silent JavaScript error.

  1. AssertRun your normal Playwright assertion.
  2. FreezeOn failure, scrub and capture immediately.
  3. ContinueRegister a soft failure; keep the journey running.

02 / Live receipt specimen

One failure. Five useful clues.

Choose a checkpoint to inspect the evidence an engineer receives. Arrow keys move between checkpoints.

Journey coordinates

Scrubbed before captureFields, selectors, query strings, and credentials stay out.

Assertion failed · evidence frozen

Cart count increments

RCPT / 02

Viewport

42 KB · masked
shop.test/products/field-notes
Field notes
0

Signals

bounded
DOM
data-count="0"
ARIA
status “0 items”
Console
TypeError × 1
Network
POST /cart · 200

Checkpoint 2 of 3: failed assertion evidence selected.

03 / Every receipt includes

Enough state to diagnose. Not enough to become a data leak.

04 / Field installation

Wrap only the assertions that matter.

Use regular expect inside receipt.soft. The helper freezes evidence, then records a real Playwright soft failure so your test can continue.

fixtures.ts + journey.spec.ts
// fixtures.ts
import { createReceiptTest, expect } from 'journey-failure-receipts/playwright';

export const test = createReceiptTest({
  maskSelectors: ['[data-private]'],
  domSelector: 'main',
});

// journey.spec.ts
test('add to cart', async ({ page, receipt }) => {
  await receipt.soft('Cart count increments', async () => {
    await expect(page.getByTestId('cart-count')).toHaveText('1');
  });
});

PL–05 / ready for CI

Stop rerunning journeys just to see what already happened.

Install the fixture

Free, MIT licensed, and local by default.
No account. No upload. No lock-in.