Skip to content

Standard: Testing ​

Applies to ​

Every code change that enters the repository. This covers the backend (Rust), the page (JS, CSS, HTML), scripts, and workflows.

Not covered: changes to docs only (docs/, README, CHANGELOG). Tests do check the section format of CHANGELOG, so changing that format is covered.

Rules ​

  • When you change a behavior rule, first change the test that checks the rule, watch the changed test fail, and then change the code.
  • npm test (Rust unit tests and the page's Node tests) and npm run lint (rustfmt, clippy including warnings, Biome) pass. CI runs the same commands.
  • When you change a flow people see (buttons, windows, saving, agent integration), npm run test:e2e passes. When you add a new flow, add a check line to the scenario and the expected list in tests/e2e.mjs.
  • Pure rules (calculation, conversion, parsing) are split into functions that run without the page or the app and checked with unit tests (src/core/, src/yard/, scripts/*-lib.mjs, mod tests in each Rust module). In the yard these include the lake's shape (lakeShape, tests/lake.test.mjs), closeness (bondProgress, tests/bond.test.mjs), the hint line (hintKey, tests/hint.test.mjs), seasonal events (tests/events.test.mjs), the catalogue (tests/catalog.test.mjs), strolling (tests/wander.test.mjs) and the sound mix (tests/soundmix.test.mjs).
  • Rust test-only code goes only inside mod tests at the end of the file. Watch tests scan only up to that point.

What goes where.

What it checksWhereHow to run
Rust logicmod tests at the end of each .rs filenpm test
Pure page logic, style contracts, module rules, strings tablestests/*.test.mjsnpm test
The yard's content loaded the way the page loads it, for tests of rules that read ittests/support/content.mjs (import it before the module under test)npm test
Seasonal event dates, shared with the backend's content.rs test so the page and the backend agreetests/fixtures/event-dates.jsonnpm test
The page's limits and the backend's values kept equal (it reads the Rust source)tests/limits.test.mjsnpm test
Rules for generating release and distribution filestests/release.test.mjs, tests/distribute.test.mjsnpm test
The real app end to endtests/e2e.mjs, test pet in tests/support/fixture-pet.mjsnpm run test:e2e
Real responses from community sitesRust live_import (skipped by default)npm run test:live-import

E2E launches the release executable with an isolated data folder and runs the scenario script inside the app. Results come out as [e2e] name=value lines, and the harness compares them with the expected list and prints ✓/✖.

Recommendations ​

Follow these when you can. When you cannot, say why in the PR.

  • When you change Windows-only code (#[cfg(windows)]), confirm it compiles with npm run dist:windows. Compiling is not running: if you cannot run the app on Windows yourself, list anything that needs a run check in the PR description. On a Mac, you can check the installers in a Windows virtual machine (for example UTM on Apple silicon, with Windows 11 on Arm).
  • Check changes that touch Linux (cfg(unix), tray, overlay, file permissions) with npm run dist:linux. It builds in Docker and then runs E2E on Xvfb, so you can see Linux runs from a macOS machine.
  • For changes that affect performance, attach the measurements from the performance standard.

Exceptions ​

WhenHow
A flow that cannot have an E2E check line (OS dialogs, a real AI subscription, another OS)Write how you checked it by hand and the result in the PR description
E2E while the window is covered and WebKit has paused animationsThe harness skips checks that depend on walking and prints that it did. This is not a failure
An urgent fix with tests added laterA maintainer approves it, and an issue is left for adding the tests

Rationale ​

The page has no build step, and the app runs on three operating systems. Unit tests check the rules, guard tests check the strings and module structure, and E2E inside the app checks the real windows and backend. macOS has no WebDriver, so E2E runs inside the app. Based on: decision “Real-app E2E runs a scenario script inside the app”

Automated checks ​

.github/workflows/build.yml runs lint, unit tests, build, and E2E on every push to main and every PR, on macOS, Windows x64 and arm64, and Linux x64 and arm64 runners. Linux E2E runs on Xvfb. For the site, its site job runs npm run site:build, which catches dead links, and tests/website.test.mjs checks that every version in the changelog has a release page and that the screenshots a page points to exist.

Change history ​

  • 2026-10-01 First version — organized "The order for changing and checking" from CONTRIBUTING into rules
  • 2026-10-03 Added the site checks (tests/website.test.mjs, dead links) to the automated checks
  • 2026-10-10 Pure functions in src/yard/ are unit-tested too; the shared content loader, the event dates shared with Rust, and the limits test

Free and open source under the MIT license. Not affiliated with OpenAI; Codex is a trademark of OpenAI.