Skip to content

Test & Story Coverage Analysis

New play functions should use the Storybook step() DSL available via the play context. This provides named, collapsible steps in the Storybook interactions panel and integrates with the test runner.

Current pattern (flat, no steps):

play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await userEvent.click(canvas.getByRole('button'));
await storyStepDelay();
await expect(canvas.getByText('Result')).toBeInTheDocument();
};

New pattern (step DSL):

play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
await step('Click the action button', async () => {
await userEvent.click(canvas.getByRole('button'));
});
await storyStepDelay();
await step('Verify result appears', async () => {
await expect(canvas.getByText('Result')).toBeInTheDocument();
});
};

The storyStepDelay() utility (skips delay under navigator.webdriver) is compatible with the step DSL and should continue to be used between major interaction steps for human observation.

All new play functions in this project must use the step DSL. Existing play functions can be migrated opportunistically but are not required to change.

ComponentStoriesTestsPlay FunctionsMDX
Grid cell atoms (8 types)3-4 variants eachYesYesNo
DataGrid molecule8+ variantsYesYesNo
EntityDataGrid factory9 variants14 unit testsYesNo
EntityDataGridShim9 variantsYesNoNo
Sidebar organism4 variantsYesYes (Default)Yes
AppHeader organism6 variants8 testsNoYes
ItemGrid organism8 variants6 testsYes (Empty, WithSearch)Yes
ItemDetails organism4 variants9 testsNoNo
New canary atoms (badge, button, drawer, etc.)100% pairing100% pairingMinimalNo
Sidebar molecules (5 sub-components)100% pairing~80% pairingNoNo
  • OverflowToolbar: story exists, no unit test
  • ItemGridMolecules: story exists, no unit test
  • AppHeader: no play functions (static composition only)
  • ItemDetails: no play functions, no MDX docs
  • Most molecules lack play functions

Each story is assigned a location:

  • Component — next to the component source (e.g., src/components/canary/organisms/shared/entity-data-grid/)
  • Use Cases — in src/use-cases/ mapped to a documented product use case
  • Other — doesn’t fit either category (build verification, developer reference)

Use case references follow the documented taxonomy in documentation/src/content/docs/product/use-cases/.

These are promoted from item-grid or newly created. None exist at the entity-data-grid level today.

ArtifactDescriptionPriorityLocation
Story: RowAutoPublishShow row editing → blur → saving state → success. Demonstrate pending changes accumulating across multiple cells in same row.HighComponent: entity-data-grid/
Story: RowAutoPublishErrorShow row editing → blur → saving → error state. Verify row stays dirty with error visual.HighComponent: entity-data-grid/
Story: SaveAllDraftsShow imperative saveAll() triggered by a toolbar button, publishing all dirty rows at once.MediumComponent: entity-data-grid/
Story: DiscardAllDraftsShow imperative discardAll() restoring original values.MediumComponent: entity-data-grid/
Unit testVerify: pending changes accumulate per row; onRowPublish fires on blur with batched changes; dirty state tracking; save/discard ref API; visual CSS class injection (saving/error).HighComponent: entity-data-grid/
Play functionInteract: edit cell → edit another cell in same row → click different row → verify saving callback fired with both changes.HighComponent: entity-data-grid/
ArtifactDescriptionPriorityLocation
Story: ClientPaginationShow pageSize config in StaticConfig, AG Grid handling pages internally.MediumComponent: entity-data-grid/
Story: ServerPaginationExisting — verify it still works alongside new mode.MediumComponent: entity-data-grid/
Unit testVerify both modes produce correct grid config; modes are mutually exclusive at design time.MediumComponent: entity-data-grid/
ArtifactDescriptionPriorityLocation
Story: WithActionsColumnShow mount-time actionsColumn ColDef with 2-3 action buttons, auto-width from actionCount.MediumComponent: entity-data-grid/
Unit testVerify pinned-right column injected; width calculation correct; action callbacks fire.MediumComponent: entity-data-grid/
Play functionClick action button in row, verify callback receives correct row data.MediumComponent: entity-data-grid/
ArtifactDescriptionPriorityLocation
Story: ThemedGridVisual story showing grid with Arda token styling — row heights, fonts, colors, borders.High (visual)Component: molecules/data-grid/
VRT baselineCapture baseline after theme migration. Before/after comparison critical.HighVRT config
ArtifactDescriptionPriorityLocation
Story: WithToolbarShow custom ReactNode toolbar above grid (buttons, dropdowns).LowComponent: entity-data-grid/
Unit testVerify toolbar renders in correct position.LowComponent: entity-data-grid/
ArtifactDescriptionPriorityLocation
Story: AutoHeightShow grid growing to fit 3 rows, then 20 rows.LowComponent: entity-data-grid/
Unit testVerify domLayout: 'autoHeight' passed to AG Grid.LowComponent: entity-data-grid/
ArtifactDescriptionPriorityLocation
Story: WithSearchShow search bar with configurable fields, debounced filtering, count display (“3 of 12 items”).MediumComponent: entity-data-grid/
Story: WithSearchAndSelectionShow count switching to “3 of 12 selected” when rows are selected.MediumComponent: entity-data-grid/
Unit testVerify debounce timing; filter predicate applies to configured fields; count updates.MediumComponent: entity-data-grid/
Play functionType in search box, verify row count changes after debounce.MediumComponent: entity-data-grid/
ArtifactDescriptionPriorityLocation
Story: DragToScrollWide grid demonstrating horizontal drag-scroll. Hard to test visually in static story.LowComponent: entity-data-grid/
Play functionSimulate pointer drag on grid body, verify horizontal scroll position changed.Low (fragile in CI)Component: entity-data-grid/

2. SelectCellEditor (new canary atom, replaces EnumCellEditor)

Section titled “2. SelectCellEditor (new canary atom, replaces EnumCellEditor)”
ArtifactDescriptionPriorityLocation
Story: DefaultFixed list dropdown with checkmark on selected item.HighComponent: atoms/grid/select/
Story: WithManyOptionsVerify scroll behavior with max-height 240px.MediumComponent: atoms/grid/select/
Story: KeyboardNavigationDocument Arrow Up/Down cycling, Enter to select, Escape to cancel.HighComponent: atoms/grid/select/
Story: BothFormatsShow SelectOption[] and Record<string, string> both accepted.MediumComponent: atoms/grid/select/
Unit testVerify: highlight cycling wraps around; Enter selects highlighted; Escape cancels; isCancelAfterEnd returns true on Escape; checkmark renders for current value; ARIA listbox/option roles present.HighComponent: atoms/grid/select/
Play functionOpen editor → Arrow Down 3 times → Enter → verify value changed.HighComponent: atoms/grid/select/
VRT baselineCapture popup appearance (replaces native <select>).MediumVRT config
ArtifactDescriptionPriorityLocation
Integration story: PrimitivesImportCheckOne story importing from @/components/canary/primitives/sheet, primitives/tooltip, etc. and rendering a composed example. Proves import paths resolve.MediumOther: src/components/canary/primitives/primitives.stories.tsx (build verification, not a component or use case)
No unit tests neededPrimitives are stock shadcn — tested upstream.

These are the acceptance test for the consolidation — proving canary components can reproduce dev-witness page layouts. Mapped to documented product use cases where applicable.

ArtifactDescriptionPriorityLocationUse Case Refs
Story: BrowseItemsSidebar + AppHeader + EntityDataGrid (item columns) with search, column toggle, multi-select actions.HighUse Cases: use-cases/reference/items/browse-and-search/REF::ITM::0001 — Browse and Search Items
Story: ViewItemDetailsClick row → ItemDetails drawer opens with fields, card preview tab.HighUse Cases: use-cases/reference/items/view-details/REF::ITM::0002 — View Item Details
Story: EditItemInlineDouble-click cell → edit → blur row → auto-publish with visual feedback.HighUse Cases: use-cases/reference/items/edit-item/REF::ITM::0004 — Edit and Publish Item; GEN::LST::0007 — Edit Entity In Place
Play functionSearch items → verify filter; click row → verify drawer; edit cell → blur → verify save.HighUse Cases: use-cases/reference/items/browse-and-search/
VRT baselineFull items page screenshot.HighVRT config
ArtifactDescriptionPriorityLocationUse Case Refs
Story: BrowseSuppliersSidebar + AppHeader + EntityDataGrid (supplier columns) with server-side search. Demonstrates generic factory works for a different entity.MediumUse Cases: use-cases/reference/business-affiliates/browse-and-search/ (canary variant alongside existing extras stories)REF::BA::0001 — Browse and Search Business Affiliates
Story: ViewSupplierDetailsClick row → detail panel with Details/Roles/Items tabs.MediumUse Cases: use-cases/reference/business-affiliates/view-details/ (canary variant)REF::BA::0002 — View Business Affiliate Details
Play functionBasic: verify grid renders with supplier columns; click row → verify callback.MediumUse Cases: use-cases/reference/business-affiliates/browse-and-search/
ArtifactDescriptionPriorityLocationUse Case Refs
Story: ColumnConfigurationToggle column visibility, reorder, resize, pin.MediumUse Cases: use-cases/general-behaviors/list-views/GEN::LST::0002 — Configure List Column Display
Story: SortAndFilterSingle/multi-column sort, global + per-column filter.MediumUse Cases: use-cases/general-behaviors/list-views/GEN::LST::0003, GEN::LST::0004 — Filter/Sort Entity List
Story: RowSelectionSingle, multi, shift-click range, select-all, selection-driven toolbar actions.MediumUse Cases: use-cases/general-behaviors/list-views/GEN::LST::0006 — Select Rows and Trigger Actions
ArtifactDescriptionPriorityLocation
Story: KitchenSinkOne story exercising all promoted capabilities: auto-publish + search + toolbar + actions + drag-to-scroll + pagination (client-side).HighComponent: entity-data-grid/ (developer reference co-located with the organism)
PurposeDeveloper reference: “here’s everything the grid can do.”
TriggerWhat to capturePriorityExpected VariancesLocation
DataGrid theme change (legacythemeQuartz)Before/after grid appearance — row heights, fonts, colors, borders. This is the highest-risk visual change.CriticalAll grid stories will diff. Row height changes (default → 48px), header height (default → 36px), font changes (system → Geist Sans 14px), cell padding (default → 12px), border styling, color mapping from blue-slate to Arda orange tokens. Baselines must be regenerated — old baselines are invalid.VRT project config
Row visual states.ag-row-saving (primary background), .ag-row-error (destructive background) — new CSS classes.HighNew baselines only — no prior state to compare against. Saving rows should show light orange tint; error rows should show light red tint.VRT project config
SelectCellEditor popupNew custom dropdown replacing native <select>.MediumNew baselines only — replaces native browser dropdown (which VRT never captured because native dropdowns are OS-rendered). Custom popup should show styled list with checkmark indicator, highlight state, and design-system tokens.VRT project config
New atoms (badge, button, drawer, etc.)Baseline snapshots for all new components entering the library.MediumNew baselines only — no prior state. These are the first VRT captures for components coming from the callil branch. Any future consolidation changes will diff against these baselines.VRT project config
Composition pagesFull-page screenshots for items page and suppliers page.HighNew baselines only. However, these pages should be visually compared against dev-witness equivalents manually during review — automated diff is not possible since the component trees are different (canary vs vendored), but the visual output should be recognizably similar.VRT project config

Stories and tests should be added alongside the implementation, not as a separate phase. Each consolidation step produces its own verifiable artifacts:

Phase 1: Foundation (primitives, atoms, styles)

Section titled “Phase 1: Foundation (primitives, atoms, styles)”
  • Run existing tests — verify nothing broke by file moves
  • Add PrimitivesImportCheck integration story (Other)
  • Generate VRT baselines for new atoms
  • Add SelectCellEditor stories + tests + play functions (Component)

Phase 2: DataGrid molecule retrofit (theme change)

Section titled “Phase 2: DataGrid molecule retrofit (theme change)”
  • Add ThemedGrid story (Component: data-grid molecule)
  • Generate VRT before/after for theme change — critical gate
  • Run existing DataGrid tests — verify no regressions

Phase 3: Entity-data-grid capability promotion

Section titled “Phase 3: Entity-data-grid capability promotion”

For each capability promoted (in order of risk), stories go Component-local:

  1. Row-auto-publish (highest risk, most complex)

    • Add RowAutoPublish, RowAutoPublishError, SaveAllDrafts, DiscardAllDrafts stories
    • Add unit tests for pending changes, publish lifecycle, ref API
    • Add play functions for edit-blur-save flow
    • Generate VRT for row visual states
  2. Actions column → story + test + play function

  3. Search/filter → story + test + play function

  4. Pagination modes → story + test

  5. Toolbar slot → story + test

  6. Auto-height → story + test

  7. Drag-to-scroll → story (play function optional, fragile in CI)

Stories go in Use Cases, mapped to product use case documentation:

  • Add items browse/view/edit stories (Use Cases: reference/items/)
    • REF::ITM::0001, REF::ITM::0002, REF::ITM::0004
  • Add suppliers browse/view stories (Use Cases: reference/business-affiliates/, canary variant)
    • REF::BA::0001, REF::BA::0002
  • Add list view general behavior stories (Use Cases: general-behaviors/list-views/)
    • GEN::LST::0002, GEN::LST::0003, GEN::LST::0004, GEN::LST::0006
  • Add KitchenSink developer reference (Component: entity-data-grid)
  • Generate VRT baselines for all composition pages

Phase 5: canary-refactor adaptation (follow-on)

Section titled “Phase 5: canary-refactor adaptation (follow-on)”

Per canary-refactor.md decision — adapt existing canary-refactor stories to use consolidated components. Divergences found here drive fixes back into the component library.

MetricTarget
Every new/modified component has a story file100%
Every new/modified component has a unit test file100%
Organisms have at least one play function100%
Organisms have MDX documentation100%
VRT baselines for all visual changes100%
Composition stories covering dev-witness equivalence2-3 pages