There is a moment in most projects where the test environment quietly decides what you are allowed to build. You reach for a Worker, or WebAssembly, or a shadow root, and jsdom does not have it — so the code gets restructured until it is testable, which usually means adding an abstraction whose only user is the test suite.
This course takes the opposite route. The application stays exactly as the free courses left it, and the test environment changes instead: a real browser, a real engine, a real worker, running the real code.
What you get for five dollars
Forty-four tests across two runners, and the reasoning behind each choice.
Thirty-eight run in Vitest browser mode against a live DuckDB compiled to
WebAssembly; six run in Playwright against the built application, because the
wasm and worker asset pipeline only exists after vite build.
Every lesson ends at an annotated tag in the same public companion repository
the free courses use — tests-01 through tests-07. The code is public; these
lessons are what you are buying.
The five problems this solves
- You cannot assert on random data. The seeder uses
Math.random(), so there is nothing stable to check. Lesson 2 makes the dataset a fixture with a seedable PRNG behind an optional parameter, without changing how the app behaves. - A 150 ms debounce makes a slow test suite. Lesson 5 replaces the clock instead, and proves that eight rapid changes produce exactly one query.
- A race condition is invisible when everything is fast. The same lesson holds two requests open by hand and forces the older one to return second, which is the only way to prove the staleness guard actually guards.
document.querySelectorcannot see into a shadow root. Lesson 6 mounts components, awaitsupdateComplete, and asserts on the shadow tree — including the accessibility work that has no visual signal.- “It persists across a reload” cannot be tested in an iframe. Lesson 7 is Playwright, reloading the page and checking that the OPFS database restores rather than reseeds.
The lesson that catches the most bugs
Lesson 5 is the one to read first if you only read one. The query runner’s two guarantees — collapse a burst into one query, never render a superseded result — are pure control flow, and both are the kind of thing that works in development and fails under a slow network in front of a user.
Testing them against a real database would measure DuckDB. So the database gets mocked, the clock gets replaced, and two requests are held open deliberately so the older one can be released second. The test then asserts the thing you actually care about: the newer result survives, and the superseded request does not clear a pending flag it no longer owns.
That is six tests and about a hundred and thirty lines. It is the highest value-per-line in the suite.
Honest about the cost
Browser mode is slower than jsdom and downloads a Chromium. The full suite runs in well under a minute on a laptop, but it is not the millisecond feedback loop of pure unit tests, and lesson 1 says so before you commit to it.
Two runners also means two file conventions that collide by default — installing Playwright made Vitest try to run the end-to-end spec, which fails in a way that looks nothing like its cause. The fix is one line, and it is in the course because it cost real time to diagnose.
Where this sits
The two free courses — SQL in the Browser and A Reactive Dashboard — build the application across twenty lessons. This one adds the suite they deliberately ship without, so the difference between untested and tested code is a diff you can read rather than a claim.
