feat: docs composites cycle 1 — testing + ThemeProvider, Breadcrumbs, PageFooterNav#1
Merged
Merged
Conversation
…r/Breadcrumbs/PageFooterNav) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Stories run as tests in real Chromium via @storybook/addon-vitest (Vitest 4 browser mode, Playwright). Adds vitest.config.ts, a test task (turbo + root), and a reusable check.test.yml wired into on.pr.yml/on.push.yml. 21 story tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Context that sets .dark + data-theme on <html> (so Base UI portals inherit it), persists to localStorage, and initializes from stored value or prefers-color-scheme. useTheme() → { theme, setTheme, toggle }. Story with a play test asserting the toggle flips the documentElement class. Adds storybook + @storybook/addon-vitest to @elide/ui devDeps so colocated stories' runtime test imports resolve.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Docs breadcrumb trail: nav > ol, chevron separators, links for segments with href, final segment aria-current=page. Story + play test asserting aria-current and link href. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Prev/next docs pagination cards; either side optional, lone next stays right-aligned. Stories (Both, NextOnly) with play tests asserting hrefs and the absent-prev case. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… testing Registers the addon (serves the MCP endpoint at :6006/mcp when Storybook dev runs) and adds the storybook HTTP MCP server to .mcp.json. Enables run-story-tests to fetch/diagnose failing stories. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ThemeProvider Toggle play test was coupled to the Storybook theme decorator's initial <html> class, which diverged from the provider's own state — failing nondeterministically in Chromatic (light+dark modes). Rewrites it to assert against the provider's reported theme with waitFor. Also fixes a11y violations surfaced via the Storybook MCP run-story-tests: CopyButton empty aria-label (fallback to 'Copy' + regression play test), Popover dialog accessible name, and Switch accessible name. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces Storybook-driven interaction testing (Vitest browser mode via Playwright) and ships the first “docs-shell composite” UI components for the docs experience: ThemeProvider/useTheme, Breadcrumbs, and PageFooterNav.
Changes:
- Added a
testTurbo pipeline + roottestscript and a reusable GitHub Actions workflow to run storyplayfunctions as browser tests. - Implemented and exported
ThemeProvider/useTheme,Breadcrumbs, andPageFooterNav, each with Storybook stories that include interaction assertions. - Tightened accessibility guardrails in stories/components (e.g.,
aria-labeldefaults and story args).
Reviewed changes
Copilot reviewed 24 out of 25 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| turbo.json | Adds a test Turbo task to run the new story-based test suite. |
| package.json | Adds root test script (turbo run test). |
| apps/storybook/package.json | Adds Vitest/Playwright deps and vitest run test script for story execution. |
| apps/storybook/vitest.config.ts | Configures Vitest browser mode + Storybook Vitest plugin to run stories as tests. |
| apps/storybook/.storybook/main.ts | Registers @storybook/addon-vitest (and MCP addon) in Storybook config. |
| .github/workflows/check.test.yml | New reusable workflow to install Chromium + run bun run test. |
| .github/workflows/on.pr.yml | Wires the reusable test workflow into PR CI. |
| .github/workflows/on.push.yml | Wires the reusable test workflow into push CI. |
| packages/ui/src/components/theme-provider.tsx | Introduces theme context/provider that reflects theme onto <html> and persists it. |
| packages/ui/src/stories/Theme.stories.tsx | Adds ThemeProvider story with play interaction test verifying toggle behavior. |
| packages/ui/src/components/breadcrumbs.tsx | Adds Breadcrumbs composite with aria-current="page" on final segment. |
| packages/ui/src/stories/Breadcrumbs.stories.tsx | Adds Breadcrumbs story + play assertions (links + current segment). |
| packages/ui/src/components/page-footer-nav.tsx | Adds PageFooterNav composite for prev/next navigation cards. |
| packages/ui/src/stories/PageFooterNav.stories.tsx | Adds PageFooterNav stories + play assertions for both/next-only cases. |
| packages/ui/src/components/code-block.tsx | Ensures CopyButton has a non-empty accessible name fallback. |
| packages/ui/src/stories/CodeBlock.stories.tsx | Adds a regression play test for CopyButton accessible name. |
| packages/ui/src/stories/Switch.stories.tsx | Sets a default aria-label arg for Switch stories. |
| packages/ui/src/stories/Popover.stories.tsx | Adds aria-label to PopoverContent in the story for accessibility. |
| packages/ui/src/index.ts | Exports the new composites (ThemeProvider, Breadcrumbs, PageFooterNav). |
| packages/ui/package.json | Adds Storybook-related devDependencies for the UI package. |
| COMPONENTS.md | Marks ThemeProvider/Breadcrumbs/PageFooterNav as done. |
| docs/superpowers/specs/2026-07-06-docs-composites-design.md | Adds the design spec documenting goals, APIs, and DoD for cycle 1. |
| docs/superpowers/plans/2026-07-06-docs-composites.md | Adds an implementation plan detailing the test infra + component work. |
| .mcp.json | Adds a local Storybook MCP endpoint configuration. |
| bun.lock | Locks new Storybook/Vitest/Playwright dependency additions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The previous fix addressed the assertion but not the root cause: ThemeProvider resolved its theme in a mount useEffect, which in Chromatic's timing ran AFTER the play function's click and reverted the toggle (button stayed 'Theme: dark'). Move resolution into a lazy useState initializer (SSR-guarded) and drop the init effect, so the theme is set synchronously and nothing re-initializes over an early interaction. Test now asserts the exact toggled value. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…sed devDep 1) resolveInitialTheme now honors the OS preference in both directions (light stays light), falling back to defaultTheme only when matchMedia is unavailable — the previous code left an OS-light user on the dark default, contradicting the docstring. 2) Remove @storybook/addon-vitest from @elide/ui devDependencies. The suite still passes: the storybookTest plugin's injected @storybook/addon-vitest/internal/test-utils import resolves from apps/storybook (the Vitest root), not packages/ui. (storybook stays — the source `storybook/test` import resolves from packages/ui.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Summary
Stands up component testing and ships the first docs-shell composites. Cycle 1 of the Tier-2 composites (Sidebar / AppNav / SectionTabs / TableOfContents follow in later PRs).
Testing (new)
playfunction. Complements Chromatic (visual) without duplicating it.apps/storybook/vitest.config.ts,@storybook/addon-vitestregistered, atesttask (Turbo + root).check.test.yml(installs Chromium, runs the suite) wired intoon.pr.yml/on.push.yml.Composites (themed from
@elide/tokens, each with aplaytest + visual diff vs the mockup)ThemeProvider/useTheme— sets.dark+data-themeon<html>(so Base UI portals inherit it), persists tolocalStorage, initializes from stored value orprefers-color-scheme.Breadcrumbs—segments[], chevron separators, final segmentaria-current="page".PageFooterNav— prev/next cards; either side optional, lonenextstays right-aligned.Verification
bun run build,bun run lint,bun run testall green from a cold cache;actionlintclean.Notes
chromaticCI job needs theCHROMATIC_PROJECT_TOKENsecret (unrelated to these Vitest tests, which need no secret).Sidebar,AppNav,SectionTabs,TableOfContents.🤖 Generated with Claude Code