Browser audit

Catching anchors that never render.

What it catches

The third layer. TypeScript catches a typo. cairn check catches an element deleted from source. Neither can see whether an element actually renders — behind a feature flag, in an empty state, or inside a conditional that no longer fires. That needs a browser.

The audit drives each tour the way a user would and reports any step whose anchor produced no spotlight.

Setup

tests/walkthrough.spec.ts
import { test } from "@playwright/test";
import { auditFlows } from "@cairnkit/cli";
import { inviteFlow, questionsFlow } from "../src/walkthrough/flows";

const BASE = "http://localhost:4200";

test("every step of every flow spotlights something", async ({ page }) => {
  await auditFlows(page, [
    { url: BASE, flow: inviteFlow },
    { url: `${BASE}/questions`, flow: questionsFlow },
  ]);
});

It uses your ?tour= deep link to start each flow, presses Next where offered, and clicks the real anchored element where the step waits on an action.

In CI

.github/workflows/ci.yml
- run: npx playwright install --with-deps chromium
- run: npx playwright test

- uses: actions/upload-artifact@v4
  if: failure()
  with:
    name: playwright-report
    path: playwright-report/

Options

  • url — the page the flow starts on. ?tour= is appended for you.
  • flow — the flow object, so the auditor knows which element to click.
  • settleMs — how long each step is given to settle. Default 400.
  • timeout — per-step wait before a step counts as unreached. Default 8000.