@vizzly-testing/static-site
v0.0.7
Published
Static site generator plugin for Vizzly - seamlessly integrate static sites (Gatsby, Astro, Jekyll, Next.js) into your visual development workflow
Downloads
206
Maintainers
Readme
@vizzly-testing/static-site
Seamlessly integrate your static sites (Gatsby, Astro, Jekyll, Next.js static export, etc.) into Vizzly's visual development workflow. Iterate locally with vizzly tdd, automatically create team builds from CI/CD, and collaborate on visual changes with position-based comments and review rules.
Installation
npm install @vizzly-testing/static-siteThe plugin is automatically discovered by the Vizzly CLI via the @vizzly-testing/* scope.
Quick Start
CLI Usage
# Capture screenshots from a static site build
vizzly static-site ./dist
# With custom viewports
vizzly static-site ./dist \
--viewports "mobile:375x667,tablet:768x1024,desktop:1920x1080"
# With filtering
vizzly static-site ./dist \
--include "blog/**" \
--exclude "**/404.html"
# With concurrency control
vizzly static-site ./dist --concurrency 5Programmatic Usage
import { run } from '@vizzly-testing/static-site';
await run('./dist', {
viewports: 'mobile:375x667,desktop:1920x1080',
concurrency: 3,
}, {
logger: console,
config: vizzlyConfig,
services: serviceContainer,
});Configuration
Main Config File
Add a staticSite section to your vizzly.config.js:
// vizzly.config.js
export default {
// Standard Vizzly config
server: { port: 47392 },
build: { environment: 'test' },
// Static Site plugin config
staticSite: {
viewports: [
{ name: 'mobile', width: 375, height: 667 },
{ name: 'tablet', width: 768, height: 1024 },
{ name: 'desktop', width: 1920, height: 1080 },
],
browser: {
headless: true,
args: ['--no-sandbox'],
},
screenshot: {
fullPage: false,
omitBackground: false,
},
concurrency: 3,
// Page filtering
include: 'blog/**',
exclude: '**/404.html',
// Page discovery
pageDiscovery: {
useSitemap: true,
sitemapPath: 'sitemap.xml',
scanHtml: true,
},
},
};Interactions File (Optional)
For page-specific interactions and overrides, create a vizzly.static-site.js file:
// vizzly.static-site.js
export default {
// Interaction hooks - run before screenshots
interactions: {
'blog/*': async (page) => {
await page.waitForSelector('.blog-content');
},
'products/*': async (page) => {
await page.click('.view-details');
},
},
// Per-page configuration overrides
pages: {
'/': {
viewports: ['mobile', 'desktop'],
},
'/pricing': {
screenshot: { fullPage: true },
},
},
};Configuration Priority
Configuration is merged in this order (later overrides earlier):
- Default configuration
config.staticSitefrom vizzly.config.jsvizzly.static-site.jsinteractions and pages- CLI options
CLI Options
--viewports <list>- Comma-separated viewport definitions (format:name:WxH)--concurrency <n>- Number of parallel pages to process (default: 3)--include <pattern>- Include page pattern (glob)--exclude <pattern>- Exclude page pattern (glob)--browser-args <args>- Additional Puppeteer browser arguments--headless- Run browser in headless mode (default: true)--full-page- Capture full page screenshots (default: false)--use-sitemap- Use sitemap.xml for page discovery (default: true)--sitemap-path <path>- Path to sitemap.xml relative to build directory
Page Discovery
The plugin discovers pages using two methods:
1. Sitemap.xml Parsing
Automatically discovers pages from sitemap.xml if available:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com/</loc>
</url>
<url>
<loc>https://example.com/blog/post-1</loc>
</url>
</urlset>2. HTML File Scanning
Recursively scans the build directory for .html files.
Both methods can be used together - the plugin will merge and deduplicate pages.
Interaction Hooks
Interaction hooks allow you to interact with pages before capturing screenshots. Define these in vizzly.static-site.js:
Pattern-Based Hooks
// vizzly.static-site.js
export default {
interactions: {
'blog/*': async (page) => {
// Apply to all blog pages
await page.waitForSelector('.blog-content');
},
'products/*': async (page) => {
// Apply to all product pages
await page.click('.view-details');
await page.waitForSelector('.product-modal');
},
'/': async (page) => {
// Specific page
await page.evaluate(() => window.scrollTo(0, 500));
},
},
};Named Hooks
Create reusable hooks that can be referenced in page configs:
// vizzly.static-site.js
export default {
interactions: {
'scroll-to-footer': async (page) => {
await page.evaluate(() => {
window.scrollTo(0, document.body.scrollHeight);
});
},
},
pages: {
'/contact': {
interaction: 'scroll-to-footer',
},
},
};Pattern Matching
Patterns support glob-like syntax:
*- Match any characters except/**- Match any characters including/blog/*- Match all blog pagesdocs/**- Match all pages under docs**/*.html- Match all HTML files
Screenshot Naming
Screenshots are named based on the page path, with viewport information stored as properties for better grouping:
Name format: path-to-page (slashes replaced with hyphens)
Properties: Viewport metadata (viewport, viewportWidth, viewportHeight)
Examples:
- Name:
index, Properties:{ viewport: 'mobile', viewportWidth: 375, viewportHeight: 667 } - Name:
blog-post-1, Properties:{ viewport: 'desktop', viewportWidth: 1920, viewportHeight: 1080 } - Name:
docs-getting-started, Properties:{ viewport: 'tablet', viewportWidth: 768, viewportHeight: 1024 }
This approach allows Vizzly to group screenshots by viewport while keeping names clean and compatible with file system restrictions.
Visual Development Workflow
This plugin integrates static sites into Vizzly's visual development workflow, enabling both local TDD iteration and seamless team collaboration. The plugin automatically detects which mode to use:
TDD Mode (Local Development)
When a TDD server is running, screenshots are compared locally for fast iteration:
# Start TDD server
vizzly tdd start
# Capture screenshots (automatically uses TDD mode)
vizzly static-site ./dist
# View live results at http://localhost:47392Output:
ℹ 📍 TDD mode: Using local server
ℹ 🌐 Found 12 pages in ./dist
ℹ ✓ /@default
ℹ ✓ /blog/post-1@default
ℹ ✅ Captured 12 screenshots successfullyRun Mode (CI/CD & Cloud)
When a VIZZLY_TOKEN is set, screenshots are uploaded to the cloud for team review:
# Capture and upload to Vizzly cloud (automatically uses Run mode)
VIZZLY_TOKEN=your-token vizzly static-site ./distOutput:
ℹ ☁️ Run mode: Uploading to cloud
ℹ 🔗 https://app.vizzly.dev/your-org/project/builds/...
ℹ 🌐 Found 12 pages in ./dist
ℹ ✓ /@default
ℹ ✅ Captured 12 screenshots successfully
ℹ 🔗 View results: https://app.vizzly.dev/your-org/project/builds/...Mode Detection
The plugin automatically chooses the mode:
- TDD mode - If a TDD server is running (
.vizzly/server.jsonfound) - Run mode - If
VIZZLY_TOKENenvironment variable is set - Warning - If neither is available, warns and skips screenshots
No need to wrap with vizzly run - the plugin handles everything!
Supported Static Site Generators
- Gatsby - Build with
gatsby build, output inpublic/ - Astro - Build with
astro build, output indist/ - Jekyll - Build with
jekyll build, output in_site/ - Next.js - Static export with
next build && next export, output inout/ - Eleventy - Build with
eleventy, output in_site/ - Hugo - Build with
hugo, output inpublic/ - VuePress - Build with
vuepress build, output in.vuepress/dist/ - Docusaurus - Build with
docusaurus build, output inbuild/ - Any static site generator that produces HTML files
Example Workflows
Gatsby
# Build Gatsby site
npm run build
# Capture screenshots
vizzly static-site ./publicAstro
# Build Astro site
npm run build
# Capture screenshots with custom viewports
vizzly static-site ./dist --viewports "mobile:375x667,desktop:1920x1080"Next.js Static Export
# Build and export Next.js site
npm run build
# Capture screenshots
vizzly static-site ./outJekyll
# Build Jekyll site
bundle exec jekyll build
# Capture only blog pages
vizzly static-site ./_site --include "blog/**"CI/CD Integration
# .github/workflows/visual-tests.yml
name: Visual Tests
on: [push, pull_request]
jobs:
visual-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
# Build your static site
- run: npm install
- run: npm run build
# Run visual tests
- run: npx @vizzly-testing/cli static-site ./dist
env:
VIZZLY_TOKEN: ${{ secrets.VIZZLY_TOKEN }}Troubleshooting
Pages not found
Ensure your build has completed and check for sitemap.xml or HTML files:
ls dist/sitemap.xml
ls dist/**/*.htmlBrowser launch fails
Try adding browser arguments:
vizzly static-site ./dist --browser-args "--no-sandbox,--disable-dev-shm-usage"Screenshots are blank
If your page needs time to render, use interaction hooks:
interactions: {
'**': async (page) => {
await page.waitForSelector('.app-loaded', { visible: true });
},
}Sitemap URLs don't match
The plugin automatically converts sitemap URLs to relative paths. If you have custom URL structures, use HTML scanning instead:
pageDiscovery: {
useSitemap: false,
scanHtml: true,
}License
MIT © Stubborn Mule Software
