Testing
The Boring JavaScript Stack now has one primary testing story: Sounding.
Sounding keeps the familiar test() API, but gives Sails apps one coherent runtime for:
- helper and business-logic trials
- JSON endpoint and policy behavior
- Inertia page contracts
- mail assertions
- browser-capable flows when the browser truly matters
When to Use
Use this skill when:
- Writing or restructuring tests in a Sails.js + Inertia.js application
- Migrating older
node:test, Playwright, or inertia-sails/test suites to Sounding
- Designing
tests/unit, tests/e2e/pages, tests/factories, and tests/scenarios
- Configuring
config/sounding.js and config/env/test.js
- Writing trials around
sails.helpers, get() / post(), visit(), auth, login, mailbox, or page
- Choosing between virtual transport and real HTTP transport
- Keeping mail capture, datastore isolation, and browser setup calm and predictable
- Setting up CI around a Sounding-powered suite
Sounding Mental Model
Keep these terms straight and use them consistently:
- a trial is one named behavior the app must prove
- the trial context is the object Sounding passes into
test()
sails is the canonical center of that context
- a world is the named business situation the trial lives inside
- an actor is the role operating through that world
- a suite is the whole organized test tree for the app
Prefer Sounding's public shape:
const { test } = require('sounding')
test('...', async ({ sails, get, visit, auth, login, page, expect }) => {})
sails.helpers.*
sails.sounding.*
Do not push people back toward:
- ad hoc
getSails() boot helpers
inertia-sails/test as the main integration story
- Playwright for every request-level behavior
tests/sounding/ as a framework-branded island
Rules
Read the rule files that match the work you are doing:
- rules/getting-started.md - Sounding philosophy, suite layout, scripts, and migration mindset
- rules/unit-testing.md - helper trials, pure business logic, worlds, factories, and scenarios
- rules/integration-testing.md - request-level JSON and Inertia trials with
get(), post(), and visit()
- rules/e2e-testing.md - browser-capable trials with
{ browser: true }, page, login, and mobile-aware flows
- rules/test-configuration.md -
config/sounding.js, config/env/test.js, datastores, mail capture, cleanup, and CI
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: sailscastshq-boring-stack-testing3description: Testing4---56# Testing78The Boring JavaScript Stack now has one primary testing story: **Sounding**.910Sounding keeps the familiar `test()` API, but gives Sails apps one coherent runtime for:1112- helper and business-logic trials13- JSON endpoint and policy behavior14- Inertia page contracts15- mail assertions16- browser-capable flows when the browser truly matters1718## When to Use1920Use this skill when:2122- Writing or restructuring tests in a Sails.js + Inertia.js application23- Migrating older `node:test`, Playwright, or `inertia-sails/test` suites to Sounding24- Designing `tests/unit`, `tests/e2e/pages`, `tests/factories`, and `tests/scenarios`25- Configuring `config/sounding.js` and `config/env/test.js`26- Writing trials around `sails.helpers`, `get()` / `post()`, `visit()`, `auth`, `login`, `mailbox`, or `page`27- Choosing between virtual transport and real HTTP transport28- Keeping mail capture, datastore isolation, and browser setup calm and predictable29- Setting up CI around a Sounding-powered suite3031## Sounding Mental Model3233Keep these terms straight and use them consistently:3435- a **trial** is one named behavior the app must prove36- the **trial context** is the object Sounding passes into `test()`37- `sails` is the canonical center of that context38- a **world** is the named business situation the trial lives inside39- an **actor** is the role operating through that world40- a **suite** is the whole organized test tree for the app4142Prefer Sounding's public shape:4344- `const { test } = require('sounding')`45- `test('...', async ({ sails, get, visit, auth, login, page, expect }) => {})`46- `sails.helpers.*`47- `sails.sounding.*`4849Do not push people back toward:5051- ad hoc `getSails()` boot helpers52- `inertia-sails/test` as the main integration story53- Playwright for every request-level behavior54- `tests/sounding/` as a framework-branded island5556## Rules5758Read the rule files that match the work you are doing:5960- [rules/getting-started.md](rules/getting-started.md) - Sounding philosophy, suite layout, scripts, and migration mindset61- [rules/unit-testing.md](rules/unit-testing.md) - helper trials, pure business logic, worlds, factories, and scenarios62- [rules/integration-testing.md](rules/integration-testing.md) - request-level JSON and Inertia trials with `get()`, `post()`, and `visit()`63- [rules/e2e-testing.md](rules/e2e-testing.md) - browser-capable trials with `{ browser: true }`, `page`, `login`, and mobile-aware flows64- [rules/test-configuration.md](rules/test-configuration.md) - `config/sounding.js`, `config/env/test.js`, datastores, mail capture, cleanup, and CI6566---67> Converted and distributed by [TomeVault](https://tomevault.io/claim/sailscastshq) — claim your Tome and manage your conversions.68<!-- tomevault:4.0:skill_md:2026-04-11 -->