I cinque video «Come si gioca» dentro il gioco: pulsante «Guarda il video» nell'aiuto di briscola, tressette, scopa, bocce e biliardo, player a tutto schermo con l'audio (il gioco e la musica si fermano, Esc torna al tavolo). video/pubblica.py li taglia dall'arrivo nel posto, li comprime per il web (~4,5 MB l'uno) e fa la copertina. Il favicon e i video copiati anche nell'immagine Docker (il Regolino online dava 404); test che ogni cartella di assets usata dal gioco sia nel Dockerfile
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A1dxvtsZx8NE9fwjXUNDBr
This commit is contained in:
@@ -91,6 +91,20 @@ try {
|
||||
await page.waitForSelector('#briscola-controls:not([hidden])');
|
||||
// Il tavolo ha la sua musica (il valzer delle carte), non quella dell'oratorio.
|
||||
await page.waitForFunction(() => music.want === 'assets/audio/carte.mp3');
|
||||
if (name === 'desktop-mouse') {
|
||||
// Il video «Come si gioca»: dall'aiuto del tavolo si apre il player, il gioco si ferma, Esc torna al tavolo.
|
||||
await page.click('#briscola-controls summary');
|
||||
await page.click('#briscola-controls .tutorial-open');
|
||||
await page.waitForSelector('#tutorial:not([hidden])');
|
||||
assert.match(await page.locator('#tutorial-video').getAttribute('src'), /assets\/video\/briscola\.mp4\?v=/);
|
||||
assert.equal(await page.locator('#tutorial-title').textContent(), 'Come si gioca: la briscola');
|
||||
assert.equal(await page.evaluate(() => music.hold), true, 'la musica del gioco tace');
|
||||
await page.screenshot({ path: `${out}/briscola-video.png` });
|
||||
await page.keyboard.press('Escape');
|
||||
assert.ok(await page.isHidden('#tutorial'));
|
||||
assert.equal(await page.evaluate(() => !music.hold && game.closeup?.id), 'briscola', 'si torna al tavolo');
|
||||
await page.click('#briscola-controls summary');
|
||||
}
|
||||
assert.ok(await page.isHidden('#bocce-controls'));
|
||||
const scene = await page.locator('#scene').boundingBox(), exit = await page.locator('#closeup-close').boundingBox();
|
||||
assert.ok(exit.y >= scene.y + scene.height, 'uscita fuori dal tavolo');
|
||||
|
||||
@@ -606,6 +606,19 @@ test('al Trebbio Andrea ci sale a piedi: la torre lo sa, e lui ha trovato la sua
|
||||
assert.ok(settle(g).some(s => s.who === 'castello' && s.text === 'Il castello.'));
|
||||
});
|
||||
|
||||
// Il favicon c'era in pagina ma non nell'immagine Docker (404 online, 26 ottobre): ogni cartella di assets che il gioco
|
||||
// usa deve essere fra quelle copiate, e ogni video «Come si gioca» deve esistere.
|
||||
test('ogni cartella di assets usata dal gioco finisce nell\'immagine Docker', async () => {
|
||||
const { readdirSync } = await import('node:fs');
|
||||
const root = new URL('../', import.meta.url);
|
||||
const copied = new Set(readFileSync(new URL('Dockerfile', root), 'utf8').match(/^COPY assets\/(\S+)\s/gm).map(l => l.split(' ')[1].slice(7)));
|
||||
const files = ['index.html', 'style.css', ...readdirSync(new URL('src/', root), { recursive: true }).filter(f => f.endsWith('.js')).map(f => 'src/' + f)];
|
||||
const used = new Set(files.flatMap(f => [...readFileSync(new URL(f, root), 'utf8').matchAll(/assets\/([a-z0-9_-]+)\//g)].map(m => m[1])));
|
||||
// raw e generated sono cartelle di lavoro, citate solo nei commenti.
|
||||
assert.deepEqual([...used].filter(d => !copied.has(d) && !['raw', 'generated'].includes(d)).sort(), []);
|
||||
for (const t of Object.values(story.tutorials)) for (const f of [t.src, t.poster]) assert.ok(existsSync(new URL(f, root)), f);
|
||||
});
|
||||
|
||||
test('i file che il Docker copia sono leggibili da tutti (nginx gira con un altro utente)', async () => {
|
||||
const { readdirSync, statSync } = await import('node:fs');
|
||||
const root = new URL('../', import.meta.url);
|
||||
|
||||
Reference in New Issue
Block a user