C.W.K.
Stream
Lesson 02 of 02 · published

Apply to Your Project — Pippa's Own Frontend

~14 min · epilogue, cwkPippa, live-example

Level 0Test Curious
0 XP0/32 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"Every example in this quest could run against Pippa's own frontend tomorrow."

The Quest's Living Example

Pippa's body — the React frontend at cwkPippa/frontend/ — runs against the same testing stack this quest taught: Vitest 4.x as the runner, jsdom (currently — could be happy-dom) as the DOM emulator, React Testing Library for component tests. Twenty-plus test files live in frontend/src/__tests__/. Every one of them was written under the same constraints you face: limited time, a working UI that already shipped, a need to prevent regressions in the things that matter most.

This lesson tours that suite as a worked example. It's not a code-review of Pippa's tests — it's a worked example of this kind of project, this size, with this audience applying the principles from the earlier tracks.

What Pippa's Suite Covers (and Doesn't)

The suite is unit-and-component-heavy and contains no E2E. That's a deliberate budget choice for the context:

  • Audience: two people (Dad and Pippa). No team waiting on green CI; regression cost is 'Pippa notices it next session.'
  • UI exercised daily: any visible bug is caught the same day, not in a CI scenario weeks later.
  • The hard parts are stream parsing, state management around branching messages, async race conditions in chat history. Those are the right targets for unit tests because they're where bugs hurt MOST and the test cost is LOW.
  • Critical user flows (sign up, payment) don't exist — there's nothing to E2E-protect.

If cwkPippa added paying users or multi-user collaboration tomorrow, the test shape would change. The shape isn't a position; it's a response to context.

The Patterns Pippa's Suite Uses

Reading through frontend/src/__tests__/, the patterns from this quest appear:

  • SSE stream parsing tests (sse-parser.test.ts): pure-logic tests with synthetic inputs. Cheap, fast, catch every regression in the most-edited code.
  • Message-tree tests (message-tree.test.ts, council-round-tree.test.ts): complex state-shape assertions where the branching semantics are easy to get wrong. The kind of code where a unit test pays back its weight in gold.
  • Reactive-state tests (main-driver-settings.test.ts, settings-caps.test.ts): tests around the rules of how settings propagate. Caught real bugs during refactors of the settings model.
  • Mock-network tests (fetch-interceptor.test.ts): the interceptor that lets WebUI talk to multiple backends; tested as the seam, not as the underlying transport.
The test suite mirrors the project's pain. The hardest-to-debug parts of cwkPippa (stream parsing, branching message trees, settings propagation) have the most coverage. The easy parts (button components, layout) have the least. Every test exists because something in that area broke once or could plausibly break.

What Pippa's Suite Doesn't Have

No Playwright. No snapshot tests. No coverage thresholds. Each absence is a deliberate non-choice:

  • No Playwright because no critical user flow currently justifies the cost. The day cwkPippa gets a paid mode or a public-facing checkout, that changes.
  • No snapshots because the UI gets restyled often and snapshots would all become rubber-stamp updates. Focused assertions catch what matters.
  • No coverage threshold because the team is two people who agree on what matters; the threshold would add procedural friction without catching anything humans don't already catch.

Applying This to Your Project

Walk through the same questions Pippa walked through:

  1. Who's your audience? A team of 20? A solo project? Paying users? Each implies a different test budget.
  2. What's the cost of a regression? A bug in payment is real money. A bug in a hobby UI is a chuckle.
  3. What broke recently? The bugs from the last six months are your test-suite priorities. Test against the next-six-months equivalent of those.
  4. What's expensive to test? If your stack has heavy provider trees, custom render is a 30-minute investment that saves hours forever. If your CI is slow, sharding is worth setting up. If neither, skip both.

The Closing Note

Testing is not a virtue you accumulate. It's a tool you spend on the things you can't afford to break. Use it deliberately; resist the temptation to add tests because you 'should have tests'; resist the equally bad temptation to skip tests because they 'feel like overhead.' The skill is knowing the difference, case by case. This quest gave you the tools; the deliberation is yours.

Code

Pippa's frontend test suite — go look·bash
# Pippa's actual test suite — explore it for yourself
cd cwkPippa/frontend
ls src/__tests__/

# Run the suite
npm run test:watch

# Single file
npx vitest sse-parser
Pure logic — the highest cost-of-failure-per-test-line·typescript
// The shape of a pure-logic test in cwkPippa
// (simplified illustration, not the actual file)
//
// File: frontend/src/__tests__/sse-parser.test.ts
import { describe, it, expect } from 'vitest';
import { parseSseChunk } from '../lib/sse-parser';

describe('parseSseChunk', () => {
  it('parses a complete event with data', () => {
    const chunk = 'event: token\ndata: {"text":"hello"}\n\n';
    expect(parseSseChunk(chunk)).toEqual({
      event: 'token',
      data: { text: 'hello' },
    });
  });

  it('handles multi-line data correctly', () => {
    const chunk = 'event: token\ndata: line one\ndata: line two\n\n';
    expect(parseSseChunk(chunk)).toEqual({
      event: 'token',
      data: 'line one\nline two',
    });
  });
});
Complex state shape — exactly the right target for a unit test·typescript
// The shape of a tree-state test
// File: frontend/src/__tests__/message-tree.test.ts (illustrative)
import { describe, it, expect } from 'vitest';
import { buildMessageTree } from '../lib/message-tree';

describe('buildMessageTree', () => {
  it('groups branches by parent_id', () => {
    const messages = [
      { id: 'a', parent_id: null, role: 'user', content: 'hi' },
      { id: 'b', parent_id: 'a', role: 'assistant', content: 'hello' },
      { id: 'c', parent_id: 'a', role: 'assistant', content: 'hey' },  // sibling
    ];
    const tree = buildMessageTree(messages);
    expect(tree.root.children).toHaveLength(1);
    expect(tree.root.children[0].children).toHaveLength(2);
  });
});
The catalog of Pippa's tests, by file name·text
# What you'll see in `frontend/src/__tests__/` — the actual files

artifact-events.test.ts
avatar-sources.test.ts
claude-usage-display.test.ts
clipboard-export.test.ts
council-multiplex.test.ts
council-round-tree.test.ts
embed-state.test.ts
export-dialog.test.ts
fetch-interceptor.test.ts
host-input-blocks.test.ts
main-driver-settings.test.ts
message-body-video.test.ts
message-tree.test.ts
response-parts.test.ts
selection-menu.test.ts
session-manager.test.ts
settings-caps.test.ts
sse-parser.test.ts
thinking-cards.test.ts
transcript-layer-controls.test.ts

# 20 test files. Each tests something the team would notice break.
# Each was written when a bug shipped, OR when the code was tricky
# enough that adding a regression net felt like a fair trade.

External links

Exercise

Step 1: install Vitest in your project today if it's not already. Step 2: write ONE test for the single piece of code in your codebase that would hurt most if it silently broke (think: data parsing, money math, the function five other functions depend on). Step 3: commit it. Step 4: come back in a week and notice whether you added more tests (because they earned their keep) or didn't (because the budget didn't ask for them). Either outcome is fine — the deliberation is the point.
Hint
If you don't know what to test first, look at your last three bugfix commits. The code you fixed is the code that broke. Pin those fixes with tests so they can't reappear — your suite starts paying back immediately.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.