86 lines
2.6 KiB
TypeScript
86 lines
2.6 KiB
TypeScript
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
import puppeteer, { type Browser, type Page } from 'puppeteer';
|
|
import fs from 'fs';
|
|
import { PNG } from 'pngjs';
|
|
import pixelmatch from 'pixelmatch';
|
|
import { startDevServer, stopDevServer } from './utils';
|
|
|
|
let browser: Browser;
|
|
let page: Page;
|
|
|
|
const baseTestPath = 'tests/output';
|
|
const screenshotPath = `${baseTestPath}/testcard-current.png`;
|
|
const baselinePath = `${baseTestPath}/testcard-baseline.png`;
|
|
const diffPath = `${baseTestPath}/testcard-diff.png`;
|
|
|
|
describe('Test Card', () => {
|
|
beforeAll(async () => {
|
|
await startDevServer(); // boot SvelteKit dev server
|
|
browser = await puppeteer.launch();
|
|
page = await browser.newPage();
|
|
await page.goto('http://localhost:5888/card');
|
|
await page.waitForNetworkIdle();
|
|
await page.addStyleTag({
|
|
content: '.clock { opacity: 0; } * { transition: none !important; }'
|
|
});
|
|
await page.setViewport({ width: 1920, height: 1080 });
|
|
await page.evaluate(() => {
|
|
return new Promise((resolve) => {
|
|
requestAnimationFrame(() => {
|
|
requestAnimationFrame(resolve);
|
|
});
|
|
});
|
|
});
|
|
await fs.promises.mkdir(baseTestPath, { recursive: true });
|
|
await page.screenshot({ path: screenshotPath });
|
|
}, 60000);
|
|
|
|
afterAll(async () => {
|
|
await browser.close();
|
|
await stopDevServer();
|
|
});
|
|
|
|
it('matches baseline (visual regression)', () => {
|
|
if (!fs.existsSync(baselinePath)) {
|
|
fs.copyFileSync(screenshotPath, baselinePath);
|
|
console.log('Baseline image created. Re-run tests.');
|
|
return;
|
|
}
|
|
|
|
const img1 = PNG.sync.read(fs.readFileSync(baselinePath));
|
|
const img2 = PNG.sync.read(fs.readFileSync(screenshotPath));
|
|
const { width, height } = img1;
|
|
|
|
expect(img2.width).toBe(width);
|
|
expect(img2.height).toBe(height);
|
|
|
|
const diff = new PNG({ width, height });
|
|
const mismatches = pixelmatch(img1.data, img2.data, diff.data, width, height, {
|
|
threshold: 0.1
|
|
});
|
|
|
|
if (mismatches > 0) {
|
|
fs.writeFileSync(diffPath, PNG.sync.write(diff));
|
|
}
|
|
|
|
expect(mismatches).toBe(0);
|
|
});
|
|
|
|
// it('has a black vertical line exactly in the center', () => {
|
|
// const img = PNG.sync.read(fs.readFileSync(screenshotPath));
|
|
// const { width, height, data } = img;
|
|
// const midX = Math.floor(width / 2);
|
|
|
|
// function getPixel(x: number, y: number) {
|
|
// const idx = (width * y + x) << 2;
|
|
// return { r: data[idx], g: data[idx + 1], b: data[idx + 2] };
|
|
// }
|
|
|
|
// for (let y = 0; y < height; y++) {
|
|
// const { r, g, b } = getPixel(midX, y);
|
|
// expect(r).toBeLessThan(20);
|
|
// expect(g).toBeLessThan(20);
|
|
// expect(b).toBeLessThan(20);
|
|
// }
|
|
// });
|
|
});
|