test(street-level): harden KartaView tests (mutation score 51% → 95%)

A mutation review (91, then 130 mutants) found tests that could not fail
(quick presses with synchronous fakes, a no-flight check with a provider
that never posed), and untested paths. New and rewritten tests kill 123 of
130 mutants; the 7 survivors are equivalent or harmless redraws.

- viewer: held-back loads for quick presses, stale sharp/flat loads,
  close mid-load, ends checks for an older photo, WebGL retried per mount,
  focus handed back, look direction kept on ›.
- provider: id-ordered pages with out-of-order indexes, page and probe
  failures retried, overtaken lookups, cones re-centred on ‹ ›, leftover
  imagery filters hide no line or cone, coverage hints, tile cache.
- source: 429 backoff and Retry-After under mock timers, hang timeouts,
  the nearest query's parameters. policy: storage-host injection, FOV 360,
  longitudes past ±180. panorama: a stub WebGL context (angles, lost
  context, re-measuring). lineCoverage.test.mjs: tooHigh hint, passes().
- core: openImage({frame:false}) and openNearest leave the camera
  (with a posing provider and a default-open control), KartaView's legend
  and wording end to end; viewerHost supportsRenderModes.
- Fixed tick-count waits replaced by an until() poll.
- Browser gate fixture: odd photos archived (409 at storage2, served by
  the proxy), the first lookup rate-limited (429, Retry-After: 0); the
  line-click step asserts the camera stays and › skips the archived photo.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Said TurkseverandClaude Opus 5.5 committed 2026-10-13 20:43:27 +01:00
1 parent bd0bbf5134
commit 3d4c6de21a
14 files changed
+1374 -81

No files matched your search

+39 -7
View File
@@ -850,7 +850,7 @@ async function main() {
},
);
await step(
'KartaView: a click on a line opens the nearest photo, cones follow its drive, and › steps along it',
'KartaView: a click on a line opens the nearest photo where the camera is, cones follow its drive, and › steps along it, past an archived photo',
async ({ skip }) => {
const along = Array.from({ length: 9 }, (_, i) => [
KV_LINE.lon,
@@ -871,6 +871,17 @@ async function main() {
if (!handle && !fixtures) return skip('no KartaView line in view');
assert.ok(handle, 'a KartaView line is pickable');
const at = await handle.jsonValue();
const camera = () =>
page.evaluate(() => {
const c = window.__godsEyeView.viewer.camera.positionCartographic;
return {
lon: (c.longitude * 180) / Math.PI,
lat: (c.latitude * 180) / Math.PI,
height: c.height,
};
});
const parked = await camera();
// The first lookup is rate-limited (fixtures): it waits and retries.
await page.mouse.click(at.x, at.y);
await page.waitForFunction(
() => {
@@ -894,10 +905,22 @@ async function main() {
}),
'the photo is on screen',
);
// A line click picks a spot: the camera stays where it was.
await sleep(1500);
const now = await camera();
assert.ok(
Math.abs(now.lon - parked.lon) < 1e-6 &&
Math.abs(now.lat - parked.lat) < 1e-6 &&
Math.abs(now.height - parked.height) < 0.5,
`the camera did not move: ${JSON.stringify({ parked, now })}`,
);
if (fixtures) {
assert.ok(
photos.some((photo) => photo.id === street.imageId),
`${street.imageId} is a fixture photo`,
const opened = photos.find((photo) => photo.id === street.imageId);
assert.ok(opened, `${street.imageId} is a fixture photo`);
assert.equal(
opened.archived,
false,
'the nearest photo that storage still has',
);
assert.ok(
await uiUntil(
@@ -922,12 +945,21 @@ async function main() {
),
'› opened the next photo',
);
if (fixtures)
if (fixtures) {
const skipped = photos.find(
(photo) => photo.id === String(Number(before) + 1),
);
assert.equal(
skipped?.archived,
true,
'the photo after is archived',
);
assert.equal(
(await ui()).street.imageId,
String(Number(before) + 1),
'the next photo along the drive',
String(Number(before) + 2),
'› skipped the archived photo to the next one along the drive',
);
}
},
);
if (fixtures)