c094eb88fa
Adds src/ (scripts, raw measurement logs, derived data, report source), tests/, LICENSE (MIT, code) and LICENSE-DATA.md (CC BY 4.0 for the survey's data; third-party terms). The report is updated to the current site; the v1 and v2 data hand-off files are unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
39 lines
3.0 KiB
JavaScript
39 lines
3.0 KiB
JavaScript
import { chromium } from 'playwright-core';
|
|
import { PAGE, HAND } from './paths.mjs';
|
|
const b = await chromium.launch({ executablePath: process.env.CH });
|
|
const errs = [], fails = [];
|
|
const p = await b.newPage({ viewport: { width: 1440, height: 900 } });
|
|
p.on('pageerror', e => errs.push(e.message)); p.on('console', m => { if (m.type() === 'error') errs.push(m.text()) });
|
|
await p.goto(PAGE('web/index.html'), { waitUntil: 'load' }); await p.waitForTimeout(2500);
|
|
const st = () => p.evaluate(() => ({ view: S.view, k: T[S.view].k, x: T[S.view].x, y: T[S.view].y, rot: globeRot.slice(), fit: FIT[S.view], dis: document.getElementById('treset').disabled }));
|
|
const near = (a, b) => Math.abs(a.k / b.k - 1) < .003 && Math.abs(a.x - b.x) < 1.5 && Math.abs(a.y - b.y) < 1.5;
|
|
for (const v of ['ae', 'globe', 'dp', 'merc']) {
|
|
if (v !== 'ae') { await p.click(`.models button[data-v="${v}"]`); await p.waitForTimeout(1300); }
|
|
let s0 = await st();
|
|
if (!s0.dis) fails.push(`${v}: Reset enabled on a fresh view`);
|
|
await p.click('#tzoom'); await p.waitForTimeout(900);
|
|
let s1 = await st();
|
|
const changed = !near(s1, s0) || (v === 'globe' && Math.hypot(s1.rot[0] - s0.rot[0], s1.rot[1] - s0.rot[1]) > 1);
|
|
if (!changed) fails.push(`${v}: Zoom to route changed nothing`);
|
|
if (s1.dis) fails.push(`${v}: Reset still disabled after zooming`);
|
|
await p.screenshot({ path: `out/zoom_${v}.png` });
|
|
await p.click('#treset'); await p.waitForTimeout(900);
|
|
let s2 = await st();
|
|
if (!near(s2, s2.fit)) fails.push(`${v}: Reset did not return to the fitted view ${JSON.stringify([s2.k, s2.fit.k])}`);
|
|
if (v === 'globe' && Math.hypot(s2.rot[0] + 160, s2.rot[1] - 25) > .5) fails.push(`globe: Reset left rotation at ${s2.rot}`);
|
|
if (!s2.dis) fails.push(`${v}: Reset not disabled after resetting`);
|
|
console.log(`${v}: zoom k ${s0.k.toFixed(1)} -> ${s1.k.toFixed(1)}, rot ${s0.rot.map(n=>n.toFixed(0))} -> ${s1.rot.map(n=>n.toFixed(0))}; reset -> k ${s2.k.toFixed(1)} rot ${s2.rot.map(n=>n.toFixed(0))}`);
|
|
}
|
|
// globe: drag, then reset must undo the rotation
|
|
await p.click('.models button[data-v="globe"]'); await p.waitForTimeout(1300);
|
|
await p.mouse.move(600, 400); await p.mouse.down(); await p.mouse.move(800, 300, { steps: 8 }); await p.mouse.up(); await p.waitForTimeout(100);
|
|
let d = await st(); if (d.dis) fails.push('globe: Reset disabled after dragging');
|
|
await p.click('#treset'); await p.waitForTimeout(900); d = await st();
|
|
if (Math.hypot(d.rot[0] + 160, d.rot[1] - 25) > .5) fails.push(`globe: Reset after drag left rotation ${d.rot}`);
|
|
// another route, zoomed on AE
|
|
await p.click('.models button[data-v="ae"]'); await p.waitForTimeout(1300);
|
|
await p.evaluate(() => { const a = LS.findIndex(s => s.name === 'Fortaleza'), c = LS.findIndex(s => s.name === 'Luanda'); select(LP.find(q => (q.a === a && q.b === c) || (q.a === c && q.b === a)).idx); });
|
|
await p.click('#tzoom'); await p.waitForTimeout(900); await p.screenshot({ path: 'out/zoom_ae_sacs.png' });
|
|
console.log('FAILS', JSON.stringify(fails)); console.log('ERRORS', JSON.stringify(errs));
|
|
await b.close();
|