LayoutGuard is a command-line interface (CLI) tool designed to automate visual regression testing for web applications. It uses Playwright to drive a browser, execute user-defined scenarios, take screenshots, and compare them against previously approved "golden" snapshots.
π€ Note: This project was entirely generated using the Qwen3-Coder-Plus model, showcasing the capabilities of AI in software development.
- π Scenario-based Testing: Define test scenarios in simple TypeScript files.
- π Centralized Snapshot Management: Manage all artifacts in a root
.layoutguarddirectory. - β Interactive Approval Workflow: Review and approve new or changed snapshots.
- π€ CI/CD Integration: Exits with a non-zero status code if visual differences are detected.
- π― Flexible Targeting: Specify which element to capture in a screenshot.
- πΌοΈ Immediate Diff Viewing: Automatically open a visual diff image when a test fails.
npm install -g layoutguardOr use it directly with npx:
npx layoutguard initAfter initializing, you'll need to install the Playwright browsers you want to use:
npx playwright install chromium # For Chromium/Chrome
npx playwright install firefox # For Firefox
npx playwright install webkit # For SafariYou can also install specific versions or channels:
npx playwright install chromium@betanpx layoutguard initThis command sets up the necessary configuration and directory structure:
- Creates a
layoutguard.config.jsonfile - Creates a
.layoutguarddirectory withsnapshotsandfailuressubdirectories - Creates an
examplesdirectory with an example test file
After running init, you'll need to install the Playwright browsers you want to use:
npx playwright install chromium # For Chromium/Chrome
npx playwright install firefox # For Firefox
npx playwright install webkit # For SafariThe layoutguard.config.json file allows you to customize behavior:
{
"testMatch": ["**/*.spec.ts"],
"baseUrl": "http://localhost:3000",
"playwright": {
"browserName": "chromium"
},
"diffThreshold": 0.01
}testMatch: A glob pattern to find test files.baseUrl: The base URL to prepend to navigation actions.playwright.browserName: Which browser to use (chromium, firefox, or webkit).diffThreshold: Threshold for pixel difference (0 to 1). 0 means zero tolerance.
Test scenarios are defined in .spec.ts files. Each file exports a default object that conforms to the LayoutTest interface:
import { Page } from 'playwright';
import type { LayoutTest } from 'layoutguard';
const test: LayoutTest = {
name: 'Dashboard Add Form Popup',
scenario: async (page: Page) => {
await page.goto('/dashboard');
await page.click('#add-new-item-button');
await page.waitForSelector('.add-item-popup', { state: 'visible' });
await page.waitForTimeout(500); // Wait for CSS transitions
},
selector: '.add-item-popup', // Optional: specify an element to capture
};
export default test;name: A unique, descriptive name for the test. This is used for the snapshot filename.scenario: The sequence of actions to perform before taking the screenshot.selector: Optional. A CSS selector for the element to capture. If omitted, the full page is captured.
npx layoutguard check [test]This command executes visual regression tests:
- If
[test]is omitted, layoutguard will run all tests found. [test]can be either the test name (from the test object'snamefield) or a direct path to a test file (relative or absolute).- Use the
--show-diffoption to automatically open the visual diff image if a test fails.
npx layoutguard approve [test]This command runs the specified test(s) and replaces the existing golden snapshots with the newly generated ones:
- If
[test]is omitted, it will update snapshots for all found tests. [test]can be either the test name (from the test object'snamefield) or a direct path to a test file (relative or absolute).
my-awesome-project/
βββ .layoutguard/
β βββ snapshots/
β β βββ dashboard-add-form-popup.png // Golden snapshot
β β βββ another-test.png
β βββ failures/
β βββ dashboard-add-form-popup/
β βββ new.png // The latest screenshot
β βββ original.png // The golden snapshot it was compared against
β βββ diff.png // A visual diff of the two
βββ node_modules/
βββ src/
β βββ components/
β βββ dashboard/
β βββ Dashboard.tsx
β βββ dashboard.spec.ts // Test file co-located with component
βββ layoutguard.config.json
βββ package.json
βββ tsconfig.json
MIT