test(gate-b): update Playwright assertions for cutout-on-checkerboard (#55)
- live-mask.spec.ts: replace green-overlay avgAlpha assertions with
checkerboard + slab pixel detection; add green-overlay color rejection
check; fix hasColorVariance false-positive with monochrome test image
- mask-ux.spec.ts: rename test to match new rendering (no green overlay)
- playwright.config.ts: set baseURL when webServer is used so page.goto('/')
resolves correctly in local dev
Fixes: issue #55 mask preview
This commit is contained in:
@@ -101,14 +101,33 @@ test.describe('LIVE mask fundamentals (issue #55)', () => {
|
|||||||
// b) Must have checkerboard pixels (removed background)
|
// b) Must have checkerboard pixels (removed background)
|
||||||
expect(stats.checkerPixels).toBeGreaterThan(0);
|
expect(stats.checkerPixels).toBeGreaterThan(0);
|
||||||
|
|
||||||
// c) Must have slab pixels (the wood showing through)
|
// c) Must have slab pixels (content showing through)
|
||||||
expect(stats.slabPixels).toBeGreaterThan(0);
|
expect(stats.slabPixels).toBeGreaterThan(0);
|
||||||
|
|
||||||
// d) Slab pixels must have color variance — real wood, not green wash
|
// d) No green tint pixels — the green overlay is gone.
|
||||||
expect(stats.hasColorVariance).toBe(true);
|
// This is the critical check: any (g>180, r<100, b<100) pixel means
|
||||||
|
// the old green-wash rendering is still active.
|
||||||
// e) No green tint pixels — the green overlay is gone
|
|
||||||
expect(stats.greenTintPixels).toBe(0);
|
expect(stats.greenTintPixels).toBe(0);
|
||||||
|
|
||||||
|
// e) Slab pixels must not be the old green overlay color (60,220,60).
|
||||||
|
// With the fix, slab pixels are the original photo pixels, not green paint.
|
||||||
|
const greenOverlayPixels = await page.evaluate(() => {
|
||||||
|
const canvas = document.querySelector('canvas.mask-canvas') as HTMLCanvasElement;
|
||||||
|
if (!canvas) return 0;
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
if (!ctx) return 0;
|
||||||
|
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||||
|
const { data } = imgData;
|
||||||
|
let count = 0;
|
||||||
|
for (let i = 0; i < data.length; i += 4) {
|
||||||
|
// Old green overlay: R~60, G~220, B~60, alpha>0
|
||||||
|
if (data[i] < 80 && data[i + 1] > 200 && data[i + 2] < 80 && data[i + 3] > 0) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
});
|
||||||
|
expect(greenOverlayPixels).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('2. Knobs respond fast on real photo — debounce working, no multi-second lag', async ({ page }) => {
|
test('2. Knobs respond fast on real photo — debounce working, no multi-second lag', async ({ page }) => {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ function ensureDir(dir: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test.describe('Mask UX timing & overlay', () => {
|
test.describe('Mask UX timing & overlay', () => {
|
||||||
test('overlay is translucent — photo visible under green mask', async ({ page }) => {
|
test('overlay renders — canvas has content, not blank', async ({ page }) => {
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
|
|
||||||
const fileInput = page.locator('#photo-file-input');
|
const fileInput = page.locator('#photo-file-input');
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export default defineConfig({
|
|||||||
use: {
|
use: {
|
||||||
trace: 'on-first-retry',
|
trace: 'on-first-retry',
|
||||||
screenshot: 'only-on-failure',
|
screenshot: 'only-on-failure',
|
||||||
baseURL: BASE_URL,
|
baseURL: BASE_URL || 'http://localhost:18080',
|
||||||
// Ignore self-signed TLS certs on deployed hosts.
|
// Ignore self-signed TLS certs on deployed hosts.
|
||||||
ignoreHTTPSErrors: true,
|
ignoreHTTPSErrors: true,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user