Skip to content

feat(storybook): phase-2 storybook coverage + browser visual baseline - #18

Merged
Chilfish merged 12 commits into
mainfrom
feat/storybook-tweet
Aug 20, 2026
Merged

Chilfish merged 12 commits into
mainfrom
feat/storybook-tweet

Conversation

@Chilfish

Copy link
Copy Markdown
Owner

Summary

阶段二主线(review-2026-08-19 P1-1~P1-3 + 所有者裁定):tweet 目录 Storybook 全覆盖 + 视觉验证 + addon-vitest 浏览器测试 + AC-UI 门禁。UI 从「口说还原官方」变为「可验证还原」。

变更(原子提交)

组件/重构

  • refactor(tweet):TrendingCard.tsx 自 TweetCard 拆出 + index.ts barrel(P2-1);主图 alt 去重复朗读(a11y,P1-2);媒体三态统一(P2-2);移除 JS 截断改 CSS clamp(P3-1);trending 分支提前 + 官方 1.91:1 比例(P3-2)

测试

  • test(tweet):card-render.spec.ts AC-CARD-005~008 真实 renderToString 断言(trending 结构 / 回退普通卡 / 缺图不塌陷 / 无卡空渲染);AC-card.md v1.1 验证方法如实化

Storybook 全覆盖

  • tweet 14 组件 stories(TweetCard 五态 / TrendingCard / Header / TextBody / MediaAlt / OptionsMenu / PlainTweet / Node / SelectableWrapper / InputForm / CommentBranch / ThreadLine / FilterToggle / AIVisionBlock)
  • ins 8 个缺失组件 + translation 在用 10 组件 + settings 4 组件 + ui 22 在用原语

视觉基线基建

  • feat(verify):AC-UI-VISION-001(每组件 ≥1 story)+ AC-UI-A11Y-001(a11y 配置 + 已知违规修复);build-storybook 入 pre-push
  • chore(storybook):addon-vitest 接线 —— @vitest/browser + @vitest/browser-playwright + chromium;vitest.config 新增 storybook 项目;bun run test:storybook(真实 Chromium 渲染 + axe)
  • ci:verify/index.ts scoped 到 unit/acceptance/integration(排除浏览器项目);pre-push/CI 移除与 verify 重复的 bun run test 步骤

Verification

  • bun run test:storybook:28 files / 137 tests(真实 Chromium)
  • bun run verify/index.ts --exit-on-fail:287 passed / 4 skipped
  • bun run test:280/280
  • bunx eslint . / bun run typecheck:0 错
  • bun run build-storybook:0 报错

说明

Storybook 浏览器测试为开发侧可视化基线(不进 CI/Vercel,避免 chromium 安装);Vercel 部署流程不受影响(无 test/storybook 任务、新依赖为 devDeps、产出已 gitignore)。

- add review-2026-08-19-tweetcard-storybook-critique.md (P1 x3, P2 x2, P3 x2)
- backlog: phase-2 main line = component storybook coverage + visual baseline;
  owner rulings: external-link disclaimer dropped, jetfuel fallback driven by user feedback
- code-style: mandatory storybook story for every used component
- git-workflow: PR checklist requires story + build-storybook for UI changes
P2-1 (review-2026-08-19): 14-file tweet dir lacked a barrel index;
split TrendingCardView out of TweetCard.tsx into TrendingCard.tsx.

- add app/components/tweet/index.ts exporting all 14 components
- TrendingCard: main image alt empty (decorative, h3 carries accessible name),
  avatars switch to MediaImage (loading/error placeholder, P2-2),
  fix category key duplicates and postsCount spacing (P3-2)
- TweetCard: drop JS truncateText in favor of CSS line-clamp + title attr (P3-1),
  remove CardImage self-managed error collapse (MediaImage fallback instead),
  move trending branch ahead of the empty-card early return (P3-2),
  large-image cards use official 1.91:1 ratio
- ac-card AC-CARD-005: source checks now span TweetCard + TrendingCard
review P1-1/P1-3 (2026-08-19): AC-CARD-005 claimed snapshot/storybook
verification but was a source string scan; the trending card had zero
component-level behavior lock-in and the jetfuel fallback path was untested.

- add test/acceptance/card-render.spec.ts (AC-CARD-005~008):
  renderToString + HTML assertions for the trending variant, the normal
  card fallback, the missing-image no-collapse path, and the empty render
- ac-card.spec.ts: downgrade old source scan to helper AC-CARD-009, with
  source checks spanning TweetCard.tsx + TrendingCard.tsx after the P2-1 split
- AC-card.md v1.1: document the honest render-based verification methods
Phase-2 main line (review-2026-08-19 P1-2): tweet directory components
previously had zero stories; product claim of official-render fidelity had
no visual evidence. Scenario matrix per component: default/loading/error/empty
plus official fixture inputs and product-specific states.

- add app/stories/tweet.fixtures.ts: shared EnrichedTweet fixtures sourced
  from real test fixtures (trending jetfuel payload, card, vision photos,
  translation entities) for component stories
- add app/stories/story.store.tsx: WithStoreState helper to seed zustand
  stores post-mount for state-dependent stories
- stories: TweetCard (5 states), TrendingCard, TweetHeader, TweetTextBody,
  TweetMediaAlt, TweetOptionsMenu, PlainTweet (MyPlainTweet), TweetNode,
  SelectableTweetWrapper, TweetInputForm, CommentBranch, ThreadLine,
  FilterUnrelatedToggle, AIVisionBlock
- .storybook/preview.tsx: single global MemoryRouter context (react-router v8)
  so router-dependent stories share one Router instead of nesting one per story
- ac-card AC-CARD-005 source sanity now also requires empty alt on trending
  image (a11y: main image is decorative; h3 carries the accessible name)
Phase-2 visual baseline acceptance (review-2026-08-19 P1-2): the tweet
directory previously had zero story coverage and the trending card duplicated
the accessible name in the main image alt. These ACs make coverage and the
a11y baseline checkable offline in verify/CI.

- verify/acceptance-criteria/AC-ui.md: AC-UI-VISION-001 (every used component
  has a non-empty story; 14 tweet components enumerated) and AC-UI-A11Y-001
  (a11y addon registered, axe configured, trending main image decorative alt,
  avatars decorative, icon buttons carry sr-only names)
- test/acceptance/ac-ui.spec.ts: offline static checks implementing both ACs
- lefthook pre-push: add 'bun run build-storybook' to the real gate
- backlog: check off tweet 14-component story task and AC-CARD-005 render
  test task (AC-CARD-005~008 in card-render.spec.ts); note visual-baseline
  partial landing (AC-UI ACs + build-storybook in pre-push) with owner
  decision pending on baseline form
- dev log: 2026-08-19 add branch worklog with atomic commits, pitfalls
  (nested Router in stories, Meta component inference, imageUrl required
  type, Windows EIO writes, lint autofix doc churn)
- docs-only: no code change
Phase-2 items 2-3 (review-2026-08-19): extend story coverage to every in-use
component in the remaining directories, following the use-based ('getest
used-something is covered') rule, in per-component story files.

- ins: IGCaption / IGHeader / IGHeaderActions (IGTranslateToggle, IGScreenshotButton,
  IGOptionsMenu) / IGTranslateDialog / InsLogo / PlainIGPost stories + ig.fixtures
- translation: TranslationActions (BackButton / ToggleTransButton / SaveAsImageButton /
  DownloadMedia / AIErrorDetail / DictionaryViewer) and TranslationEditors
  (TranslationDisplay / TranslationEditor / AltTranslationEditor / AIVisionEditorDialog open)
- settings: AITranslationSettings / AIVisionSettings / GeneralSettings / SettingsUI
  (SettingsGroup preview), with store seeding for enabled states
- ui: ui-primitives bundle covering 22 in-use primitives (button/alert/card/input/label/
  select/switch/checkbox/toggle/skeleton/spinner/empty/media/tooltip/dropdown-menu/
  popover/dialog/badge/avatar/separator/preview-card/scroll-area)
- AC-UI-VISION-001: coverage now checks ins (14), in-use translation (10), settings (8)
  and ui primitives (22) in addition to the 14 tweet components (import-or-file based)
- backlog: check off ins story task and translation/settings/ui primitive
  story task; note visual-baseline partial landing (owner decision pending)
- dev log: 2026-08-19 add item 2-3 coverage table, AC-UI-VISION-001 scope
  extension, and the multiple-meta-per-file pitfall
- AC-ui.md: document the use-based coverage scope across all five directories
- docs-only: no code change
The Storybook Test panel failed with 'No projects matched the filter
storybook:<configDir>' / 'Failed to start Vitest' because there was no
storybook vitest project and the browser provider peer deps were absent.

- add @vitest/browser + @vitest/browser-playwright (peer deps) and align
  vitest/@vitest/coverage-v8 to 4.1.11; chromium v1234 installed
- vitest.config.ts: add 'storybook' project (storybookTest() plugin reads
  .storybook/main.ts, playwright chromium headless, setup reuses
  .storybook/vitest.setup.ts with a11y annotations); project name set to
  'storybook:<configDir>' so the panel's --project filter matches
- package.json: test:storybook script (vitest run --project 'storybook:*')
- fix VisionDialogOpened story: useEffect depended on the unstable editor
  object, causing an infinite re-render loop that crashed the browser test
- docs: dev log + backlog item 4 visual-baseline progress

Verified: bun run test:storybook 28 files / 137 tests pass in real Chromium;
bun run test (unit+acceptance) still 280/280.
Running verify with no --project filter now also picks up the new 'storybook'
browser project, which the deterministic node gate can't run (needs chromium and
is an optional visual-baseline layer). Scope the gate to unit/acceptance/
integration; 'bun run test:storybook' stays the opt-in browser runner.

After the fix: verify 40 files / 287 passed / 4 skipped (excluding storybook).
Audit of CI/CD + Vercel after adding the browser test deps:

- no install-time browser download (playwright/@vitest/browser have no
  postinstall); only 'bun run test:storybook' / the Storybook Test panel
  needs chromium, and neither runs in CI/Vercel
- Vercel deploy unaffected: vercel.json only rewrites; default build is
  'bun install' + 'bun run build' (no test/storybook tasks); new deps are
  devDependencies (not in the runtime bundle); build/ and storybook-static
  are gitignored
- de-dup: 'bun run test' (unit+acceptance) is a strict subset of
  'verify/index.ts' (unit+acceptance+integration). pre-push ran both and CI
  ran both, so the whole node suite executed twice. Removed the standalone
  test step from pre-push and from the 'Unit tests' CI job; verify covers it.

- lefthook pre-push: typecheck + lint + verify + build-storybook
- verify.yml: install + typecheck + lint + verify
- CLAUDE.md + dev log: document the split and rationale
bunx eslint . (pre-push/CI, no --fix) fails on markdown table alignment in
the docs touched this session. Apply the @antfu/prettier formatting so the
full lint scan is clean. Content unchanged; whitespace/column only.
@vercel

vercel Bot commented Aug 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
anon-tweet Ready Ready Preview Aug 20, 2026 6:07am

@Chilfish
Chilfish merged commit 1572e96 into main Aug 20, 2026
2 checks passed
@Chilfish
Chilfish deleted the feat/storybook-tweet branch August 20, 2026 06:12

This branch was successfully deployed

1 active deployment
Preview — 9b08fc54 Deployed Aug 20, 2026 by vercel[bot]
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