Files
leggenda-del-regolo/tests/bruciate.browser.mjs
T

68 lines
4.6 KiB
JavaScript

// Le bruciate nel browser vero: dai volontari della Smarronata, la manovella girata col mouse e col dito, il sacco.
// npm run browser:bruciate — schermate in /tmp/regolo-bruciate.
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-bruciate';
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'] });
for (const [name, mobile, viewport] of [['desktop', false, { width: 1280, height: 860 }], ['touch', true, { width: 844, height: 390 }]]) {
const page = await browser.newPage({ viewport, hasTouch: mobile, isMobile: mobile });
page.on('pageerror', e => errors.push(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');
settle(game); game.go('smarronata_1993'); settle(game);
game.act('talk', 'volontari'); settle(game);
game.choose(game.options().findIndex(o => o.text === 'Vi do una mano alla manovella?')); settle(game);
game.choose(game.options().findIndex(o => o.text === 'Alla bona.')); settle(game);
});
await page.waitForSelector('#bocce-controls:not([hidden])');
await page.waitForFunction(async () => (await import('/src/engine/render.js')).hasBackground('assets/closeups/smarronata-bruciatore.png'));
assert.equal(await page.locator('#bocce-throw').textContent(), 'Rovescia nel sacco');
assert.ok(await page.locator('#bruciate-help').isVisible());
assert.ok(!(await page.locator('#bocce-left').isVisible()), 'niente pulsanti Mira');
assert.ok(!(await page.locator('#bocce-power').isVisible()), 'niente forza');
await page.screenshot({ path: `${out}/${name}-ferma.png` });
const box = await page.locator('#scene').boundingBox(), P = (x, y) => [box.x + x / 640 * box.width, box.y + y / 360 * box.height];
// I giri attorno alla manovella: col mouse tenendo premuto, col dito trascinando (eventi di puntatore veri).
const loops = async (turns, steps = 16) => {
const at = i => { const a = i / steps * Math.PI * 2; return P(506 + Math.cos(a) * 40, 190 + Math.sin(a) * 40); };
if (mobile) {
const cdp = await page.context().newCDPSession(page), touch = (type, [x, y]) => cdp.send('Input.dispatchTouchEvent', { type, touchPoints: type === 'touchEnd' ? [] : [{ x, y }] });
await touch('touchStart', at(0));
for (let i = 1; i <= turns * steps; i++) await touch('touchMove', at(i));
await touch('touchEnd', at(0));
} else {
await page.mouse.move(...at(0)); await page.mouse.down();
for (let i = 1; i <= turns * steps; i++) await page.mouse.move(...at(i));
await page.mouse.up();
}
};
await loops(3);
const turned = await page.evaluate(() => Math.abs(game.closeup.drum));
assert.ok(turned > 6, `il cilindro ha girato: ${turned.toFixed(1)} rad`);
await page.screenshot({ path: `${out}/${name}-gira.png` });
// Il resto della cottura lo si fa fare al gioco a velocità giusta (le schermate con swiftshader sono lente).
await page.evaluate(() => { const c = game.closeup; c.speed = 4.5; for (const k of c.chestnuts) k.cook = 1.05; c.t = Math.max(c.t, 5); });
await page.waitForFunction(() => !document.querySelector('#bocce-throw').disabled);
await page.screenshot({ path: `${out}/${name}-cotte.png` });
if (mobile) await page.locator('#bocce-throw').tap(); else await page.locator('#bocce-throw').click();
await page.waitForFunction(() => game.closeup?.step === 'result', null, { timeout: 10000 });
assert.match(await page.locator('#bocce-status').textContent(), /bruciate buone su 18/);
await page.screenshot({ path: `${out}/${name}-sacco.png` });
await page.locator('#closeup-close').click();
await page.waitForFunction(() => game.state.flags.bruciate_fatte);
await page.close();
}
assert.deepEqual(errors, []);
console.log(`ok: schermate in ${out}`);
} finally { await browser?.close(); server.kill(); }