Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .agents/skills/browser-tests/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,5 @@ pnpm eslint packages/design-system/src/components/ds-{name}/
- **Migrate from Storybook play**: [migrate-story-tests](../migrate-story-tests/SKILL.md)
- **New component**: [component-scaffold](../component-scaffold/SKILL.md)
- **React state in tests**: [react-patterns](../react-patterns/SKILL.md)
- **Docs snippet tests**: [docs-tests](../docs-tests/SKILL.md)
- **Examples**: `packages/design-system/src/components/*/__tests__/*.browser.test.tsx`
1 change: 1 addition & 0 deletions .agents/skills/code-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Refactor card to use CSS modules and fix hover state selector specificity
| `ds-*.tsx` (not stories/tests) | [react-patterns](../react-patterns/SKILL.md); [ark-ui](../ark-ui/SKILL.md) if Ark |
| `*.stories.tsx` | [storybook](../storybook/SKILL.md), [react-patterns](../react-patterns/SKILL.md) |
| `*.browser.test.tsx` | [browser-tests](../browser-tests/SKILL.md) |
| `*.docs.test.ts` | [docs-tests](../docs-tests/SKILL.md) |
| `*.module.scss` | [scss](../scss/SKILL.md) |

3. Flag only clear, high-severity issues (max 10 inline comments)
Expand Down
122 changes: 122 additions & 0 deletions .agents/skills/docs-tests/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
---
name: docs-tests
description: Write and run Storybook docs snippet tests (`*.docs.test.ts`) for Show code and MCP manifest verification against production storybook-static. Use when adding or editing docs tests or verifying Autodocs snippets after story changes.
---

# Docs Tests Skill

Verify Autodocs **Show code** panel text and MCP manifest snippets in `ds-{name}/__tests__/ds-{name}.docs.test.ts` — not in `*.browser.test.tsx` ([browser-tests](../browser-tests/SKILL.md)).

Story authoring rules: [storybook](../storybook/SKILL.md) "Docs source snippets" + "Snippet verification".

## What docs tests verify

| Output | Mechanism | Data source |
| ---------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| **Show code** | Playwright opens Autodocs, clicks **Show code**, reads `pre` text | [`read-show-code.ts`](../../../packages/design-system/tests/storybook/read-show-code.ts) |
| **MCP manifest** | HTTP `fetch` of `components.json` | [`read-manifest-snippet.ts`](../../../packages/design-system/tests/storybook/read-manifest-snippet.ts) |

Both use the same `STORYBOOK_URL` from global setup — not filesystem reads, not the Storybook `/mcp` JSON-RPC endpoint.

## Production target

- `pnpm test:storybook-docs` runs `build:storybook` then vitest `--project=storybook-docs`.
- Global setup ([`setup.storybook-docs.ts`](../../../packages/design-system/vitest/setup.storybook-docs.ts)) serves `storybook-static/` on an ephemeral port (same artifact as GitHub Pages).
- Do **not** run docs tests against `pnpm start` (dev server). Show code snippets differ there because React Compiler is not applied the same way as in the production Storybook build.

## File layout

```
ds-{name}/__tests__/
├── ds-{name}.docs.test.ts
└── __snapshots__/ds-{name}.docs.test.ts.snap
```

## Quick start

```tsx
import { chromium, type Browser, type Page } from 'playwright';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
import { readManifestSnippet } from '../../../../tests/storybook/read-manifest-snippet';
import { readShowCodeSnippet } from '../../../../tests/storybook/read-show-code';

const DOCS_STORY_ID = 'components-breadcrumb--docs';
const COMPONENT_ID = 'components-breadcrumb';

describe('DsBreadcrumb docs snippets', () => {
let browser: Browser;
let page: Page;

beforeAll(async () => {
browser = await chromium.launch({ headless: true });
page = await browser.newPage({ viewport: { width: 1400, height: 900 } });
});

afterAll(async () => {
await browser.close();
});

describe('Default', () => {
it('Show code panel matches staged authoring rules', async () => {
const snippet = await readShowCodeSnippet(page, {
docsStoryId: DOCS_STORY_ID,
storyName: 'Default',
});

expect(snippet).toContain("type: 'code'");
expect(snippet).toMatchSnapshot();
});

it('MCP manifest snippet matches staged authoring rules', async () => {
const snippet = await readManifestSnippet(COMPONENT_ID, 'Default');

expect(snippet).toMatchSnapshot();
});
});
});
```

Examples: [`ds-breadcrumb.docs.test.ts`](../../../packages/design-system/src/components/ds-breadcrumb/__tests__/ds-breadcrumb.docs.test.ts), [`ds-button-v3.docs.test.ts`](../../../packages/design-system/src/components/ds-button-v3/__tests__/ds-button-v3.docs.test.ts).

## IDs

| Constant | Derivation | Example |
| --------------- | ------------------------------------ | --------------------------------------------------------- |
| `DOCS_STORY_ID` | Story `title` kebab-cased + `--docs` | `Components/ButtonV3` → `components-buttonv3--docs` |
| `COMPONENT_ID` | Key in built `components.json` | `components-buttonv3` (not always `components-button-v3`) |

Confirm `COMPONENT_ID` after `pnpm build:storybook`:

```bash
node -e "const m=require('./packages/design-system/storybook-static/manifests/components.json'); console.log(Object.keys(m.components).filter(k=>k.includes('your-component')))"
```

Story names in tests match Autodocs `h3` titles (`IconOnly` → `"Icon Only"`).

## Assertions

- **Snapshots** — `expect(snippet).toMatchSnapshot()` for full-text regression.
- **Story-specific `toContain`** — when a variant has a distinguishing prop or pattern (e.g. `loading`, `type: 'code'`). No shared assertion helper; no generic `<DsX>` tag check.

| Rule | Show code test | MCP test |
| -------------------------------------- | ----------------------------------------- | -------------------- |
| Story-specific props or patterns | `toContain` for the distinguishing detail | same when applicable |
| `decorators` visible in Show code only | `toContain('decorator')` when applicable | do not assert in MCP |

## Skip

Do not add `*.docs.test.ts` coverage for stories with `docs.canvas.sourceState: 'none'` or showcase matrices tagged `!manifest`.

## Commands

```bash
pnpm --filter @drivenets/design-system test:storybook-docs packages/design-system/src/components/ds-{name}/__tests__/ds-{name}.docs.test.ts --run
```

Update snapshots after verifying output: add `--run -u`.

## Related

- Story authoring: [storybook](../storybook/SKILL.md)
- Behavioral tests: [browser-tests](../browser-tests/SKILL.md)
- PR snippet check: [pr-prep](../pr-prep/SKILL.md)
13 changes: 12 additions & 1 deletion .agents/skills/pr-prep/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ Use [AGENTS.md#code-quality-checkers](../../../AGENTS.md#code-quality-checkers)

For new components or substantial interaction/behavior changes, confirm an updated `*.browser.test.tsx` exists under the component's `__tests__/` when appropriate.

### Step 2b: Verify story snippets (when `*.stories.tsx` changed)

Per [storybook](../storybook/SKILL.md) Snippet verification and [docs-tests](../docs-tests/SKILL.md):

1. **Show code + manifest (primary)** — `pnpm --filter @drivenets/design-system test:storybook-docs <matching *.docs.test.ts path> --run`.
2. **MCP agent tooling (secondary)** — if Storybook is on port 6006, `get-documentation-for-story` via local MCP; else **SKIP**.

Add `*.docs.test.ts` when introducing stories without one.

### Step 3: Review changed files against project rules

Read the matching skill(s) from the [code-review file → skill table](../code-review/SKILL.md#code-review-process) for paths in the diff. Flag violations found in the diff.
Expand Down Expand Up @@ -76,6 +85,8 @@ PR Preparation Report
[PASS/FAIL] Lint .................. {details}
[PASS/FAIL] Typecheck ............. {details}
[PASS/FAIL] Tests ................. {details}
[PASS/FAIL] Show code (docs tests) . {details}
[PASS/FAIL] MCP manifest snippets . {details}
[PASS/FAIL] Rule violations ....... {details}
[PASS/FAIL] No !important ........ {details}
[PASS/FAIL] No hardcoded colors .. {details}
Expand All @@ -88,7 +99,7 @@ PR Preparation Report
[PASS/FAIL] No AI test slop .... {details}
[PASS/FAIL] Changeset ............ {details}

{N}/14 checks passed.
{N}/16 checks passed.
```

If all pass, the PR is ready for submission. If any fail, list the specific files and lines that need fixing.
17 changes: 16 additions & 1 deletion .agents/skills/storybook/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,19 @@ Storybook's default `source.type` is `auto`. Args-only stories (no `render`) alw
- **`render` that goes straight to `return`** (compound sub-components, no hooks/handlers): rely on `auto`/`dynamic`; do **not** add `type: 'code'`.
- **Showcase matrices**: hide the panel with `docs.canvas.sourceState: 'none'` (see below).

## Snippet verification

Show code (Autodocs panel) and MCP manifest snippets are **different outputs** — verify both when `type: 'code'` is set.

| Output | What it shows |
| ----------------- | -------------------------------------------------------------------------------------------------- |
| **Show code** | Serialized story (`parameters`, `decorators`, `render`) when `type: 'code'`; clean JSX when `auto` |
| **MCP `snippet`** | Evaluated `render` body only |

Verify both via `*.docs.test.ts` — see [docs-tests](../docs-tests/SKILL.md). For ad-hoc agent MCP checks during story authoring, use `pnpm start` + `--manifests-url http://localhost:6006` (separate from docs tests).

Add or update `*.docs.test.ts` when changing stories that expose Show code — see [docs-tests](../docs-tests/SKILL.md).

## Showcase / matrix stories

For visual-only grids (size/variant matrices) that aren't real usage examples:
Expand All @@ -115,10 +128,12 @@ Stories and MDX feed the DS MCP server (`packages/mcp`). Follow [Storybook AI be
- **MDX guidelines** — put token values and rules in the file body, not only in runtime `{map}` loops agents cannot see.
- **Exclude noise** — `tags: ['!manifest']` on anti-pattern or human-only stories/docs.
- **Exclude performance panel** — opt a component out of the ⚡ performance panel with `parameters: { performancePanel: { disable: true } }`.
- **Verify locally** — with Storybook running (`pnpm start`), the dev server exposes a built-in MCP at `http://localhost:6006/mcp`. Use whichever configured MCP server points at that URL (the alias is per-developer) to check your changes: `list-all-documentation` (confirm `!manifest` stories are absent) and `get-documentation` / `get-documentation-for-story` (confirm snippets render `<DsX>` not the HOC name, descriptions have no `@summary`, props look right). This is not `packages/mcp`, which serves published docs to DS _consumers_.
- **Verify manifest snippets** — with Storybook running (`pnpm start`), use local MCP (`http://localhost:6006/mcp` or `--manifests-url http://localhost:6006`): `list-all-documentation`, `get-documentation` / `get-documentation-for-story`. Confirm manifest render snippets use `<DsX>` not HOC names, descriptions have no `@summary`, `!manifest` stories are absent. This checks **agent-facing** snippets only — not the Autodocs Show code panel. Not `packages/mcp`, which serves published docs to DS _consumers_.
- **Verify Show code** — run `*.docs.test.ts` per [docs-tests](../docs-tests/SKILL.md). Published `@drivenets/design-system-mcp` serves DS consumers and may lag local edits.

## Related

- New component: [component-scaffold](../component-scaffold/SKILL.md)
- Behavioral tests: [browser-tests](../browser-tests/SKILL.md)
- Show code / MCP snippet tests: [docs-tests](../docs-tests/SKILL.md)
- React in stories: [react-patterns](../react-patterns/SKILL.md)
16 changes: 9 additions & 7 deletions .cursor/agents/ds-verifier.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ You are a skeptical verifier for `@drivenets/design-system`. Do not accept claim

## Run (changed files only)

| Change | Command |
| -------------------------------------- | --------------------------------------------------------------------------------- |
| `packages/design-system/**/*.tsx` etc. | `pnpm eslint <changed-paths>` |
| Any design-system source | `pnpm --filter @drivenets/design-system typecheck` |
| `*.browser.test.tsx` | `pnpm --filter @drivenets/design-system test <path> --run` |
| `packages/eslint-plugin/**` | Per [eslint-plugin](../../AGENTS.md#drivenetseslint-plugin-design-system) section |
| `packages/vite-plugin/**` | Per [vite-plugin](../../AGENTS.md#drivenetsvite-plugin-design-system) section |
| Change | Command |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `packages/design-system/**/*.tsx` etc. | `pnpm eslint <changed-paths>` |
| Any design-system source | `pnpm --filter @drivenets/design-system typecheck` |
| `*.browser.test.tsx` | `pnpm --filter @drivenets/design-system test <path> --run` |
| `*.docs.test.ts` | `pnpm --filter @drivenets/design-system test:storybook-docs <path> --run` — see [docs-tests skill](../../.agents/skills/docs-tests/SKILL.md) |
| `*.stories.tsx` (snippet check) | Run matching `*.docs.test.ts` per [docs-tests skill](../../.agents/skills/docs-tests/SKILL.md); local MCP manifest per [storybook skill](../../.agents/skills/storybook/SKILL.md) |
| `packages/eslint-plugin/**` | Per [eslint-plugin](../../AGENTS.md#drivenetseslint-plugin-design-system) section |
| `packages/vite-plugin/**` | Per [vite-plugin](../../AGENTS.md#drivenetsvite-plugin-design-system) section |

Skip commands when no relevant files changed. Say what you skipped and why.

Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,15 @@ jobs:
- name: Run Tests
run: pnpm test:coverage --affected

- name: Build Storybook for docs snippet tests
run: pnpm build:storybook --affected
Comment on lines +123 to +124

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're going to build storybook for every PR now, let's use turbo cache. See the build-storybook job for reference


- name: Install Playwright Chromium
run: pnpm --filter @drivenets/design-system install:playwright
Comment on lines +126 to +127

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already a dependency of the test:coverage task, so there is no need to run it manually. Chromium should be installed at this point


- name: Run Storybook docs snippet tests
run: pnpm --filter @drivenets/design-system exec vitest --project=storybook-docs --run
Comment on lines +129 to +130

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is kinda "implementation details" -- let's create a new npm script for this (i.e., test:docs or something)

Maybe it should also have its own CI job?


build:
name: Build
runs-on: ubuntu-latest
Expand Down
Loading
Loading