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.