Spark hardening: cart test harness, skip-to-content link, cart aria-live announcements - #27
Merged
Conversation
Plain-Node tests (CI pattern: node tests/js/*.test.js) covering the previously untested cart modules: SparkCartClient (mocked GraphQL, quantity/subscription edge cases, CSRF/429 retry, expired-cart recovery, event dispatch), SparkCartRewards (gift state transitions, upsell visibility), spark-progress-bar (shipping/gift threshold events), and spark-cart-drawer (open/close/render). Built by Codex CLI under the Fable-Codex build loop; no source files modified. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Public data-value attribute path for progress-bar transitions, drawer template contract assertions, quantity edge characterizations (zero coercion, MAX_QTY_PER_LINE not enforced client-side), retry-path status handling, 5000ms timeout/abort contract, duplicate gift line lookup. 19 -> 28 tests; test-only change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Visually hidden 'Skip to main content' link as the first focusable element in base.html, revealed on focus per the standard skip-link pattern; main gains id=main-content and tabindex=-1 as the jump target. Localized via en.default.json. Compiled main.css rebuilt and committed (sass-compat check passes). Source-order, target, and compiled-CSS drift assertions in tests/js/skip-to-content.test.js. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
templates/index.html overrides content_wrapper with its own main, so the homepage skip link had no target; it now carries id=main-content and tabindex=-1, with a test scanning all templates so future overrides fail the suite. Adds a data-light-primary dark-text override for the focused skip link and asserts the compiled CSS clipping/reveal declarations, not just the selector. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds global.accessibility.skip_to_main_content to all 10 non-English locales (locale-shape contract; Python suite green again) and gives the account-only partial's outer container the #main-content target so the skip link works when settings.account_only is on. Test scan extended to cover the account-only branch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mid-luminance brand primaries (e.g. #FFB900) defeat both the white default and the data-light-primary dark override, so the focused skip link now uses fixed neutral colors (white on slate-800) instead of var(--primary-color). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds a visually hidden role=status aria-live=polite region to the cart drawer, announcing on spark:cart:updated actions: 'remove' and 'update' get localized messages (SparkI18n.cartItemRemoved / cartQuantityUpdated, wired through base.html and all 11 locales), other actions clear stale text. Clear-then-set so repeated identical announcements re-fire. Covered by tests/js/spark-cart-drawer-announce.test.js. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Synchronous clear-then-set can be coalesced into one accessibility- tree update, so identical consecutive announcements would not re-fire in many screen readers. The message is now set via a 0ms-deferred task (cancelled on newer announcements and on disconnect), with a repeat-announcement test using deferrable fake timers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
next-devin
marked this pull request as ready for review
July 12, 2026 15:51
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Re-review of commit All four findings from the previous review at commit
The Files Reviewed (incremental)
Notes
Previous Review Summary (commit 8c1456d)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 8c1456d)Status: 4 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (22 files)
Notes
Reviewed by minimax-m3 · Input: 51.9K · Output: 6.2K · Cached: 423.3K |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three bounded slices sharing one PR, built via the Fable → Codex build loop (Codex CLI built each phase; independent Codex reviews gated each slice).
1. JS test harness for the cart client stack
Plain-Node tests (existing CI pattern, no framework/deps) covering the previously untested modules:
SparkCartClient(mocked GraphQL, quantity/subscription edge cases, CSRF/429 retry, expired-cart recovery, timeout/abort contract, event dispatch),SparkCartRewards(gift state transitions, upsell visibility, duplicate gift lookup),spark-progress-bar(shipping/gift threshold events via the publicdata-valuepath),spark-cart-drawer(open/close/render + template contract assertions). 33 tests across five files.2. Skip-to-content accessibility link
Visually hidden "Skip to main content" link as the first focusable element in
base.html, revealed on focus, targeting#main-content(<main>in base + homepage override + account-only branch). Localized in all 11 locales. Focused style uses fixed neutral colors (white on slate-800, 14.63:1 contrast) because mid-luminance brand primaries defeat both white text and thedata-light-primaryoverride. Compiledmain.cssrebuilt and committed; source-order/target/compiled-drift tests included.3. Cart-drawer aria-live announcements
Polite
role="status"live region in the drawer shadow DOM announcing onspark:cart:updated—remove→ "Item removed from cart.",update→ "Cart quantity updated." — wired throughSparkI18nand all 11 locales. Repeated identical announcements re-fire via a 0ms-deferred set (cancelled on newer announcements/disconnect). Covered by 5 announcement tests including a repeat-announcement case with deferrable fake timers.Review trail
--xhighadversarial challenge found uncovered quantity/retry/gift edges, folded back in as characterization tests (19 → 28 tests).<main>override lacked the skip target; locale-shape contract broke the Python suite; account-only branch had no target; contrast edge) — all repaired and re-reviewed clear.The challenge also surfaced four latent gift-flow race conditions in existing source (duplicate gift add on threshold crossing, no reconciliation between threshold edges, unguarded in-flight gift mutations, stale gift flags after empty render). Source fixes are out of scope for this test-and-a11y PR and tracked as follow-up.
Verification
python3 -m unittest discover -s tests, everytests/js/*.test.jsunder Node 22,sass-compat --check.ntk push; compiled CSS matches source.🤖 Generated with Claude Code