GdzieWjade/scripts/smoke.mjs

58 lines
3.2 KiB
JavaScript
Raw Normal View History

2026-10-03 14:29:28 +02:00
// End-to-end smoke test against `pnpm preview` (http://localhost:4173). Run: node scripts/smoke.mjs
import { chromium } from 'playwright-core';
const URL = process.env.URL ?? 'http://localhost:4173/';
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1280, height: 900 }, locale: 'pl-PL' });
const errors = [];
page.on('pageerror', (e) => errors.push(`pageerror: ${e.message}`));
page.on('console', (m) => { if (m.type() === 'error') errors.push(`console: ${m.text()}`); });
let step = 0;
const ok = (cond, msg) => { step++; if (!cond) { console.error(`FAIL ${step}: ${msg}`); process.exitCode = 1; } else console.log(`ok ${step}: ${msg}`); };
await page.goto(URL, { waitUntil: 'networkidle' });
ok(await page.locator('text=Zaloguj się').first().isVisible(), 'login screen shown');
// resident flow: report -> appears in own place detail as unverified
await page.click('text=Zaloguj jako Anna Kowalska');
await page.waitForSelector('#q');
ok((await page.locator('text=Wyniki:').first().innerText()).includes('27'), 'places list loaded (~2.7k)');
await page.fill('#q', 'Pracownia Przykładowa');
await page.click('button[id^=place-]');
await page.waitForSelector('text=Szczegóły dostępności');
await page.click('text=Popraw lub uzupełnij >> nth=0');
await page.selectOption('#rep-attr', 'entrance');
await page.click('label[for=rep-v-no]');
await page.click('text=Zapisz zgłoszenie');
ok(await page.locator('text=Zgłoszenie zapisane').isVisible(), 'report saved and flagged unverified');
// settings persist per account
await page.click('nav >> text=Profil');
await page.selectOption('#set-size', '125');
await page.reload({ waitUntil: 'networkidle' });
ok((await page.evaluate(() => document.documentElement.style.fontSize)) === '125%', 'text size persisted across reload');
// official flow: queue shows pending reports, accept one -> place becomes verified
await page.click('nav >> text=Profil');
await page.click('text=Wyloguj');
await page.click('text=Zaloguj jako Maria Wiśniewska');
await page.waitForSelector('.kbb-kpis');
ok(await page.locator('text=0 / 82').first().isVisible(), 'dashboard shows operator data gap (0 / 82 stops)');
const pending = await page.locator('button:has-text("Zatwierdź")').count();
ok(pending >= 3, `moderation queue has ${pending} pending reports`);
await page.locator('button:has-text("Zatwierdź")').first().click();
ok((await page.locator('button:has-text("Zatwierdź")').count()) === pending - 1, 'accepting removes it from the queue');
// map pins + route render without worker errors
await page.click('nav >> text=Trasa');
await page.click('text=Sukiennice → Zamek Królewski na Wawelu');
await page.waitForSelector('text=Opis trasy tekstem');
await page.waitForTimeout(1500);
const canvas = await page.locator('canvas.maplibregl-canvas').count();
ok(canvas === 1, 'map canvas present');
ok(await page.locator('text=Bariery i uwagi na trasie').isVisible(), 'route summary + barriers listed');
ok(await page.locator('ol.usa-list li').count() > 3, 'text route steps listed');
await page.click('text=Trasa >> nth=0').catch(() => {});
ok(errors.filter((e) => !/GL Driver|favicon/.test(e)).length === 0, `no console errors ${JSON.stringify(errors.slice(0, 3))}`);
await browser.close();