# How to Perform a Visual QA Diff Between Original and Cloned Websites

> Learn how to perform a visual QA diff between original and cloned websites. Compare screenshots pixel-by-pixel using Playwright and pixelmatch for accurate AI Website Cloner results.

- Repository: [JCodesMore/ai-website-cloner-template](https://github.com/JCodesMore/ai-website-cloner-template)
- Tags: how-to-guide
- Published: 2026-06-28

---

**Capturing screenshots of both the original target site and the locally hosted Next.js clone, then comparing them pixel-by-pixel using tools like Playwright and pixelmatch, is the core method for visual QA diff in the AI Website Cloner Template.**

The **AI Website Cloner Template** is a full-stack Next.js project generator that mirrors target websites through an automated pipeline. Performing a **visual QA diff between original and cloned websites** ensures that the generated components accurately replicate the source design across all device viewports. This verification happens during the "Assembly & QA" phase, where agents use browser automation to detect visual regressions before finalizing the build.

## The Visual QA Pipeline in AI Website Cloner Template

According to the repository's [`README.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/README.md) (lines 94-95), the pipeline reaches **"Assembly & QA"** after the parallel build phase completes. This stage is where the visual comparison happens, validating that the cloned Next.js output matches the original site's appearance.

### Reconnaissance Phase: Baseline Capture

During the initial reconnaissance step, the system captures screenshots of the **original website** at every viewport size (desktop, tablet, and mobile). These baseline images are stored in `docs/design-references/` and serve as the authoritative reference for all subsequent comparisons.

### Assembly & QA Phase: Pixel Comparison

After the components are generated and the Next.js app is built, the pipeline launches the local development server (`npm run dev`). The same viewport configurations used during reconnaissance are applied to render the cloned site, producing a second set of screenshots. A **pixel-by-pixel diff** algorithm then highlights discrepancies between the original and cloned image sets.

## Implementing the Visual QA Diff Script

The repository implements visual QA through a TypeScript script that leverages **Playwright** for browser automation and **pixelmatch** for image comparison. Below is the complete implementation that reproduces the agent's QA workflow:

```typescript
// scripts/visual-qa.ts
import { chromium, expect } from '@playwright/test';
import pixelmatch from 'pixelmatch';
import { readFileSync, writeFileSync } from 'fs';
import { PNG } from 'pngjs';

// Helper to compare two PNG buffers
function diffImages(imgA: Buffer, imgB: Buffer, outPath: string) {
  const pngA = PNG.sync.read(imgA);
  const pngB = PNG.sync.read(imgB);
  const { width, height } = pngA;
  const diff = new PNG({ width, height });

  const mismatched = pixelmatch(
    pngA.data,
    pngB.data,
    diff.data,
    width,
    height,
    { threshold: 0.1 }
  );

  writeFileSync(outPath, PNG.sync.write(diff));
  return mismatched;
}

// Main routine – runs for a given URL and a list of viewports
async function runVisualQA(originalUrl: string, localUrl: string) {
  const browser = await chromium.launch();
  const page = await browser.newPage();

  const viewports = [
    { name: 'desktop', width: 1440, height: 900 },
    { name: 'tablet', width: 768, height: 1024 },
    { name: 'mobile', width: 375, height: 667 },
  ];

  for (const vp of viewports) {
    await page.setViewportSize({ width: vp.width, height: vp.height });

    // 1️⃣ Original site screenshot
    await page.goto(originalUrl, { waitUntil: 'networkidle' });
    const origPath = `tmp/orig-${vp.name}.png`;
    await page.screenshot({ path: origPath, fullPage: true });

    // 2️⃣ Cloned site screenshot
    await page.goto(localUrl, { waitUntil: 'networkidle' });
    const clonePath = `tmp/clone-${vp.name}.png`;
    await page.screenshot({ path: clonePath, fullPage: true });

    // 3️⃣ Diff
    const diffPath = `tmp/diff-${vp.name}.png`;
    const mismatched = diffImages(
      readFileSync(origPath),
      readFileSync(clonePath),
      diffPath
    );

    console.log(
      `${vp.name}: ${mismatched} pixel differences – diff saved to ${diffPath}`
    );
  }

  await browser.close();
}

// Example usage (run after `npm run dev`)
// Replace with the real target and the local dev URL.
runVisualQA('https://example.com', 'http://localhost:3000');

```

The `diffImages` function reads both PNG buffers, instantiates a new PNG canvas for the diff output, and invokes `pixelmatch` with a threshold of `0.1` to detect perceptible differences while ignoring minor anti-aliasing variations.

## Running Visual QA Locally and in CI

You can execute the visual QA diff through several methods depending on your environment:

- **Local development**: Run `npm run dev && ts-node scripts/visual-qa.ts` to start the cloned app and immediately capture comparison screenshots for desktop, tablet, and mobile viewports.

- **CI/CD integration**: Add a step in [`.github/workflows/ci.yml`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.github/workflows/ci.yml) that executes `ts-node scripts/visual-qa.ts` after `npm run build`. This fails the workflow if the pixel difference exceeds your defined threshold, guaranteeing visual fidelity before merging pull requests.

- **Diff-only mode**: Execute `node scripts/visual-qa.js --mode diff-only` to skip launching the dev server when baseline screenshots are already stored in `docs/design-references/`.

## Key Files and Configuration

Understanding the repository structure helps you locate and customize the visual QA components:

- **[`README.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/README.md)** (lines 94-95): Documents the "Assembly & QA" pipeline stage where visual diff occurs.
- **`docs/design-references/`**: Directory containing the original site screenshots that serve as the baseline for comparison.
- **[`src/app/layout.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/layout.tsx) and [`src/app/page.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/page.tsx)**: Core Next.js entry points rendered during the screenshot capture of the cloned site.
- **[`AGENTS.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/AGENTS.md)**: Source-of-truth configuration file where the visual QA step is defined as part of the agent skill workflow.

## Summary

- The **AI Website Cloner Template** performs visual QA diff during the "Assembly & QA" phase by comparing original site screenshots against the generated Next.js output.
- **Playwright** handles browser automation and screenshot capture, while **pixelmatch** provides the pixel-by-pixel comparison algorithm.
- Baseline images are stored in `docs/design-references/` and compared against `tmp/` outputs generated from the local dev server running at `localhost:3000`.
- The [`scripts/visual-qa.ts`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/scripts/visual-qa.ts) implementation supports desktop (1440×900), tablet (768×1024), and mobile (375×667) viewports by default.
- Integrating the script into CI pipelines ensures visual regressions fail builds before deployment.

## Frequently Asked Questions

### What tools does the AI Website Cloner Template use for visual QA diff?

The template uses **Playwright** for browser automation and screenshot capture, combined with **pixelmatch** (or alternatively `looks-same`) for the actual image comparison. These tools run within a TypeScript script that launches Chromium in headless mode to render both the original and cloned sites consistently.

### Where are the baseline screenshots stored for comparison?

Original site screenshots captured during the reconnaissance phase are stored in `docs/design-references/`. These serve as the immutable reference points that the cloned site screenshots are compared against during the QA phase.

### How do I adjust the sensitivity of the visual diff detection?

Modify the `threshold` parameter in the `pixelmatch` call within [`scripts/visual-qa.ts`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/scripts/visual-qa.ts). The default value of `0.1` ignores minor anti-aliasing differences; lowering this value increases sensitivity to catch smaller visual discrepancies, while raising it permits more tolerance for rendering variations.

### Can I run visual QA diff in a CI/CD pipeline?

Yes. Add a step to your workflow file (e.g., [`.github/workflows/ci.yml`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.github/workflows/ci.yml)) that runs `ts-node scripts/visual-qa.ts` after `npm run build`. Configure the script to exit with a non-zero status code when `mismatched` pixels exceed your tolerance level, which will fail the build and prevent deployment of visually inaccurate clones.