test: Storybook browser smoke test + CSP-safety gate#16
Merged
Conversation
Add a @storybook/test-runner pass that opens every story in headless Chromium and asserts each component paints visible content with no console / page errors. Story images that 404 offline are filtered as resource noise; media elements (img/iframe/...) count as rendered even when their remote asset fails to load. Runs against both the dev server (test-storybook) and the production static build (test-storybook:ci -> storybook build + http-server). Storybook bundles from src/ via Vite, so this validates the components, not the published dist/ artifact (covered by the Next.js integration). Pinned to @storybook/test-runner 0.23.0 (the Storybook 9-compatible line; 0.24+ requires Storybook 10) and playwright 1.60.0, and wired into CI with a Chromium install step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add scripts/csp-probe.mjs (pnpm test:csp): import + render the built dist/ bundle under node --disallow-code-generation-from-strings (V8's engine-level equivalent of a Content-Security-Policy without 'unsafe-eval') and fail on any eval / new Function at import or render. It exercises the template-backed paths (links, menu, social) that historically compiled lodash templates at render time. Hard gate: it fails if this package OR its pinned @unlayer/exporters evaluates a string. It is RED today because the pinned @unlayer/exporters@1.400.0 compiles lodash templates via new Function at import, so importing react-elements throws under a strict CSP. It turns green once the workspace catalog is bumped to a precompiled / CSP-safe @unlayer/exporters release. A green check must mean the package is genuinely CSP-safe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a browser-level Storybook smoke test for @unlayer/react-elements and wires it into CI to catch “renders nothing” regressions and unexpected browser console/page errors across all stories.
Changes:
- Add Storybook test-runner configuration that asserts each story paints visible content and produces no non-noise console/page errors.
- Add package scripts and devDependencies to run the smoke test locally and against a static Storybook build.
- Update CI workflow (and CLAUDE.md documentation) to run the Storybook smoke test in headless Chromium.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/react/package.json | Adds Storybook smoke test scripts and pins required devDependencies (test-runner, Playwright, http-server, wait-on, concurrently). |
| packages/react/.storybook/test-runner.ts | Implements the smoke assertions (visible paint + error collection/filtering) for each story page. |
| CLAUDE.md | Documents the new Storybook smoke test and lists it as a CI quality gate. |
| .github/workflows/test.yml | Installs Playwright Chromium and runs the Storybook smoke test in CI. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ivoIturrieta
approved these changes
May 25, 2026
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.
What
Two browser/runtime test layers for
@unlayer/react-elements, added as separate commits.1. Storybook browser smoke test
A
@storybook/test-runnerpass that opens every story in headless Chromium and asserts:#storybook-roothas a non-zero painted box; media elements like<img>/<iframe>count as rendered even when their remote asset 404s offline), andRuns against both the dev server (
pnpm test-storybook) and the production static build (pnpm test-storybook:ci). ✅ 106/106 stories pass.2. CSP-safety gate
scripts/csp-probe.mjs(pnpm test:csp) imports + renders the builtdist/bundle undernode --disallow-code-generation-from-strings— V8's engine-level equivalent of a Content-Security-Policy without'unsafe-eval'— and fails on anyeval/new Functionat import or render.This gate is intentionally RED right now. The pinned
@unlayer/exporters@1.400.0compiles lodash templates vianew Functionat import, so importing react-elements throws under a strict CSP. The gate turns green once the workspace catalog is bumped to a precompiled / CSP-safe@unlayer/exportersrelease (the unlayer/unlayer exporters CSP fix). A green check must mean the package is genuinely CSP-safe.Notes
@storybook/test-runner@0.23.0(SB-9 line),playwright@1.60.0,concurrently@9.2.1,http-server@14.1.1,wait-on@9.0.10.test.yml) gains a Chromium install + smoke step and the CSP gate step.🤖 Generated with Claude Code
📖 Storybook Preview: https://unlayer.github.io/elements/pr/16/