// L'Ingorgo Sonoro nel browser vero: il manifesto in piazza, l'effetto speciale, la festa nelle cinque scene con le // console che si mescolano, e il ritorno a maggio uscendo dal centro. // npm run browser:ingorgo — schermate in /tmp/regolo-ingorgo. import { chromium } from 'playwright'; import { mkdirSync } from 'node:fs'; import assert from 'node:assert/strict'; import { staticServer } from './helpers.mjs'; const out = process.env.OUT ?? '/tmp/regolo-ingorgo'; mkdirSync(out, { recursive: true }); const server = await staticServer(); let browser; const errors = []; try { browser = await chromium.launch({ args: ['--autoplay-policy=no-user-gesture-required', '--use-gl=angle', '--use-angle=swiftshader', '--enable-unsafe-swiftshader'] }); const page = await browser.newPage({ viewport: { width: 1280, height: 860 } }); page.on('pageerror', e => { errors.push(e.message); console.log('ERR', e.message); }); await page.goto(`http://127.0.0.1:${server.port}/`); await page.click('#splash'); await page.click('#new-game'); await page.click('#rione [data-rione="campomigliaio"]'); await page.click('#skip-intro'); await page.evaluate(async () => { const { settle } = await import('/tests/helpers.mjs'); window.settle = settle; settle(game); game.go('piazza', [250, 300]); settle(game); game.act('look', 'manifesto_ingorgo'); }); // Il manifesto si apre ingrandito; un clic sopra, e parte il desiderio. await page.waitForFunction(() => game.closeup?.id === 'manifesto_ingorgo' && game.closeup.t > 0.6, null, { timeout: 15000 }).catch(async e => { console.log(await page.evaluate(() => JSON.stringify({ c: game.closeup, sp: game.speech, q: game.queue, task: game.task, walking: game.walking, xy: [game.state.x, game.state.y] }))); throw e; }); await page.waitForFunction(() => game.closeup.t > 1.4, null, { timeout: 5000 }); await page.screenshot({ path: `${out}/0-manifesto.png` }); const box = await page.locator('#scene').boundingBox(); await page.mouse.click(box.x + box.width / 2, box.y + box.height / 2); // Le battute davanti al manifesto, poi l'effetto: a metà i fasci, poi il lampo, poi i coriandoli sulla festa. await page.waitForFunction(() => game.speech?.text.startsWith('Quanto darei'), null, { timeout: 15000 }); await page.screenshot({ path: `${out}/1-desiderio.png` }); await page.waitForFunction(() => game.closeup?.id === 'ingorgo' && game.closeup.t > 1.2, null, { timeout: 15000 }); await page.screenshot({ path: `${out}/2-fasci.png` }); await page.waitForFunction(() => game.closeup?.t > 2.5, null, { timeout: 5000 }); await page.screenshot({ path: `${out}/3-coriandoli.png` }); await page.waitForFunction(() => !game.closeup && game.state.flags.ingorgo && game.speech?.text.toLowerCase().includes('ingorgo'), null, { timeout: 5000 }); await page.screenshot({ path: `${out}/3b-festa.png` }); await page.evaluate(() => settle(game)); // La festa, scena per scena: lo sfondo di notte, e la musica di più console insieme. for (const [scene, at] of [['piazza', [250, 300]], ['via_antica_posta', [300, 300]], ['piazzetta_comune', [300, 330]], ['antica_posta_alta', [330, 300]], ['piazzetta', [330, 320]]]) { await page.evaluate(([s, a]) => { game.go(s, a); settle(game); }, [scene, at]); await page.waitForFunction(async () => (await import('/src/engine/render.js')).hasBackground(game.backdrop()), null, { timeout: 10000 }).catch(() => {}); await page.waitForTimeout(1500); const mixNow = await page.evaluate(() => [...music.tracks.values()].map(t => [t.src.split('/').pop(), Math.round(t.gain * 100)])); console.log(scene, JSON.stringify(mixNow)); assert.ok(mixNow.length >= 2, `${scene}: più console insieme`); await page.screenshot({ path: `${out}/4-${scene}.png` }); } // Uscendo dal centro si torna a maggio. await page.evaluate(() => { game.go('via_de_medici'); }); await page.waitForFunction(() => !game.state.flags.ingorgo && game.speech?.text.startsWith('Mi stropiccio'), null, { timeout: 5000 }); await page.screenshot({ path: `${out}/5-risveglio.png` }); assert.deepEqual(errors, []); console.log(`ok: schermate in ${out}`); } finally { await browser?.close(); server.kill(); }