mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
fix(street-level): KartaView PR review — context loss mid-load, chunked reads, source switches, a11y
From the IC8 review of #1121 (2 P2, 7 P3; each with a test that fails on the old code): P2 - A WebGL context lost while a newer panorama loaded left a black viewer and a 'successful' open: the panorama now builds on the new canvas (or falls back to its front view). - The streaming body read every real answer takes was tested with one chunk only: answers split mid-character are reassembled; the shared test fake now streams, so every source test runs the production path. P3 - Lighting another source by its chip (params) now stops a running lookup and clears its spinner and error, as setProviderEnabled did; a restore that changes nothing leaves them alone. - Panoramas decode off the main thread (ImageBitmap, RGBA upload: ~90 ms → ~15 ms at 4,096 px on a phone-class CPU) and are 2,048 px docked, 4,096 once the viewer grows; a closed viewer keeps a 1×1 texture. - The lit KARTAVIEW chip label is #8f8aff (~6:1; #635bff was 3.7:1). - The viewer's keyboard focus ring is drawn above the photo. - Tests: a second context loss and a drag on the new canvas; the look direction kept across a loss; a page's 30 s first try. - The browser gate loses a real WebGL context in the 360° step and checks the 429 lookup was asked again (the fixture counter is reset first). Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
97a1a667de
commit
c99eb93174
12 files changed
+512
-26
No files matched your search
@@ -42,7 +42,9 @@ import {
|
||||
describeKartaViewCall,
|
||||
KV_LINE,
|
||||
KV_SEQUENCE_ID,
|
||||
kartaViewLookups,
|
||||
kartaViewPhotos,
|
||||
resetKartaViewFixture,
|
||||
} from './fixtures/street-level/kartaView.mjs';
|
||||
|
||||
const PANEL_ID = 'street-level-panel';
|
||||
@@ -751,6 +753,8 @@ async function main() {
|
||||
* draped map so a line is where it is drawn; leaves Mapillary lit.
|
||||
*/
|
||||
async function kartaViewSteps() {
|
||||
// The first lookup from here on is the rate-limited one.
|
||||
resetKartaViewFixture();
|
||||
const ui = () =>
|
||||
page.evaluate(() =>
|
||||
window.__godsEyeView.dataManager.layers
|
||||
@@ -895,6 +899,11 @@ async function main() {
|
||||
const street = (await ui()).street;
|
||||
if (!fixtures && /No street-level imagery/.test(street.error || ''))
|
||||
return skip('no KartaView photo near the line');
|
||||
if (fixtures)
|
||||
assert.ok(
|
||||
kartaViewLookups() >= 2,
|
||||
`the rate-limited lookup was asked again (${kartaViewLookups()} lookups)`,
|
||||
);
|
||||
assert.equal(street.error, null, `viewer error: ${street.error}`);
|
||||
assert.equal(street.providerId, 'kartaview');
|
||||
assert.equal(street.renderModes, true, 'FIT / FILL for a flat photo');
|
||||
@@ -964,7 +973,7 @@ async function main() {
|
||||
);
|
||||
if (fixtures)
|
||||
await step(
|
||||
'KartaView: a 360° photo opens on the panorama without FIT / FILL, and dragging turns it',
|
||||
'KartaView: a 360° photo opens on the panorama without FIT / FILL, dragging turns it, and it survives a lost WebGL context',
|
||||
async () => {
|
||||
const pano = photos.find((photo) => photo.isPano);
|
||||
await page.evaluate((id) => {
|
||||
@@ -1004,12 +1013,56 @@ async function main() {
|
||||
await uiUntil((v, was) => v.street.bearing !== was, bearing),
|
||||
'dragging the panorama turned its bearing',
|
||||
);
|
||||
// A GPU reset: the panorama comes back on a new canvas, and drags.
|
||||
assert.ok(
|
||||
await page.evaluate(() => {
|
||||
const canvas = document.querySelector('.sl-kv-pano');
|
||||
window.__kvLostCanvas = canvas;
|
||||
const lose = canvas
|
||||
.getContext('webgl')
|
||||
?.getExtension('WEBGL_lose_context');
|
||||
lose?.loseContext();
|
||||
return Boolean(lose);
|
||||
}),
|
||||
'the browser can lose a WebGL context on purpose',
|
||||
);
|
||||
assert.ok(
|
||||
await settle(
|
||||
page,
|
||||
() => {
|
||||
const canvas = document.querySelector('.sl-kv-pano');
|
||||
return (
|
||||
canvas &&
|
||||
canvas !== window.__kvLostCanvas &&
|
||||
!canvas.hidden &&
|
||||
canvas.width > 1
|
||||
);
|
||||
},
|
||||
null,
|
||||
{ timeout: 30_000 },
|
||||
),
|
||||
'the panorama is drawn again on a new canvas',
|
||||
);
|
||||
const after = await ui();
|
||||
assert.equal(after.street.imageId, pano.id);
|
||||
assert.equal(after.street.isPano, true);
|
||||
assert.equal(after.street.error, null);
|
||||
const turned = after.street.bearing;
|
||||
await page.mouse.move(box.x, box.y);
|
||||
await page.mouse.down();
|
||||
for (let i = 1; i <= 8; i++)
|
||||
await page.mouse.move(box.x + i * 15, box.y);
|
||||
await page.mouse.up();
|
||||
assert.ok(
|
||||
await uiUntil((v, was) => v.street.bearing !== was, turned),
|
||||
'the new canvas drags',
|
||||
);
|
||||
},
|
||||
);
|
||||
else
|
||||
await skipStep(
|
||||
'fixtures only',
|
||||
'KartaView: a 360° photo opens on the panorama without FIT / FILL, and dragging turns it',
|
||||
'KartaView: a 360° photo opens on the panorama without FIT / FILL, dragging turns it, and it survives a lost WebGL context',
|
||||
);
|
||||
await page.evaluate(() =>
|
||||
window.__godsEyeView.dataManager.layers
|
||||
|
||||
Reference in new issue
Block a user