Keep e2e 65 and 67 green in the full suite after #410
feuerwerk / gate (push) Successful in 5m55s
feuerwerk / suite (push) Successful in 20m21s

Suite 755 for b17a924 was red in three places. Both e2e 65 and e2e 67
were green on their own. Two of the new checks did not fit into the
full run. The product is not at fault.

- e2e 66 (66s): the per-frame pixel read never stopped. splice(0)
  emptied the array, so the length bound was never reached. Each
  pixelAt leaves the stage shifted to its pixel until the next
  drawing. The editor, idle after Stop, kept it at (-710, -376), so
  the Play click of e2e 67 hit no object. The loop now ends on a flag
  while the run still draws each frame.
- e2e 65 (65k2, 65k3): the console panel keeps 500 lines and is never
  cleared in the suite. Lines of earlier steps pushed the first beats
  out, so the beats began at 1.3. The checks now read the harness's
  console log since Play, which has no limit.
- 65k2 also writes panelBusiest, the three most frequent other lines
  in the panel. The next CI run names the module that logs that much.

Tests (melektaus-atx):
- e2e 66+67 before the fix: 67 breaks off as in CI.
- e2e 66+67 with the fix: ALL PASSED, 52 checks.
- e2e 65 under a flood of 100 lines/s: ALL PASSED, 76 checks.
  The old reading under the same flood shows the CI picture.
- e2e 65+66+67: ALL PASSED, 126 checks (a first run had the known
  e2e 67 firstAt wobble, 0.1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-10-30 13:05:46 +01:00
1 parent b17a924157
commit 2333f66ba2
2 files changed
+22 -6

No files matched your search

+14 -5
View File
@@ -1052,6 +1052,7 @@ export async function song(t) {
},
});
const playbacks = () => json('__gm.sound.playbacks()');
const heardFrom = t.consoleLog.length;
await play();
const game = await waitFor(playbacks, (list) => list[0]?.planned.length >= 4, 60);
const [run] = game;
@@ -1102,10 +1103,18 @@ export async function song(t) {
// at 120 BPM, bar 2 again after bar 2's last beat as the loop goes round; On song marker
// runs each time round; the pause above held them with the clock. "late" is how long ago
// the beat was heard, and Song position, read then, stands that far into the beat.
const heardLines = async () =>
(await json('__gm.console.lines()'))
.map((line) => line.text)
.filter((text) => /(beat|marker) /.test(text));
// Read from the page's console as the harness keeps it since Play, not from the panel: the
// panel keeps the last 500 lines, and in the full suite other lines pushed beats out of it.
const heard = (text) => /(beat|marker) /.test(text);
const heardLines = async () => t.consoleLog.slice(heardFrom).filter(heard);
// What else the panel was filled with, the three lines most often there: says in the output of
// the check which leftover of an earlier step logs that much.
const panelBusiest = async () => {
const counts = new Map();
for (const { text } of await json('__gm.console.lines()'))
if (!heard(text)) counts.set(text.slice(0, 120), (counts.get(text.slice(0, 120)) ?? 0) + 1);
return [...counts].sort((a, b) => b[1] - a[1]).slice(0, 3);
};
const heardSome = await waitFor(
heardLines,
(lines) => lines.filter((l) => l.includes('marker Round')).length >= 2,
@@ -1124,7 +1133,7 @@ export async function song(t) {
counted.every((c, i) => c === expected[i]) &&
markersHeard.length >= 2 &&
beats.every((b) => b.late >= 0 && b.late <= 0.15 && Math.abs(b.fraction * 0.5 - b.late) < 0.02),
JSON.stringify({ beats, markersHeard: markersHeard.length }),
JSON.stringify({ beats, markersHeard: markersHeard.length, panelBusiest: await panelBusiest() }),
);
// 65k3. Music follows the game (#338): W held over a beat asks Switch song for "Half", bar 2 beat 3,
// on the next bar. The playing keeps its number on buses of its own, heard from that bar line
+8 -1
View File
@@ -794,14 +794,21 @@ export async function video(t) {
Math.abs(soughtPlayer.time - 0.5) < 0.05,
JSON.stringify({ sought, soughtHeld, soughtPlayer }),
);
// The reads end while the run still draws each frame: a read leaves the stage shifted to its pixel
// until the next drawing, and the editor, idle after Stop, would keep it so under every later
// click (e2e 67's Play missed).
await t.evaluate(`window.__vd66s = [];
window.__vd66sOn = true;
(function read() {
if (!window.__vd66sOn) return;
const r = __gm.gameRect('${STEERED}');
if (r) window.__vd66s.push(__gm.pixelAt(Math.round(r.x), Math.round(r.y)));
if (window.__vd66s.length < 150) requestAnimationFrame(read);
requestAnimationFrame(read);
})();`);
await press('g');
await sleep(2200);
await t.evaluate('window.__vd66sOn = false');
await sleep(100);
const playedFrames = await json('window.__vd66s.splice(0)');
const finished = t.consoleLog.slice(finishedFrom).filter((line) => line.includes('vd66 finished'));
await stop();