test: stabilize WebGL wait command click

This commit is contained in:
2026-07-29 05:52:55 +09:00
parent 4c9f299de7
commit d04accc9e1

View File

@@ -483,15 +483,32 @@ async function verifyBattlePointerFlow(page) {
assert(postMovement.waitBounds, 'Expected the wait command button after movement.');
await page.waitForTimeout(120);
await clickSceneBounds(page, 'BattleScene', postMovement.waitBounds);
await page.waitForFunction((unitId) => {
const battle = window.__HEROS_DEBUG__?.battle();
return (
battle?.turnPromptVisible === true &&
battle?.turnPromptMode === 'turn-end' &&
battle?.actedUnitIds?.includes(unitId)
const waitCommandClick = await clickBattleCommand(
page,
'wait'
);
try {
await page.waitForFunction((unitId) => {
const battle = window.__HEROS_DEBUG__?.battle();
return (
battle?.turnPromptVisible === true &&
battle?.turnPromptMode === 'turn-end' &&
battle?.actedUnitIds?.includes(unitId)
);
}, lastAllySetup.unitId);
} catch (error) {
const diagnostic =
await battleCommandPointerDiagnostic(
page,
waitCommandClick
);
throw new Error(
`The wait-command pointer click did not finish the final ally action: ${JSON.stringify(
diagnostic
)}`,
{ cause: error }
);
}, lastAllySetup.unitId);
}
const automaticTurnPrompt = await page.evaluate(() => window.__HEROS_DEBUG__?.battle()?.turnPrompt);
assert(
automaticTurnPrompt?.title === '모든 아군의 행동이 종료되었습니다.' &&
@@ -1923,6 +1940,146 @@ async function clickTurnPromptSecondary(page) {
return { button, point };
}
async function clickBattleCommand(page, command) {
await page.evaluate(
() =>
new Promise((resolve) =>
requestAnimationFrame(() =>
requestAnimationFrame(resolve)
)
)
);
const button = await page.evaluate(
(requestedCommand) => {
const scene =
window.__HEROS_GAME__?.scene.getScene(
'BattleScene'
);
const candidate = scene?.commandButtons?.find(
(entry) =>
entry.command === requestedCommand
);
const bounds =
candidate?.background?.getBounds?.();
return candidate && bounds
? {
command: candidate.command,
available: candidate.available,
active:
candidate.background.active,
visible:
candidate.background.visible,
inputEnabled:
candidate.background.input?.enabled ===
true,
bounds: {
x: bounds.x,
y: bounds.y,
width: bounds.width,
height: bounds.height
}
}
: null;
},
command
);
assert(
button?.command === command &&
button.available === true &&
button.active === true &&
button.visible === true &&
button.inputEnabled === true,
`Expected an active ${command} command button: ${JSON.stringify(
button
)}`
);
const point = await clickSceneBounds(
page,
'BattleScene',
button.bounds
);
return { button, point };
}
async function battleCommandPointerDiagnostic(
page,
click
) {
return page.evaluate((requestedClick) => {
const scene =
window.__HEROS_GAME__?.scene.getScene(
'BattleScene'
);
const canvas = document.querySelector('canvas');
const canvasBounds =
canvas?.getBoundingClientRect();
const pointer = scene?.input?.activePointer;
const buttons = (
scene?.commandButtons ?? []
).map((button) => {
const bounds =
button.background?.getBounds?.();
return {
command: button.command,
available: button.available,
active:
button.background?.active ?? false,
visible:
button.background?.visible ?? false,
inputEnabled:
button.background?.input?.enabled ===
true,
bounds: bounds
? {
x: bounds.x,
y: bounds.y,
width: bounds.width,
height: bounds.height
}
: null
};
});
return {
click: requestedClick,
battle:
window.__HEROS_DEBUG__?.battle?.() ??
null,
buttons,
commandMenuObjectCount:
scene?.commandMenuObjects?.filter(
(object) => object.active
).length ?? 0,
suppressNextLeftClick:
scene?.suppressNextLeftClick ?? null,
canvasBounds: canvasBounds
? {
x: canvasBounds.x,
y: canvasBounds.y,
width: canvasBounds.width,
height: canvasBounds.height
}
: null,
sceneSize: scene
? {
width: scene.scale.width,
height: scene.scale.height
}
: null,
activePointer: pointer
? {
x: pointer.x,
y: pointer.y,
downX: pointer.downX,
downY: pointer.downY,
upX: pointer.upX,
upY: pointer.upY,
isDown: pointer.isDown
}
: null
};
}, click);
}
async function turnPromptPointerDiagnostic(page, click) {
return page.evaluate((requestedClick) => {
const scene = window.__HEROS_GAME__?.scene.getScene('BattleScene');