feat: Storybook coverage — bucket 1 + layout chrome (#749) - #779
Merged
Conversation
Adds stories for the pure, prop-driven component gaps identified in #749: PlayerItemList, List/Li, Achievements, ModeSwitcher, EntitySearchInput, TutorialModal, WaitlistForm, StaticBanner, BackToTopButton, ToastManager. Also adds the minimal decorator infra these turned out to need: - withQueryClient (global): a fresh, retry-off QueryClient per story, for components that call TanStack Query hooks directly or transitively (EntitySearchInput, TutorialModal both do, despite being listed as context-free in the issue's audit). - withGameContext + testUtils/mockGameContext: a minimal GameContext mock for EntitySearchInput's indirect useGame() dependency (via useFeatureFlag). ActivityInput was left out of this batch - it now pulls in useGame, useSupportFlow, useFeatureFlag and timer state, which is bucket-2/3-level complexity, not the "prop-driven, no context" component the issue described.
Stories Navbar, NavDrawer, Footer, and Infobar - the layout chrome called out as bucket 3 in #749, step 4 of its suggested approach. - Split AuthContext's raw context into context/authContext.ts, mirroring the existing GameContext.tsx/gameContext.ts split, so it can be mounted directly in stories without pulling in AuthProvider's real bootstrap/fetch logic. - Add testUtils/mockAuthContext.ts (mockAuthContextValue({authenticated, ...overrides})) and .storybook/decorators/withAuthContext.tsx, following bucket-1's conventions. - Navbar.stories.tsx: LoggedOut, LoggedIn, WithAnnouncements (play test opens the popover), WithMapEnabled - wrapped in MemoryRouter + a seeded QueryClient (appConfig, announcements) + mock AuthContext/GameContext. - NavDrawer.stories.tsx: LoggedIn (play test clicks close, asserts onClose fires), LoggedOut, WithMapEnabled, Closed. - Footer.stories.tsx: LoggedOut (play test asserts no Admin Panel link), LoggedIn, StaffUser (play test asserts the link appears). - Infobar.stories.tsx: Default (play test asserts name/level), PremiumPlayer, Loading, NoPlayer (renders null). Verified via eslint, tsc --noEmit, and storybook build (all clean), plus vitest on AuthContext.test.tsx and the Navbar/NavDrawer unit tests (24 passing) to confirm the context split didn't break anything. test:storybook (Playwright-driven play functions/a11y) still can't run in this sandbox - no sudo for Chromium's system deps - run locally/CI before merging. Remaining gap per #749: bucket 2 (data-fetching panels - Categories/ Projects/Skills/Tasks/ActivitiesPanel, ComingSoonPanel, NotesPanel, DetailSurface, SupportFlow screens, UnifiedTimerHome, ActivityTimeline, CurrentActivity, CharacterCurrentActivity) and the deferred ActivityInput. Per the issue's own plan, step 5 is to revisit whether those need separate stories given PlayerItemList's existing coverage. Co-Authored-By: Claude Sonnet 5 <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
Implements the first two stages of #749's suggested approach:
PlayerItemList,List/Li,Achievements,ModeSwitcher,EntitySearchInput,TutorialModal,WaitlistForm,StaticBanner,BackToTopButton,ToastManager.Navbar,NavDrawer,Footer,Infobar.ActivityInputwas deliberately excluded from bucket 1 — it depends onuseGame(),useSupportFlow,useFeatureFlag,useEntitySearchCache, live timer state,sessionStorage,AlertDialog, andSupportFlowModal, far more than the issue's "prop-driven, no context" characterization suggested.Infra added
.storybook/preview.tsx: globalwithQueryClientdecorator (fresh, retry-disabledQueryClientper story) so any TanStack Query hook — direct or transitive — doesn't crash.context/gameContext.ts/context/authContext.ts: raw contexts extracted fromGameContext.tsx/AuthContext.tsx(the latter split as part of this PR, mirroring the former) so stories can mount<Context.Provider>directly without the real providers' bootstrap/fetch logic.testUtils/mockGameContext.ts,testUtils/mockAuthContext.ts: minimal mock values satisfying each context's full interface..storybook/decorators/withGameContext.tsx,withAuthContext.tsx: reusable decorators built on the mocks above.Per-story decorators seed exact TanStack Query cache keys (
queryClient.setQueryData(...)) to control loading/empty/populated states without hitting the real API.Verification
npx eslint— clean on all new/changed files.npx tsc --noEmit— clean.npx storybook build— compiles all story files without errors.npx vitest run— existing unit tests forAuthContext,Navbar,NavDrawer(24 tests) still pass after the context split.test:storybook(Playwright-driven play functions + a11y checks) — this sandbox has no sudo to install Chromium's system deps. Should be run locally/CI before merging.Remaining gap (per #749)
Bucket 2 — data-fetching panels (
CategoriesPanel,ProjectsPanel,SkillsPanel,TasksPanel,ActivitiesPanel,ComingSoonPanel,NotesPanel,DetailSurface,SupportFlowscreens,UnifiedTimerHome,ActivityTimeline,CurrentActivity,CharacterCurrentActivity) — andActivityInput. Per the issue's own plan (step 5), worth revisiting whether these need their own stories givenPlayerItemList's existing coverage, as a follow-up.🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com