Il carosello dei Ringraziamenti si ferma, si sfoglia e ingrandisce le foto
Tutti gli sfondi del paese (game.reelPictures, uno per scena, col nome del posto) e ogni ritratto una volta sola (prima tre si ripetevano). Scorre da solo ma si ferma sotto il mouse, si trascina col mouse o col dito, si spinge con la rotella, con le frecce ai lati e con quelle della tastiera; un tocco su una foto la mostra grande col nome (il tocco si legge al rilascio: con la cattura del puntatore il clic non arriva all'immagine). Test della fila e prova nel browser. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GiECdBYE8csKd4tcFvwntT
This commit is contained in:
@@ -6,6 +6,8 @@ import { staticServer } from './helpers.mjs';
|
||||
import { mkdirSync, readFileSync } from 'node:fs';
|
||||
import assert from 'node:assert/strict';
|
||||
import { solution, route } from '../src/story/solution.js';
|
||||
import { story } from '../src/story/story.js';
|
||||
import { reelPictures } from '../src/engine/game.js';
|
||||
import { checkMultimedia } from './multimedia.browser.mjs';
|
||||
|
||||
const OUT = process.env.OUT ?? '/tmp/regolo-shots';
|
||||
@@ -120,6 +122,35 @@ try {
|
||||
await page.screenshot({ path: `${OUT}/01d-ritratto.png` });
|
||||
await page.click('#face');
|
||||
assert.ok(await page.isHidden('#face'));
|
||||
// Il carosello: tutte le immagini (due giri), scorre da solo, si ferma sotto il mouse, le frecce lo spingono di una
|
||||
// foto, un tocco su una foto la mostra grande col nome del posto.
|
||||
{
|
||||
const track = page.locator('#credits-reel .track');
|
||||
assert.equal(await track.locator('img').count(), reelPictures(story).length * 2, 'ogni sfondo e ogni ritratto, due giri');
|
||||
await page.mouse.move(5, 5);
|
||||
const x0 = await track.evaluate(t => t.scrollLeft);
|
||||
await page.waitForTimeout(600);
|
||||
const x1 = await track.evaluate(t => t.scrollLeft);
|
||||
assert.ok(x1 > x0, `il carosello scorre da solo (${x0} → ${x1})`);
|
||||
await track.hover({ position: { x: 20, y: 20 } });
|
||||
const x2 = await track.evaluate(t => t.scrollLeft);
|
||||
await page.waitForTimeout(500);
|
||||
assert.equal(await track.evaluate(t => t.scrollLeft), x2, 'sotto il mouse si ferma');
|
||||
await page.click('#credits-reel .arrow.next');
|
||||
await page.waitForTimeout(800);
|
||||
const x3 = await track.evaluate(t => t.scrollLeft);
|
||||
assert.ok(x3 - x2 > 150, `la freccia spinge di una foto (${x2} → ${x3})`);
|
||||
const third = track.locator('img').nth(2);
|
||||
const name = await third.getAttribute('alt');
|
||||
await third.click();
|
||||
assert.ok(await page.isVisible('#face img.scene'), 'la foto si vede grande');
|
||||
assert.equal(await page.textContent('#face figcaption'), name);
|
||||
await page.waitForFunction(() => document.querySelector('#face img').naturalWidth > 0, null, { timeout: 5000 });
|
||||
await page.screenshot({ path: `${OUT}/01e-carosello-zoom.png` });
|
||||
await page.keyboard.press('Escape');
|
||||
assert.ok(await page.isHidden('#face'), 'Esc chiude la foto grande, non i crediti');
|
||||
assert.ok(await page.isVisible('#credits'));
|
||||
}
|
||||
const onTop = await page.evaluate(() => { const r = document.getElementById('close-credits').getBoundingClientRect();
|
||||
return document.elementFromPoint(r.x + r.width / 2, r.y + r.height / 2)?.id === 'close-credits'; });
|
||||
assert.ok(onTop, 'i crediti stanno sopra il titolo, non dietro');
|
||||
|
||||
+15
-1
@@ -3,7 +3,7 @@ import assert from 'node:assert/strict';
|
||||
import { backgroundOrder } from '../src/engine/render.js';
|
||||
import { story } from '../src/story/story.js';
|
||||
import { solution } from '../src/story/solution.js';
|
||||
import { Game, VERBS, checkSave, introText, shuffledCredits, matchPlace } from '../src/engine/game.js';
|
||||
import { Game, VERBS, checkSave, introText, shuffledCredits, matchPlace, reelPictures } from '../src/engine/game.js';
|
||||
import { inside } from '../src/engine/geometry.js';
|
||||
import { existsSync, readFileSync } from 'node:fs';
|
||||
import { settle, exploreTorch } from './helpers.mjs';
|
||||
@@ -144,6 +144,20 @@ test('le fasi del giorno seguono la storia: pomeriggio, poi tramonto, poi sera,
|
||||
assert.deepEqual(seen, ids);
|
||||
});
|
||||
|
||||
test('il carosello dei Ringraziamenti: ogni sfondo una volta sola col nome del posto, tutti i ritratti, mai due ritratti vicini', () => {
|
||||
const reel = reelPictures(story);
|
||||
const backgrounds = new Set(Object.values(story.scenes).map(s => s.background).filter(Boolean));
|
||||
assert.deepEqual(reel.filter(p => p.kind === 'scene').map(p => p.src).sort(), [...backgrounds].sort(), 'tutti gli sfondi, senza doppioni');
|
||||
for (const p of reel) { assert.ok(p.name, `${p.src} senza nome`); assert.ok(existsSync(new URL('../' + p.src, import.meta.url)), `manca ${p.src}`); }
|
||||
const faces = story.credits.flatMap(c => c.names).filter(n => n.face);
|
||||
assert.deepEqual(reel.filter(p => p.kind !== 'scene').map(p => p.src).sort(), faces.map(n => n.face).sort(), 'tutti i ritratti, una volta');
|
||||
assert.ok(reel.some(p => p.kind === 'palio'), 'il palio ha la sua cornice');
|
||||
reel.forEach((p, i) => { if (i && p.kind !== 'scene') assert.equal(reel[i - 1].kind, 'scene', `due ritratti di fila: ${reel[i - 1].name}, ${p.name}`); });
|
||||
// Poche scene: i ritratti che non trovano posto chiudono comunque la fila.
|
||||
const few = reelPictures({ scenes: { a: { name: 'A', background: 'x.png' } }, credits: story.credits });
|
||||
assert.equal(few.length, 1 + faces.length);
|
||||
});
|
||||
|
||||
test('la ricerca della mappa: pezzi di parola, senza maiuscole, accenti e apostrofi', () => {
|
||||
assert.ok(matchPlace('Campomigliaio', 'camp'));
|
||||
assert.ok(matchPlace('Via de\' Medici', 'de medici'));
|
||||
|
||||
Reference in New Issue
Block a user