blackbaud/skyux/add-component-visual-tests
Claude Code and agent skill by blackbaud/skyux
- community
Checking that the SKILL.md file is still in the repository.
Workflow for adding Storybook visual-test stories for a @skyux/* component in this Nx monorepo, used for Percy visual regression snapshots. Use when asked to "add visual tests", "add a story", "create a storybook story", or set up Percy/visual coverage for a component. Covers the @skyux-sdk/e2e-schematics:story generator, the component-e2e generator when no storybook app exists yet, the wrapper component + .stories.ts conventions, and the build/lint/format gate. For unit tests use the add-component-unit-tests skill; for harnesses use the add-component-harness skill.
Install
npx vskill@latest install blackbaud/skyux/add-component-visual-testsSKILL.md
Add Visual Tests (Storybook stories) for a Component
Use this skill to add Storybook stories that drive Percy visual-regression snapshots for a component in a published @skyux/* library. The file-level conventions live in visual-testing.instructions.md (it auto-applies to **/apps/e2e/*-storybook/src/app/**/*.stories.ts) — read it before writing code rather than guessing.
Read AGENTS.md first if you are not already familiar with the monorepo's conventions (Nx tasks, the e2e/storybook app layout, and Conventional Commits).
When to Use
- A component needs visual-regression coverage (a new story), or an existing
story needs to cover a new visual state.
Do NOT use this skill for:
- Unit tests — use
- Test harnesses — use
- Creating a brand-new library — use
add-skyux-library, which creates the storybook app via the component-e2e generator.
Procedure
Work top to bottom. Always mirror an existing sibling story in the same storybook app (or the closest analog) for exact style; do not invent new patterns.
- Confirm the storybook app exists. Look for
apps/e2e/<library>-storybook/. If it does not exist, create it first:
``bash npx nx g @skyux-sdk/e2e-schematics:component-e2e <library> ``
This creates apps/e2e/<library>-storybook (tag component-e2e) and apps/e2e/<library>-storybook-e2e. The app intentionally uses the webpack builder (@angular-devkit/build-angular:browser) — that is the source of truth; do not migrate it to @angular/build:application. The generator already emits the SKY-standard eslint.config.js for both apps and the eslint-disable comment in .storybook/manager.ts, so no eslint reconciliation is needed. You only need to revert the unrelated churn it makes: it re-orders tags in many other project.json files and edits .prettierignore. Keep only the two new <library>-storybook* projects.
- Generate the story scaffold. Run the
storygenerator, which creates
the wrapper component, its module, and the *.stories.ts file under apps/e2e/<library>-storybook/src/app/<name>/:
``bash npx nx g @skyux-sdk/e2e-schematics:story <ComponentName> --project=<library>-storybook ``
- Fill in the wrapper and stories. Edit the generated wrapper component
(app-<name>) to embed the real SKY UX component and supply demo data, then author the named stories per visual-testing.instructions.md. Add a distinct story or args permutation for each meaningful visual state (default, key inputs, selected/disabled/error/empty/loading) the snapshot should capture. Do not add assertions or interaction logic.
- Capture snapshots with `skyVisualTest`. The
storygenerator also
creates a Cypress spec at apps/e2e/<library>-storybook-e2e/src/e2e/<name>/<name>.component.cy.ts. Capture each snapshot with skyVisualTest (not cy.screenshot + cy.percySnapshot), iterating themes with E2eVariations.forEachTheme, waiting for the component with cy.skyReady, and passing disableTimersAndAnimations: true for components that animate on render (e.g. charts). Scope the capture based on where the content renders:
- Inline components — scope to the wrapper element:
cy.get('app-<name>').skyVisualTest(...).
- Portaled overlays — a component that renders into an overlay outside
the wrapper (such as a modal sky-modal, flyout, or dropdown) is missed by a wrapper-scoped capture. Assert the overlay is visible, then capture the viewport instead: cy.skyVisualTest(name, { capture: 'viewport' }).
```typescript import { E2eVariations } from '@skyux-sdk/e2e-schematics';
describe('<Name>', () => { E2eVariations.forEachTheme((theme) => { describe(in ${theme} theme, () => { it('should render', () => { cy.visit( /iframe.html?globals=theme:${theme}&id=<storyId>--<story>, ); cy.skyReady('app-<name>').end(); cy.get('app-<name>').skyVisualTest(<name>-${theme}, { overwrite: true, disableTimersAndAnimations: true, }); }); }); }); }); ```
- Verify. Build the storybook app to confirm it compiles, then lint and
format:
``bash npx nx build <library>-storybook npm run lint:affected nx format --files=<changed-file-paths> ``
- Commit. Use a Conventional Commit with the
components/<library>scope
per commit-message.instructions.md.
Definition of Done
- A wrapper component, its module, and a
*.stories.tsexist under
apps/e2e/<library>-storybook/src/app/<name>/ and mirror a sibling story.
- The story's
Metahas a stableid, aComponents/<DisplayName>title, and
a moduleMetadata decorator; each meaningful visual state is captured as a named story or args permutation, with no assertion/interaction logic.
- The generated Cypress spec captures each snapshot with
skyVisualTest
(iterated over forEachTheme), not cy.screenshot + cy.percySnapshot: inline content is scoped to the wrapper element, while portaled overlays such as a modal (sky-modal) use capture: 'viewport'.
npx nx build <library>-storybookcompiles, lint is clean, and changed
files are formatted.
Security
- Security scanPassed, 91 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryChecking.github/skills/add-component-visual-tests/SKILL.md
Popularity
- Repository stars
- 55
- Repository forks
- 36
- 7-day trend score
- 20
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/blackbaud/skyux/add-component-visual-tests)