Guides
URL Testing
Test any web page or application with ViSnap
Test any web page or application directly with the URL adapter - no Storybook required. This approach is perfect for testing marketing sites, landing pages, or web apps that don't use Storybook.
Prerequisites
- A running web application or accessible URLs
- ViSnap installed in your project
Installation
- Install ViSnap:
npm install -D visnap
- Initialize configuration:
npx visnap init
- Configure the URL adapter in
visnap.config.ts
:
// visnap.config.ts
import { type VisualTestingToolConfig } from '@visnap/protocol';
const config: VisualTestingToolConfig = {
adapters: {
// Browser settings - how screenshots are captured
browser: {
name: "@visnap/playwright-adapter",
options: {
launch: { browser: 'chromium', headless: true },
context: { colorScheme: 'light', reducedMotion: 'reduce' },
}
},
// Test source - what URLs to test
testCase: [
{
name: "@visnap/url-adapter",
options: {
urls: [
{ id: "homepage", url: "http://localhost:3000/" },
{ id: "about", url: "http://localhost:3000/about" },
{ id: "pricing", url: "http://localhost:3000/pricing" },
],
}
}
]
}
};
export default config;
- Start your application:
npm start
# or
npm run dev
- Create baseline screenshots:
npx visnap update
- Run visual tests:
npx visnap test
- Open report:
npx visnap open
URL-Level Options
Each URL requires an id
and url
. Optional fields allow per-URL customization:
{
id: "homepage",
url: "http://localhost:3000/",
title: "Homepage", // Display name for reports
viewport: { width: 1200, height: 800 }, // Custom viewport
threshold: 0.05, // Custom threshold (0.0-1.0)
screenshotTarget: "body", // Custom screenshot target
elementsToMask: [".sticky", "#ad"], // Mask dynamic elements
disableCSSInjection: true, // Disable global CSS injection
interactions: [ // Execute before screenshot
// See Interactive Testing guide for examples
],
}
Common options:
title: "Display Name"
- Custom name in reportsviewport: { width: 375, height: 667 }
- Mobile viewportthreshold: 0.01
- More strict comparison (1% difference)screenshotTarget: ".hero"
- Screenshot specific elementelementsToMask: [".dynamic"]
- Hide elements that change frequentlydisableCSSInjection: true
- Disable global CSS injectioninteractions: [...]
- Execute actions before screenshot
Pattern Filtering
Use include/exclude to select URLs by id using minimatch patterns:
options: {
urls: [
{ id: "homepage", url: "http://localhost:3000/" },
{ id: "about", url: "http://localhost:3000/about" },
{ id: "pricing", url: "http://localhost:3000/pricing" },
{ id: "admin-dashboard", url: "http://localhost:3000/admin" },
],
include: ["homepage", "about", "pricing"], // Only test these
exclude: ["*admin*"], // Exclude admin pages
}
Troubleshooting
URL not loading? Make sure your app is running and accessible:
curl http://localhost:3000/
Screenshots not working? Check your screenshot target exists:
screenshotTarget: "body" // ensure this element exists
Next Steps
- Interactive Testing - Test hover states and forms
- Screenshot Stabilization - Make tests more stable
- CI Integration - Run tests in your pipeline