test(ui): retry a header press the rail shifted away, never a real miss

The diagnostics from d9b13c7 named the CI failure: the press landed on the
globe canvas, not the header, because the CCTV panel had moved 32 px down
between the hit check and the press (docked at 234, 266 at the press) -
something above it in the rail grows on the runner after load. A press that
provably missed the header (the page records the pointerdown target) says
nothing about dragging, so it is retried up to twice, logging what sat
above CCTV at dock and at the retry; a press that landed in the header and
did not lift still fails at once.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Said TurkseverandClaude Opus 5.5 committed 2026-10-05 16:07:27 +01:00
1 parent 0a3dc4c4ae
commit c320b47cca
1 file changed
+68 -34
+68 -34
View File
@@ -209,42 +209,76 @@ async function main() {
// Lift out: drag the header 200px left and 100px up. The window must lift
// from wherever the panel sits when the pointer goes down, so record that
// box in the page instead of trusting the earlier read.
await page.evaluate((id) => {
window.addEventListener(
'pointerdown',
(event) => {
const r = document.getElementById(id).getBoundingClientRect();
const target = event.target;
window.__qaPressBox = {
left: r.left,
top: r.top,
width: r.width,
// What the press landed on, so a failed lift says why.
target: `${target.tagName?.toLowerCase()}${target.id ? `#${target.id}` : ''}.${[...(target.classList || [])].join('.')}`,
inHeader: Boolean(target.closest?.(`#${id} .panel-header`)),
};
},
{ capture: true, once: true },
// What sits above CCTV in the rail, to name whatever shifted it.
const railAbove = () =>
page.evaluate((id) => {
const out = [];
for (const node of document.getElementById('right-context-rail')
?.children || []) {
if (node.id === id) break;
out.push(
`${node.id || node.className}:${Math.round(node.offsetHeight)}`,
);
}
return out.join(' ');
}, PANEL_ID);
const aboveAtDock = await railAbove();
/** One header drag; reports what the press landed on. */
const tryLift = async () => {
await page.evaluate((id) => {
window.addEventListener(
'pointerdown',
(event) => {
const r = document.getElementById(id).getBoundingClientRect();
const target = event.target;
window.__qaPressBox = {
left: r.left,
top: r.top,
width: r.width,
// What the press landed on, so a failed lift says why.
target: `${target.tagName?.toLowerCase()}${target.id ? `#${target.id}` : ''}.${[...(target.classList || [])].join('.')}`,
inHeader: Boolean(target.closest?.(`#${id} .panel-header`)),
};
},
{ capture: true, once: true },
);
}, PANEL_ID);
// Press only where the header really is: if the rail is still shifting,
// wait (bounded) for the title point to land on the CCTV header.
let grab = await headerPoint();
for (let tries = 0; tries < 20; tries++) {
const onHeader = await page.evaluate(
({ x, y, id }) =>
Boolean(
document.elementFromPoint(x, y)?.closest(`#${id} .panel-header`),
),
{ ...grab, id: PANEL_ID },
);
if (onHeader) break;
await new Promise((resolve) => setTimeout(resolve, 500));
grab = await headerPoint();
}
await drag(grab, -200, -100);
return {
grab,
lifted: await readPanel(),
pressed: await page.evaluate(() => window.__qaPressBox),
};
};
// A press the rail shifted out from under the header (seen on the CI
// runner: something above CCTV grows ~32 px after load) proves nothing
// about the drag, so it is retried; a press that landed in the header and
// did not lift fails at once.
let attempt = await tryLift();
for (let retry = 0; retry < 2; retry++) {
if (attempt.lifted.floating || attempt.pressed?.inHeader) break;
console.log(
`note: the press missed the header (on ${attempt.pressed?.target}; rail above CCTV ${aboveAtDock} -> ${await railAbove()}); retrying`,
);
}, PANEL_ID);
// Press only where the header really is: if the rail is still shifting,
// wait (bounded) for the title point to land on the CCTV header.
let grab = await headerPoint();
for (let tries = 0; tries < 20; tries++) {
const onHeader = await page.evaluate(
({ x, y, id }) =>
Boolean(
document.elementFromPoint(x, y)?.closest(`#${id} .panel-header`),
),
{ ...grab, id: PANEL_ID },
);
if (onHeader) break;
await new Promise((resolve) => setTimeout(resolve, 500));
grab = await headerPoint();
await new Promise((resolve) => setTimeout(resolve, 1000));
attempt = await tryLift();
}
await drag(grab, -200, -100);
const lifted = await readPanel();
const pressed = await page.evaluate(() => window.__qaPressBox);
const { grab, lifted, pressed } = attempt;
assert.equal(
lifted.floating,
true,