Skip to content

Bring CI onto the current template archetype and add unit tests#32

Merged
timdixon82 merged 1 commit into
mainfrom
sean/ci-archetype-and-tests
Jul 15, 2026
Merged

Bring CI onto the current template archetype and add unit tests#32
timdixon82 merged 1 commit into
mainfrom
sean/ci-archetype-and-tests

Conversation

@timdixon82

Copy link
Copy Markdown
Owner

Summary

  • Part 1 (archetype bring-up): declares .github/ci-archetype = static-app, replaces this repo's old scaffold-era workflows with the current merged template versions (ci.yml, lint.yml, accessibility.yml, security.yml, codeql.yml, deploy.yml), and adds .github/lint-tools/. .github/accessibility-tools/ was already current and left unchanged. Root pa11y.json was already customised (chromeLaunchConfig, ignore-list comments) and kept as-is.
  • Part 2 (unit tests): extracts the DOM-free core logic from clock-practice.js into a new module, clock-logic.js — random time generation, hand-angle math, time formatting, answer checking, hint text, and hour/minute value wrapping. index.html's script tag becomes type="module" so clock-practice.js can import from it. This was a SMALL extraction (pulling out already-separable pure functions), not a structural refactor.
  • Adds Vitest as a dev dependency and a test script (vitest run), matching the estate pattern used by Braille Reference and the Braille Name Generator.

Deploy allow-list (bundler-free repo)

Clock Practice has a package.json for lint tooling only, with no build script, so it falls into the template's BUNDLED job, which auto-falls-back to the allow-list assembly step when no dist/ is produced. This repo's runtime files (index.html, clock-practice.js, clock-logic.js, styles.css, favicon.svg) live at the repo root rather than in styles//scripts/ subfolders, so each is allow-listed by its own anchored include, alongside /assets/*** for the analytics script.

The template's default /scripts/*** and /data/*** includes were deliberately dropped: this repo's scripts/ folder holds internal developer tooling (next-q.sh, record-backport.sh, etc.), not runtime JavaScript, and including it would have published those scripts to the public site. Confirmed with a local rsync dry-run — _site/ contains exactly the six runtime files and nothing else (no node_modules, no internal scripts).

Test coverage

33 Vitest unit tests in tests/clock-logic.test.js, asserting against an independent reference (the standard analog-clock hand-angle formula, computed separately from handAngles, plus the game's own stated rules for correctness and value wrapping) rather than echoing the implementation:

  • randomTime: hour always an integer 1-12; minute always a multiple of five, 0-55; produces more than one distinct value over repeated sampling.
  • handAngles: matches the standard clock formula across a table of times including 12 o'clock, quarter past, half past, and near-midnight (11:55); explicit checks for the o'clock, half-past, and quarter-past cases.
  • formatTime: leading-zero minute padding, no hour padding, the o'clock case, and a two-digit minute.
  • isCorrectAnswer: accepts an exact match, rejects hour-only-wrong, minute-only-wrong, and both-wrong, and accepts 12:00 (noon/midnight representation).
  • getHint: all three hint branches (both wrong, hour wrong, minute wrong).
  • wrapHour/wrapMinute: normal increment/decrement plus both wrap-around directions (12->1, 1->12, 55->0, 0->55).

Accessibility regression suite (docs/patterns/accessibility-regression-suite.md)

Ran the static front-end suite's automated checks and inspected the checked-out HTML for the manual entries. Found and fixed two pre-existing defects (present before this PR, unrelated to the extraction) while bringing the honest accessibility gate online:

  • S-08 (assertive live region for non-urgent feedback): #feedback carried both role="status" and an explicit aria-live="assertive" override. Removed the explicit aria-live, leaving role="status" alone (implies polite), matching the suite's fixed pattern.
  • S-09 (missing landmark structure): no <main> or <header> element existed. Wrapped the <h1> in <header> and the game content in <main>.
  • S-06 (ESLint glob coverage): confirmed both clock-practice.js and clock-logic.js return a non-empty --print-config output; lint:js now covers both files plus tests/.
  • S-03 (ARIA grid rows) and S-11 (form input border contrast): not applicable — no grid or form inputs in this project.
  • S-10 (focus ring contrast): unchanged by this PR; not re-verified here as it is outside the scope of this bring-up.
  • S-01, S-02, S-04, S-05, S-07, S-12: not applicable to this project (no filtering, no colour-scheme change, emoji already wrapped in aria-hidden, no modal).

Checks run locally

  • npm ci — clean.
  • npm test (Vitest) — 33/33 passing.
  • npm run build --if-present — no-op as expected (bundler-free); no dist/ produced.
  • npm run lint (html-validate, stylelint, eslint) — clean.
  • Pa11y (--config pa11y.json) against the served repo root — 0 issues, both before and after the S-08/S-09 fixes.
  • axe-core CLI (--tags wcag2a,wcag2aa,wcag2aaa,wcag22aa,wcag22aaa --exit) against the same URL — 0 violations, both before and after the fixes.
  • Manual smoke test via a headless Selenium/chromedriver session: page loads the ES module script with no console errors, the hour spinbutton wraps 12 -> 1 on increment (wrapHour), and Check My Answer renders live feedback correctly.
  • Local rsync dry-run of the deploy allow-list: _site/ contains exactly index.html, clock-practice.js, clock-logic.js, styles.css, favicon.svg, and assets/analytics/count.js — no node_modules, no internal tooling scripts.

No design-level accessibility blockers found; nothing to route to Simon.

No secrets or personal data included.

…ore logic

Declares this repo's static-app archetype, replaces the old scaffold-era
workflows with the current merged CI/lint/accessibility/security/CodeQL/
deploy templates, and extracts the DOM-free clock logic (random time
generation, hand-angle math, answer checking, hint text, value wrapping)
into clock-logic.js so it can be unit tested with Vitest independently of
the browser.

Also fixes two accessibility regression suite defects found already
present in index.html while bringing the accessibility gate up: an
assertive aria-live override on the polite feedback region (S-08), and a
missing main landmark (S-09). Narrows the bundler-free deploy allow-list to
this project's actual runtime files, since the template's default
/scripts/*** and /data/*** includes would otherwise publish this repo's
internal developer tooling scripts to the public site.
@timdixon82 timdixon82 merged commit 1b5c0e8 into main Jul 15, 2026
6 checks passed
@timdixon82 timdixon82 deleted the sean/ci-archetype-and-tests branch July 15, 2026 06:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant