Recette 1e : titre du bilan sur l'issue, notation du moteur partout, boutons de 48 px en paysage, filtre en accent-soft, longue partie ; tests navigateur adaptés au bilan
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
ced004edb0
commit
663ef35b51
+46
-21
@@ -184,13 +184,21 @@ async function savedGameCount() {
|
||||
);
|
||||
}
|
||||
|
||||
/** Les événements d'un journal et son événement courant : la partie,
|
||||
* sans les analyses du moteur qui s'y rangent en arrière-plan (conseils,
|
||||
* analyse de partie, étapes 1d et 1e). */
|
||||
function played(journal) {
|
||||
return journal === null ? null : { events: journal.events, head: journal.head };
|
||||
}
|
||||
|
||||
/** Le journal enregistré, une fois les enregistrements en cours terminés
|
||||
* (l'application enregistre sans attendre) : deux lectures identiques. */
|
||||
* (l'application enregistre sans attendre) : deux lectures identiques de
|
||||
* la partie. */
|
||||
async function savedJournal() {
|
||||
let last = await readJournal();
|
||||
let last = played(await readJournal());
|
||||
for (let i = 0; i < 50; i++) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
const next = await readJournal();
|
||||
const next = played(await readJournal());
|
||||
if (JSON.stringify(next) === JSON.stringify(last)) {
|
||||
return next;
|
||||
}
|
||||
@@ -222,6 +230,10 @@ async function waitForPlayer() {
|
||||
if (!panel.hidden) {
|
||||
return panel.dataset.kind;
|
||||
}
|
||||
// Le bilan remplace le panneau de fin de partie (étape 1e).
|
||||
if (!document.getElementById("summary-veil").hidden) {
|
||||
return "over";
|
||||
}
|
||||
const usable = (id) => {
|
||||
const b = document.getElementById(id);
|
||||
return !b.hidden && !b.disabled;
|
||||
@@ -1523,13 +1535,23 @@ for (let actions = 0; ; actions++) {
|
||||
|
||||
// --------------------------------------------------------- Fin de partie
|
||||
|
||||
// Le panneau de fin de partie, puis le bilan à sa place une fois
|
||||
// l'analyse prête (étape 1e, testé en détail par bilan.mjs).
|
||||
await page.waitForSelector('#summary[data-ready="true"]', { timeout: 120_000 });
|
||||
const journal = await savedJournal();
|
||||
const result = `${await page.textContent("#panel-text")}, ${await page.textContent("#panel-detail")}`;
|
||||
check((await page.textContent("#panel-overline")) === "Fin de partie" &&
|
||||
/^(Vous gagnez|L'ordinateur gagne|Vous passez|L'ordinateur passe)/.test(
|
||||
await page.textContent("#panel-text")) &&
|
||||
/^\d+ points? pour (vous|lui)(, videau à \d+)?\.$/.test(await page.textContent("#panel-detail")),
|
||||
`panneau de fin de partie : ${result}`);
|
||||
/** Le titre du bilan et la phrase du résultat. */
|
||||
async function summaryResult() {
|
||||
const title = await page.textContent("#summary-title");
|
||||
const reading = await page.textContent("#summary-reading");
|
||||
const detail = /^(Vous avez passé son double : |L'ordinateur a passé votre double : )?\d+ points? pour (vous|lui)(, videau à \d+)?\./.exec(reading)?.[0] ?? reading;
|
||||
return `${title}, ${detail}`;
|
||||
}
|
||||
const result = await summaryResult();
|
||||
check((await page.textContent("#summary .overline")) === "Fin de partie" &&
|
||||
/^(Vous gagnez|L'ordinateur gagne)/.test(await page.textContent("#summary-title")) &&
|
||||
/^(Vous avez passé son double : |L'ordinateur a passé votre double : )?\d+ points? pour (vous|lui)(, videau à \d+)?\. /.test(
|
||||
await page.textContent("#summary-reading")),
|
||||
`bilan de fin de partie : ${result}`);
|
||||
check((await page.textContent("#prompt")) === "", "fin de partie : la consigne répète le panneau");
|
||||
log(
|
||||
`partie finie : ${result} (${countMoves(journal, "player")} coups du joueur, ` +
|
||||
@@ -1538,11 +1560,11 @@ log(
|
||||
const won = journal.events.at(-1).winner === "player";
|
||||
check((await vibrations()).at(-1) === (won ? "30,50,30,50,60" : "60"),
|
||||
`fin de partie : vibration ${(await vibrations()).at(-1)}`);
|
||||
check((await page.textContent("#panel-secondary")) === "Revoir la partie" &&
|
||||
(await page.textContent("#panel-primary")) === "Rejouer" &&
|
||||
(await page.textContent("#panel-settings")) === "Changer les réglages" &&
|
||||
(await page.getAttribute("#panel-settings", "href")) === "#/nouvelle-partie",
|
||||
"fin de partie : panneau sans « Revoir la partie », « Rejouer » et « Changer les réglages »");
|
||||
check((await page.textContent("#summary-analysis")) === "Voir l'analyse" &&
|
||||
(await page.textContent("#summary-primary")) === "Rejouer" &&
|
||||
(await page.textContent("#summary-settings")) === "Changer les réglages" &&
|
||||
(await page.getAttribute("#summary-settings", "href")) === "#/nouvelle-partie",
|
||||
"fin de partie : bilan sans « Voir l'analyse », « Rejouer » et « Changer les réglages »");
|
||||
await review("6-fin-de-partie");
|
||||
await page.setViewportSize({ width: 844, height: 320 });
|
||||
await sleep(150);
|
||||
@@ -1573,12 +1595,13 @@ log(skips > 0 ? `aucun coup possible ${skips} fois (${skipsByDice} en touchant l
|
||||
log(`vibrations demandées : ${(await vibrations()).length}`);
|
||||
await shot("4-fin-de-partie");
|
||||
|
||||
// « Revoir la partie » ferme le panneau ; « Rejouer » reste dans la barre
|
||||
// d'actions.
|
||||
await page.click("#panel-secondary");
|
||||
// Fermer le bilan laisse voir la partie finie, sans panneau ; « Rejouer »
|
||||
// reste dans la barre d'actions.
|
||||
await page.click("#summary-close");
|
||||
await page.waitForSelector("#summary-veil", { state: "hidden" });
|
||||
check(!(await page.isVisible("#panel")) && (await page.textContent("#again")) === "Rejouer" &&
|
||||
(await page.isVisible("#again")),
|
||||
"« Revoir la partie » : panneau toujours là, ou pas de « Rejouer »");
|
||||
"bilan fermé : panneau toujours là, ou pas de « Rejouer »");
|
||||
|
||||
step("mes parties");
|
||||
// Mes parties (IndexedDB), depuis le menu : une deuxième partie commencée,
|
||||
@@ -1628,14 +1651,16 @@ step("mes parties");
|
||||
}));
|
||||
throw new Error(`reprise bloquée : ${JSON.stringify(state)}`);
|
||||
});
|
||||
await page.waitForSelector("#panel");
|
||||
// La partie finie reprise : son bilan, déjà analysé, à la place du
|
||||
// panneau.
|
||||
await page.waitForSelector('#summary[data-ready="true"]', { timeout: 60_000 });
|
||||
const resumed = await savedJournal();
|
||||
check(JSON.stringify(resumed) === JSON.stringify(finished), "la première partie n'a pas été reprise");
|
||||
const shown = `${await page.textContent("#panel-text")}, ${await page.textContent("#panel-detail")}`;
|
||||
const shown = await summaryResult();
|
||||
check(shown === result, `écran différent après la reprise : ${shown}`);
|
||||
check((await page.evaluate(() => performance.getEntriesByType("navigation").length)) === loads,
|
||||
"la page a été rechargée");
|
||||
await page.click("#panel-secondary");
|
||||
await page.click("#summary-close");
|
||||
log(
|
||||
`mes parties : ${listed} parties listées (${branchCount} branche(s) pour la première), ` +
|
||||
`SGF exporté (${sgf.length} octets), première partie reprise sans rechargement`,
|
||||
|
||||
Reference in New Issue
Block a user