diff options
| author | Gabriel Schneider <[email protected]> | 2026-07-03 15:17:46 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-08-01 15:02:07 -0300 |
| commit | 6b4b1f76bb6bf969fb5106f95fb3f9ad077fac08 (patch) | |
| tree | 423fa58bc169d44d7581ab50970f154e962646ab /tests | |
| parent | d1ed5bd8f55935e6470c4a7559216119571a084f (diff) | |
| download | pardes-6b4b1f76bb6bf969fb5106f95fb3f9ad077fac08.tar.gz pardes-6b4b1f76bb6bf969fb5106f95fb3f9ad077fac08.zip | |
fixing mouse drag on web
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/browser_replay_dump.zon | 7 | ||||
| -rw-r--r-- | tests/browser_replay_e2e.mjs | 84 |
2 files changed, 88 insertions, 3 deletions
diff --git a/tests/browser_replay_dump.zon b/tests/browser_replay_dump.zon index fbac9067..bee296d7 100644 --- a/tests/browser_replay_dump.zon +++ b/tests/browser_replay_dump.zon @@ -4,7 +4,8 @@ .topbar = "pardes replay browser e2e", .theme = "dark", .columns = .{ - .{ .weight = 1, .panes = .{ 0, 1 } }, + .{ .weight = 1, .panes = .{ 0 } }, + .{ .weight = 1, .panes = .{ 1 } }, }, .panes = .{ .{ @@ -34,7 +35,7 @@ .kind = .terminal, .tag = "sh /tmp Del", .body = - \\$ zig build replay-wasm + \\$ zig build replay -Dtarget=wasm32-emscripten \\browser e2e marker 4200 , .scroll = 0, @@ -44,7 +45,7 @@ .terminal = .{ .cwd = "/tmp", .stream = - \\$ zig build replay-wasm + \\$ zig build replay -Dtarget=wasm32-emscripten \\browser e2e marker 4200 , }, diff --git a/tests/browser_replay_e2e.mjs b/tests/browser_replay_e2e.mjs index f0d85bf8..2d8e202c 100644 --- a/tests/browser_replay_e2e.mjs +++ b/tests/browser_replay_e2e.mjs @@ -170,6 +170,75 @@ function validateScreenshot(png) { console.log(`browser replay screenshot ok: ${png.width}x${png.height}, bright=${bright}, nonDark=${nonDark}, colored=${colored}`); } +function pixelRgb(png, x, y) { + const off = (y * png.width + x) * png.channels; + const r = png.rows[off]; + return { + r, + g: png.channels === 1 ? r : png.rows[off + 1], + b: png.channels === 1 ? r : png.rows[off + 2], + }; +} + +function countChangedPixels(a, b, region = {}) { + if (a.width !== b.width || a.height !== b.height) { + throw new Error(`png sizes differ: ${a.width}x${a.height} vs ${b.width}x${b.height}`); + } + const x0 = Math.max(0, Math.floor(region.x0 ?? 0)); + const y0 = Math.max(0, Math.floor(region.y0 ?? 0)); + const x1 = Math.min(a.width, Math.ceil(region.x1 ?? a.width)); + const y1 = Math.min(a.height, Math.ceil(region.y1 ?? a.height)); + let changed = 0; + for (let y = y0; y < y1; y += 1) { + for (let x = x0; x < x1; x += 1) { + const ap = pixelRgb(a, x, y); + const bp = pixelRgb(b, x, y); + const dr = Math.abs(ap.r - bp.r); + const dg = Math.abs(ap.g - bp.g); + const db = Math.abs(ap.b - bp.b); + if (dr + dg + db > 45 && Math.max(dr, dg, db) > 12) changed += 1; + } + } + return changed; +} + +async function screenshotPng(page) { + return parsePng(await page.screenshot({ fullPage: true })); +} + +async function waitForNextDraw(page, action) { + const before = await page.evaluate(() => window.__pardesReplayE2E?.draws ?? 0); + await action(); + await page.waitForFunction((draws) => (window.__pardesReplayE2E?.draws ?? 0) > draws, before, { timeout: 5000 }); + await page.waitForTimeout(50); +} + +async function findHoverBoundary(page, baseline) { + const canvasSize = await page.evaluate(() => { + const canvas = document.querySelector("canvas"); + return { width: canvas.clientWidth, height: canvas.clientHeight }; + }); + const y = Math.floor(canvasSize.height * 0.55); + const center = canvasSize.width / 2; + const offsets = []; + for (let dx = -48; dx <= 48; dx += 3) offsets.push(dx); + + for (const dx of offsets) { + const x = Math.round(center + dx); + await waitForNextDraw(page, () => page.mouse.move(x, y)); + const hover = await screenshotPng(page); + const changed = countChangedPixels(baseline, hover, { + x0: x - 20, + x1: x + 20, + y0: 20, + y1: canvasSize.height - 20, + }); + if (changed >= 80) return { x, y, changed, canvasSize }; + } + + throw new Error("browser replay hover did not visibly draw the dashed resize handle"); +} + const { server, url } = await serve(webDir); let cleanupPlaywright = async () => {}; let browser; @@ -263,6 +332,21 @@ try { }, backingScale, { timeout: 5000 }); await page.waitForFunction(() => window.__pardesReplayE2E?.draws >= 3, null, { timeout: 5000 }); + const baseline = await screenshotPng(page); + const hover = await findHoverBoundary(page, baseline); + console.log(`browser replay hover ok: changed=${hover.changed} x=${hover.x} y=${hover.y}`); + + const dragToX = Math.min(hover.canvasSize.width - 24, hover.x + 120); + await waitForNextDraw(page, () => page.mouse.down()); + await waitForNextDraw(page, () => page.mouse.move(dragToX, hover.y, { steps: 8 })); + await waitForNextDraw(page, () => page.mouse.up()); + const dragged = await screenshotPng(page); + const dragChanged = countChangedPixels(baseline, dragged); + if (dragChanged < 2500) { + throw new Error(`browser replay drag did not visibly resize panes: changed=${dragChanged}`); + } + console.log(`browser replay drag ok: changed=${dragChanged}`); + await page.screenshot({ path: screenshotPath, fullPage: true }); validateScreenshot(parsePng(await readFile(screenshotPath))); } finally { |
