SPB Git forge
3commits 1branches 0releases
417.0 KBsize
maindefault branch
10 days agolast push
TypeScript 66.5% Python 30.9% JavaScript 1.4% CSS 0.7%
2.9 KB · 49 lines javascript
Raw Blame History
1/**2 * Production QA sweep: every key route at 390 and 1440 px — HTTP status, console errors, horizontal overflow, screenshot.3 * Run: node qa/screens.mjs [BASE_URL]   (default http://localhost:8321)4 */5import { chromium } from '/Users/simon-pierreboucher/Desktop/uqo-eval/node_modules/playwright/index.mjs';6import { mkdirSync } from 'node:fs';78const BASE = process.argv[2] ?? 'http://localhost:8321';9const OUT = new URL('./screens/sweep/', import.meta.url).pathname;10mkdirSync(OUT, { recursive: true });1112const PAGES = ['/', '/explore', '/search?q=starlink', '/satellites', '/satellites?constellation=starlink&status=ACTIVE', '/satellite/iss-zarya-25544',13  '/satellite/sputnik-1-2', '/constellations', '/constellation/starlink', '/operators', '/operator/spacex', '/countries', '/country/canada',14  '/launches', '/launch/1998-067', '/launch-sites', '/debris', '/reentries', '/events', '/stats', '/rankings?metric=operators', '/sources',15  '/methodology', '/status', '/developers', '/about', '/privacy', '/terms', '/admin', '/does-not-exist'];16const WIDTHS = [390, 1440];17const browser = await chromium.launch();18let failures = 0;19for (const width of WIDTHS) {20  const mobile = width < 768;21  const ctx = await browser.newContext({ viewport: { width, height: mobile ? 844 : 900 }, deviceScaleFactor: 1, isMobile: mobile, hasTouch: mobile });22  const page = await ctx.newPage();23  for (const path of PAGES) {24    const errors = [];25    const onErr = (e) => errors.push(String(e));26    const onCon = (m) => { if (m.type() === 'error') errors.push(m.text()); };27    page.on('pageerror', onErr);28    page.on('console', onCon);29    const t0 = Date.now();30    const res = await page.goto(BASE + path, { waitUntil: 'networkidle', timeout: 60000 }).catch((e) => ({ status: () => `ERR ${e.message.slice(0, 40)}` }));31    await page.waitForTimeout(800);32    const overflow = await page.evaluate(() => document.documentElement.scrollWidth - document.documentElement.clientWidth).catch(() => -1);33    const expected = path === '/does-not-exist' ? 404 : path === '/admin' ? [200, 307] : 200;34    const status = res.status();35    const okStatus = Array.isArray(expected) ? expected.includes(status) : status === expected;36    const filtered = errors.filter((e) => !/WebGL|webgl|THREE\.WebGLRenderer|favicon/.test(e));37    const ok = okStatus && overflow <= 0 && filtered.length === 0;38    if (!ok) failures++;39    console.log(`${ok ? 'OK ' : 'FAIL'} ${width} ${status} ${String(Date.now() - t0).padStart(5)}ms overflow=${overflow} errors=${filtered.length} ${path}${filtered.length ? ' :: ' + filtered[0].slice(0, 120) : ''}`);40    await page.screenshot({ path: `${OUT}${width}-${path.replace(/[^a-z0-9]+/gi, '_').replace(/^_|_$/g, '') || 'home'}.png`, fullPage: false }).catch(() => undefined);41    page.off('pageerror', onErr);42    page.off('console', onCon);43  }44  await ctx.close();45}46await browser.close();47console.log(failures ? `\n${failures} failure(s)` : '\nall pages OK');48process.exit(failures ? 1 : 0);49