Visual QA Diff Process: How to Compare Cloned Websites to Originals in ai-website-cloner-template

The visual QA diff is a mandatory pixel-perfect comparison workflow that validates the cloned Next.js site against the original URL before marking the build as complete.

In the JCodesMore/ai-website-cloner-template repository, visual QA diff serves as the final quality gate (Phase 5) of the clone pipeline. After all sections are assembled in src/app/page.tsx and the build passes (npm run build), the clone is not considered finished until it undergoes rigorous side-by-side visual verification against the source website.

What Is the Visual QA Diff Process?

The visual QA diff is defined in Phase 5 of the clone workflow (.windsurf/workflows/clone-website.md). This phase mandates opening the original URL and the locally built clone in equal-size windows to perform a systematic pixel-level comparison. The process validates that the Next.js implementation matches the original's layout, styling, responsive behavior, and interactive states across desktop and mobile breakpoints.

Unlike automated unit tests, this QA catches pixel-level differences that static type checking (npx tsc --noEmit) cannot detect, ensuring the cloned site is visually indistinguishable from the target.

Step-by-Step Visual QA Workflow

The workflow documentation prescribes an eight-step verification process:

1. Open Both Sites Side-by-Side

Open the original URL and the locally built clone (npm run build) in two equal-size browser windows. This establishes a fair visual baseline for comparison.

2. Capture Screenshots at Critical Breakpoints

Take full-page screenshots at two specific viewports:

  • Desktop: 1440px width
  • Mobile: 390px width

These breakpoints cover the primary responsive layouts where discrepancies most commonly occur.

3. Compare Section-by-Section

Starting from the top of the page, compare each visual block—hero sections, navigation bars, cards, footers—between the two screenshots. This isolation technique identifies exactly which component diverges from the original.

4. Identify and Resolve Discrepancies

For every visual mismatch:

  • Check the component specification file at docs/research/components/<name>.spec.md
  • If the spec is incorrect, re-extract the value from the browser using getComputedStyle()
  • If the spec is accurate, adjust the component implementation code

This ensures the source of truth (the spec file) remains accurate and the implementation follows it exactly.

5. Verify Interactive States

Click, hover, scroll, and trigger all interactive states on the clone (header transitions at scroll position 100+, tab switches, hover effects) and confirm they behave identically to the original. Visual QA covers dynamic behavior, not just static pixels.

6. Repeat for Mobile

Run the identical comparison process at the 390px mobile breakpoint. Responsive breakpoints often hide layout bugs invisible at desktop sizes, making this step mandatory.

7. Iterate Until Pixel-Perfect

Fix the offending component, rebuild (npm run build), and re-run the visual diff. Repeat this loop until zero differences remain between the original and clone.

8. Document the Results

Report the total sections built, components created, spec files written, assets downloaded, build status, and any remaining visual gaps as outlined in the Phase 5 workflow documentation.

Automating Pixel Comparison with Node.js and Pixelmatch

While manual inspection is required for interactive states, you can automate static pixel comparison using the pixelmatch library. Below is a Node.js script from the repository that compares desktop and mobile screenshots after capture:

// compare-screenshots.js
import fs from 'fs';
import { PNG } from 'pngjs';
import pixelmatch from 'pixelmatch';

// Helper to load a PNG file
function loadImage(path) {
  return new Promise((resolve, reject) => {
    const data = fs.createReadStream(path).pipe(new PNG()).on('parsed', function () {
      resolve(this);
    }).on('error', reject);
  });
}

// Compare two screenshots and write a diff image
async function compareScreenshots(originalPath, clonePath, diffPath) {
  const [origImg, cloneImg] = await Promise.all([
    loadImage(originalPath),
    loadImage(clonePath),
  ]);

  if (origImg.width !== cloneImg.width || origImg.height !== cloneImg.height) {
    throw new Error('Image dimensions differ – ensure both screenshots use the same viewport size.');
  }

  const diff = new PNG({ width: origImg.width, height: origImg.height });
  const numDiffPixels = pixelmatch(
    origImg.data,
    cloneImg.data,
    diff.data,
    origImg.width,
    origImg.height,
    { threshold: 0.1 } // adjust sensitivity as needed
  );

  diff.pack().pipe(fs.createWriteStream(diffPath));
  console.log(`Diff generated: ${diffPath} – ${numDiffPixels} pixels differ`);
}

// Run for both breakpoints
(async () => {
  await compareScreenshots('screenshots/original-desktop.png', 'screenshots/clone-desktop.png', 'diffs/desktop-diff.png');
  await compareScreenshots('screenshots/original-mobile.png', 'screenshots/clone-mobile.png', 'diffs/mobile-diff.png');
})();

To use this automation:

  1. Capture screenshots at 1440px and 390px viewports
  2. Install dependencies: npm install pixelmatch pngjs
  3. Execute: node compare-screenshots.js
  4. Review the generated diff images (diffs/desktop-diff.png, diffs/mobile-diff.png)—any non-transparent pixels indicate visual discrepancies requiring investigation

How Visual QA Fits Into the Architecture

The visual QA diff operates as the validation layer atop four architectural pillars:

Component-spec files (docs/research/components/<name>.spec.md) serve as the single source of truth for CSS values, content, and interaction models. Any visual mismatch points to either an inaccurate spec (extraction error) or code generation mistake.

Builder agents generate component code from these specs. The QA process verifies that the generated code renders identically to the extracted specifications.

Version-controlled work-trees allow each section to be built in isolation; the visual QA validates that the merged result in src/app/page.tsx behaves exactly like the original.

Automated build verification runs before and after each merge, but visual QA catches the pixel-level differences that TypeScript checks cannot.

Key Files in the Visual QA Pipeline

  • .windsurf/workflows/clone-website.md – Defines the Phase 5 visual QA process, checklist, and reporting format
  • README.md (Assembly & QA section) – Shows where visual QA fits in the overall pipeline after page assembly
  • docs/research/INSPECTION_GUIDE.md – Provides the initial checklist for capturing screenshots and design tokens that feed the QA diff
  • src/app/page.tsx – The entry point where assembled sections are wired together; visual QA validates this final rendered page
  • src/lib/utils.ts – Contains the cn utility for consistent class-name generation; mismatches often surface during visual QA

Summary

  • The visual QA diff is the mandatory Phase 5 quality gate that runs after src/app/page.tsx assembly and successful npm run build
  • Comparisons must occur at 1440px (desktop) and 390px (mobile) breakpoints using side-by-side screenshots
  • Discrepancies are resolved by checking docs/research/components/<name>.spec.md files and using getComputedStyle() for re-extraction
  • Interactive states (hover, scroll, click) require manual verification, while static layouts can use automated pixel comparison with pixelmatch
  • The loop of build, compare, fix, and rebuild continues until zero visual differences remain

Frequently Asked Questions

What breakpoints should I use for visual QA diff?

Use 1440px width for desktop and 390px width for mobile breakpoints. These dimensions are specified in the workflow documentation (.windsurf/workflows/clone-website.md) and cover the primary responsive layouts where the clone must match the original pixel-for-pixel.

How do I fix visual discrepancies found during the QA process?

First, consult the component specification file in docs/research/components/<name>.spec.md. If the spec contains incorrect values, re-extract the correct CSS using getComputedStyle() from the browser. If the spec is accurate, modify the component implementation code to match the specification exactly, then rebuild and re-run the diff.

Can the visual QA diff process be fully automated?

Partially. You can automate static pixel comparison using the pixelmatch Node.js script to compare screenshots at 1440px and 390px viewports. However, interactive state verification (hover effects, scroll transitions, click handlers) requires manual testing to ensure behavioral parity with the original site.

Where does visual QA fit in the ai-website-cloner pipeline?

Visual QA occurs in Phase 5, immediately after page assembly (merging work-tree branches into src/app/page.tsx) and automated build verification. It is the final gate before declaring the clone complete, ensuring that all assembled components render identically to the original website across all breakpoints and interaction states.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →