test: cover hero and projects carousel scripts with a stub-DOM self-test - #79
Conversation
Extracts the [data-hero-carousel] and [data-carousel] inline scripts from index.html and runs them against a dependency-free stub DOM with deterministic timers: dot generation, slide/aria-current state, live-region text, keyboard/swipe/hash navigation, auto-rotate and every pause condition, hero height measurement (clones, resize debounce) and projects scroll-sync (debounced scroll, scrollend, IntersectionObserver). Refs #78 (the links.yml wiring line is left for a human; see the issue) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: quality <quality@hive.kubestellar.io>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Read the diff against main and ran it: node --test scripts/carousels.test.mjs → 36 pass / 0 fail on Node 26. Script extraction (scripts/carousels.test.mjs:29, :243, :549) pulls the [data-hero-carousel] and [data-carousel] blocks verbatim from index.html, matching the pattern story-dialog.test.mjs:18 already uses; the markup-contract assertions (:269-280, :575-588) hold against the current page. README entry matches what the file does. Looks correct to me.
One action for a maintainer, not a defect in this diff: .github/workflows/links.yml:68 enumerates test files explicitly and this PR does not add carousels.test.mjs to it (the author's token tier cannot push under .github/workflows/, per the PR body). So on merge, this suite runs only when invoked by hand — the same situation #77 (7f1eaa8) fixed for the previous two suites. The one-line replacement is in #78 (run: node --test scripts/*.test.mjs, which also stops the list from drifting again). Suggest applying it in the same merge or immediately after, otherwise #78 should stay open as the tracker — which the body's Refs #78 already does correctly.
I have not approved or changed anything.
— hive: agent=reviewer backend=copilot model=claude-fable-5.1 copilot=1.0.88
Test Improvement
Adds
scripts/carousels.test.mjs— a zero-dependencynode --testsuite that extracts the hero carousel ([data-hero-carousel]) and projects carousel ([data-carousel]) scripts verbatim fromindex.htmland runs them against a stub DOM with deterministic timers, in the same style asacmm-levels.test.mjs. 36 tests covering:hidden inert); dot generation +aria-current; status text announcements; Arrow/Home/End (Tab left alone); touch swipe with mouse guard, 48 px threshold and vertical-gesture guard;#hero-*deep link +hashchange; 7 s auto-rotate; pauses for hover, focus-within, hidden tab, reduced motion (+ toggle);--hero-stage-h/--hero-hmeasurement via clones that dropid/inert, 80 ms resize debounce,fonts.readyre-measure; single-slide / no-dots no-op guards.<h3>+ link); tab dots named from trimmed<h3>text with positional fallback; roving tabindex +aria-current;scrollTosmooth vsauto; card focus withpreventScrolland plain-focus()fallback; keyboard on track and dots;focusinbrings a card into view without re-focusing; 6 s auto-advance and all pause conditions incl.visibilitychange; scroll-sync — 80 ms debouncedscroll, 450/80 ms programmatic-scroll suppression,scrollendfeature detection, IntersectionObserver options and most-visible-entry selection.README
Checkssection updated.Verification:
node --test scripts/*.test.mjs→ 116 pass / 0 fail (80 before). Mutation check againstindex.html: dropping the mouse-swipe guard, the vertical-swipe guard, the herofocusoutrelatedTargetcheck, the IOprogrammaticScrollguard, cloneremoveAttribute('id'), the resize debounce, thedocument.hiddenrotate guard,preventScroll, or the dots' roving tabindex each fails the suite.scripts/check-links.shstill clean.Observation, not changed here: in the hero script a user navigation sets
aria-live="polite"and the status text, thenrestart()synchronously flipsaria-liveback to"off"while auto-rotation is active — screen readers may swallow the announcement. The suite asserts the text only (andpoliteunder reduced motion, where no restart occurs) so it does not lock either behaviour in.Refs #78 (needs-human: wiring this file into the
testjob of.github/workflows/links.yml— exact one-line replacement in the issue — is under.github/workflows/, which this agent's token tier cannot push; until then the file runs only when invoked by hand)Filed by quality agent (ACMM L4/L6 — full mode)
— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88