// Regression for the SW viewer work (2026-10-19): the existing SW/Header Stories must render pixel-identical // before (base Storybook) and after (this branch) at several widths. // Usage: node packages/sw/tests/viewer-regression.browser.mjs import { createRequire } from 'node:module' import { mkdir, writeFile } from 'node:fs/promises' import path from 'node:path' const runtime = process.env.SW_RUNTIME_MODULES ?? 'C:/Users/user/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules' const require = createRequire(path.join(runtime, 'index.js')) const { chromium } = require('playwright') const { PNG } = require('pngjs') const pixelmatch = require('pixelmatch').default ?? require('pixelmatch') const [base, next, outArg] = process.argv.slice(2) const out = path.resolve(outArg ?? 'docs/sw/viewer-qa/regression') await mkdir(out, { recursive: true }) const ids = ['overview', 'interactive-states', 'logo-slot', 'document-dropdown', 'responsive-more', 'k-guide', 'property-panel-compare', 'composed-controls', 'document-open', 'hidden-sub-controls', 'detail-buttons'] const widths = [1920, 1180, 768] const browser = await chromium.launch({ headless: true, executablePath: process.env.SW_CHROME_PATH ?? 'C:/Program Files/Google/Chrome/Application/chrome.exe' }) const shot = async (url, width) => { const page = await browser.newPage({ viewport: { width, height: 1000 }, reducedMotion: 'reduce' }) await page.goto(url) await page.waitForSelector('#storybook-root > *') await page.evaluate(() => document.fonts.ready) await page.waitForTimeout(400) const buffer = await page.screenshot({ fullPage: true, animations: 'disabled' }) await page.close() return PNG.sync.read(buffer) } const results = [] for (const id of ids) for (const width of widths) { const url = root => `${root}/iframe.html?id=sw-header--${id}&viewMode=story` const [a, b] = [await shot(url(base), width), await shot(url(next), width)] const same = a.width === b.width && a.height === b.height let diff = same ? 0 : -1 if (same) { const image = new PNG({ width: a.width, height: a.height }) diff = pixelmatch(a.data, b.data, image.data, a.width, a.height, { threshold: 0 }) if (diff) await writeFile(path.join(out, `${id}-${width}-diff.png`), PNG.sync.write(image)) } results.push({ id, width, size: `${a.width}x${a.height} / ${b.width}x${b.height}`, diffPixels: diff, result: diff === 0 ? 'PASS' : 'FAIL' }) console.log(`${diff === 0 ? 'PASS' : 'FAIL'} sw-header--${id} @${width} diff ${diff}`) } await browser.close() await writeFile(path.join(out, 'regression.json'), JSON.stringify({ base, next, results }, null, 2) + '\n') const failed = results.filter(item => item.result !== 'PASS').length console.log(`${results.length - failed}/${results.length} PASS`) process.exit(failed ? 1 : 0)