EN FR

Chapter 18Operate

Checks and tests

Four checks that block the branch, and a test suite that calls the routes for real. What each one catches, and why it exists.

4 min read11 sectionsChapter 18 / 22

Two commands

bash bash
npm run check    # four checks on the built site
npm test         # the full suite, which builds along the way

These are exactly the ones CI runs, and they block the branch. A check that does not block gets bypassed, then disabled, then removed.

The four checks

check-html — is the content in the raw HTML?

This is the project's safety net. It verifies three things on the actually built HTML:

  1. every text value from the JSON is present in the HTML source;
  2. every data-cms in the HTML points at a key that exists in the JSON;
  3. no editable zone sits inside a hydrated island.
CheckWhat it catches
1client:only — the content is in no served HTML, therefore in no index.
2A stale path after a key was renamed.
3client:load around an editable zone — the framework re-renders it on load and wipes the client's edits in progress. Invisible in the source.
A list to keep up to date

The script enumerates the pages to check explicitly, one entry per page and per language. Adding a page or a language without completing that list leaves a check that passes while verifying nothing.

scripts/check-html.mjs js
const PAGES = [
  { content: 'src/content/pages/fr/home.json', html: 'dist/fr/index.html' },
  { content: 'src/content/pages/en/home.json', html: 'dist/en/index.html' },
];

check-locales — do the languages say the same thing?

Fails on any key present in one language and absent from another, in both directions: a translated key that does not exist in the reference language would never be displayed, and that is wasted work better seen straight away.

check-logs — can a secret leak through a log?

Refuses a console.* that would evaluate a token, a hash, a cookie, a session, or an object containing them (env, headers, payload).

Accepted

js js
console.error('[save] write failed (key missing)');
console.warn('[auth] rate exceeded');

Strings are removed before analysis: a message mentioning “key” is not a leak.

Refused

js js
console.error(key);
console.log(env);
console.error(error);   // may contain an API response

That is the line added six months later to debug, and forgotten afterwards.

check-secrets — does the build contain a secret?

Scans the build folder for hashes, tokens and secret patterns. It does not replace the “no secret in the repository” rule: it verifies no accident bypassed it — an exposed build variable, a value copied into a component.

The test suite

CommandWhat it exercises
npm run test:gitThe Git provider: read, write, conflict, error translation. Offline by default, real with --online.
npm run test:authHashing, constant-time comparison, session signature and lifetime, cookies.
npm run test:guardRate, caps, paths, and the order of checks — by calling the routes directly.
npm run test:sanitizeThe same corpus submitted to both sanitisers — browser and server — and compared.
npm run test:mediaFormat recognition from the bytes, dimension reading, name rewriting.
npm run test:heicHEIC recognition; decoding is skipped for lack of a sample, unless INLINE_HEIC_SAMPLE is provided.
npm run test:bootstrapBootstrapping on a versioned annotated page, refusals included.
npm run test:localesThe translation fallback and the marking of untranslated fields.
npm run test:editorOverlay logic: path resolution, item reconciliation, drafts.
npm run test:scaffoldA site created from scratch, installed, built, checked.
Why test:guard calls the routes

A size cap placed after reading the body protects nothing, and an identity check placed before rate counting lets the route be hammered. Testing rules in isolation says nothing about their order: hence a test that goes through the real routes.

Testing what would ship to a registry

Two commands answering different questions.

npm run test:scaffold

Does the code work? Creates a site, installs the package by its path in the repository, builds, checks.

npm run test:pack

Does what would ship to the registry work? Same thing, but through npm pack: the exact archives a publication would produce.

The second is the only mode that catches a file forgotten in files or a path missing from exports — errors invisible while installing from a folder, and which break the first third-party site. Run it before any publication.

In continuous integration

The shipped workflow runs npm test then npm run check, on every push and every merge request. No secret is needed: the checks touch neither the content repository nor the write token — they build the site and inspect it.

The reference repository adds a second job, kept separate because it installs a fresh project and takes a few minutes: without it, the template embedded in create-inline diverges silently from the reference repository, and you only find out with the next client.

Adding a check

A useful check has three properties:

  1. it blocks — otherwise it only provides comfort;
  2. it examines the result, not the intent: the built HTML, the build folder, a route's response;
  3. it fails with a message that says what to do, not merely what is wrong.

A site-specific check goes in scripts/ and is added to check. A check that would hold for every client goes into the package — and becomes a versioned change.

Before every commit

bash bash
npm test && npm run check

Two minutes. That is the price of a fix found before the merge rather than after it goes live at a client's.