From 2b58d7be74a466f2b6aa83264ef5eb9fea0fe342 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Tue, 30 Jun 2026 09:06:28 +1000 Subject: [PATCH] ifcviewer-web: smoke-test click-to-select highlight Third Playwright case: click dead-centre on the framed sample, assert the canvas changes (selection highlight rendered) with zero WebGPU errors. A broken async pick would hang init or leave the canvas unchanged. All three cases pass. Co-Authored-By: Claude Opus 4.8 --- src/ifcviewer-web/tests/smoke.spec.mjs | 41 ++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/ifcviewer-web/tests/smoke.spec.mjs b/src/ifcviewer-web/tests/smoke.spec.mjs index 7fab5a55a1..51743dc374 100644 --- a/src/ifcviewer-web/tests/smoke.spec.mjs +++ b/src/ifcviewer-web/tests/smoke.spec.mjs @@ -118,3 +118,44 @@ test('loads a user-picked sidecar through the Blob.slice byte-range path', async expect(gpuErrors, gpuErrors.join('\n')).toEqual([]); }); + +test('click selects an object and the highlight renders (async pick)', async ({ page }) => { + // Exercises the async object-pick readback: a click maps the pick staging + // buffer via a spontaneous callback (no blocking spin, which would hang the + // page), routes object_id through selection, and the next render flushes the + // highlight. A broken async pick either hangs init/never selects (canvas + // unchanged) or spams WebGPU errors. + const gpuErrors = []; + page.on('console', (msg) => { + const t = msg.text(); + if (/Uncaptured WebGPU error|is invalid|Not enough memory left/i.test(t)) { + gpuErrors.push(t); + } + }); + page.on('pageerror', (e) => gpuErrors.push('pageerror: ' + e.message)); + + await page.goto('/IfcViewerWeb.html'); + await page.waitForFunction( + () => !!(window.Module && window.Module._app_ptr), + null, + { timeout: 30_000 }, + ); + await page.waitForTimeout(1000); // sample framed + a few frames drawn + + // Click dead-centre, where the framed sample geometry sits. A plain + // down+up at one point is a pick (no drag), so it must change the canvas + // (selection highlight). If centre happens to miss, the assertion guards it. + const box = await page.locator('#viewer-canvas').boundingBox(); + const cx = box.x + box.width / 2; + const cy = box.y + box.height / 2; + const before = await shot(page); + await page.mouse.click(cx, cy); + await page.waitForTimeout(600); // async pick result + flush + render + const after = await shot(page); + expect( + Buffer.compare(before, after), + 'click did not change the canvas — async pick failed or hit empty space', + ).not.toBe(0); + + expect(gpuErrors, gpuErrors.join('\n')).toEqual([]); +});