fix: refine turn completion and interaction flow

This commit is contained in:
2026-07-20 12:32:17 +09:00
parent 31e1396ac8
commit 3961282d82
4 changed files with 449 additions and 96 deletions

View File

@@ -810,13 +810,13 @@ try {
throw new Error(`Expected positional bond bonuses and reduced counter damage: ${JSON.stringify(combatMechanicsProbe)}`);
}
const moveWaitTurnPromptStates = await page.evaluate(() => {
const finalAllyActionPromptStates = await page.evaluate(async () => {
const scene = window.__HEROS_GAME__?.scene.getScene('BattleScene');
const state = window.__HEROS_DEBUG__?.battle();
const lastAlly = state?.units?.find((unit) => unit.id === 'zhang-fei');
if (!scene || !state || !lastAlly) {
throw new Error('Expected Zhang Fei and battle scene for move-wait turn prompt test.');
throw new Error('Expected Zhang Fei and battle scene for final ally action prompt test.');
}
scene.hideTurnEndPrompt();
@@ -829,31 +829,79 @@ try {
const liveLastAlly = scene.debugUnitById(lastAlly.id);
if (!liveLastAlly) {
throw new Error('Expected live Zhang Fei unit for move-wait turn prompt test.');
throw new Error('Expected live Zhang Fei unit for final ally action prompt test.');
}
const originalPosition = { x: liveLastAlly.x, y: liveLastAlly.y };
const destination = scene.reachableTiles(liveLastAlly).find((tile) => tile.x !== liveLastAlly.x || tile.y !== liveLastAlly.y);
if (!destination) {
throw new Error('Expected a non-origin reachable tile for final ally movement timing test.');
}
scene.selectUnit(liveLastAlly);
scene.moveSelectedUnit(liveLastAlly.x, liveLastAlly.y);
const movement = scene.moveSelectedUnit(destination.x, destination.y);
const duringMoveState = window.__HEROS_DEBUG__?.battle();
await movement;
const postMoveState = window.__HEROS_DEBUG__?.battle();
scene.completeUnitAction(liveLastAlly, 'wait');
const postWaitState = window.__HEROS_DEBUG__?.battle();
return { postMoveState, postWaitState };
scene.input.keyboard?.emit('keydown-ENTER', { repeat: true });
const postRepeatedEnterState = window.__HEROS_DEBUG__?.battle();
const modalBlockerActive = scene.turnPromptObjects.some((object) => object.depth === 39 && object.input?.enabled === true);
const otherAlly = state.units.find((unit) => unit.faction === 'ally' && unit.hp > 0 && unit.id !== liveLastAlly.id);
const liveOtherAlly = otherAlly ? scene.debugUnitById(otherAlly.id) : undefined;
if (liveOtherAlly) {
scene.selectUnit(liveOtherAlly);
}
const postBlockedSelectionState = window.__HEROS_DEBUG__?.battle();
liveLastAlly.x = originalPosition.x;
liveLastAlly.y = originalPosition.y;
scene.positionUnitView(liveLastAlly);
return {
duringMoveState,
postMoveState,
postWaitState,
postRepeatedEnterState,
postBlockedSelectionState,
modalBlockerActive
};
});
if (
!moveWaitTurnPromptStates?.postMoveState?.turnPromptVisible ||
moveWaitTurnPromptStates.postMoveState.turnPromptMode !== 'post-move' ||
moveWaitTurnPromptStates.postMoveState.phase !== 'command' ||
moveWaitTurnPromptStates.postMoveState.pendingMove?.unitId !== 'zhang-fei' ||
moveWaitTurnPromptStates.postMoveState.actedUnitIds?.includes('zhang-fei')
finalAllyActionPromptStates?.duringMoveState?.phase !== 'animating' ||
finalAllyActionPromptStates.duringMoveState.commandMenuVisible ||
finalAllyActionPromptStates.duringMoveState.turnPromptVisible
) {
throw new Error(`Expected final ally move to show post-move turn prompt: ${JSON.stringify(moveWaitTurnPromptStates)}`);
throw new Error(`Expected movement animation to lock command input until arrival: ${JSON.stringify(finalAllyActionPromptStates)}`);
}
if (
!moveWaitTurnPromptStates.postWaitState?.turnPromptVisible ||
moveWaitTurnPromptStates.postWaitState.turnPromptMode !== 'turn-end' ||
moveWaitTurnPromptStates.postWaitState.phase !== 'idle'
finalAllyActionPromptStates?.postMoveState?.turnPromptVisible ||
finalAllyActionPromptStates.postMoveState.turnPromptMode !== null ||
!finalAllyActionPromptStates.postMoveState.commandMenuVisible ||
finalAllyActionPromptStates.postMoveState.phase !== 'command' ||
finalAllyActionPromptStates.postMoveState.pendingMove?.unitId !== 'zhang-fei' ||
finalAllyActionPromptStates.postMoveState.actedUnitIds?.includes('zhang-fei')
) {
throw new Error(`Expected move-wait completion to show turn-end prompt: ${JSON.stringify(moveWaitTurnPromptStates)}`);
throw new Error(`Expected final ally move to keep command selection open without a turn prompt: ${JSON.stringify(finalAllyActionPromptStates)}`);
}
if (
!finalAllyActionPromptStates.postWaitState?.turnPromptVisible ||
finalAllyActionPromptStates.postWaitState.turnPromptMode !== 'turn-end' ||
finalAllyActionPromptStates.postWaitState.commandMenuVisible ||
finalAllyActionPromptStates.postWaitState.phase !== 'idle' ||
!finalAllyActionPromptStates.postWaitState.actedUnitIds?.includes('zhang-fei')
) {
throw new Error(`Expected final ally action completion to show the turn-end prompt: ${JSON.stringify(finalAllyActionPromptStates)}`);
}
if (
!finalAllyActionPromptStates.postRepeatedEnterState?.turnPromptVisible ||
finalAllyActionPromptStates.postRepeatedEnterState.turnPromptMode !== 'turn-end' ||
finalAllyActionPromptStates.postRepeatedEnterState.activeFaction !== 'ally' ||
!finalAllyActionPromptStates.modalBlockerActive ||
!finalAllyActionPromptStates.postBlockedSelectionState?.turnPromptVisible ||
finalAllyActionPromptStates.postBlockedSelectionState.turnPromptMode !== 'turn-end' ||
finalAllyActionPromptStates.postBlockedSelectionState.selectedUnitId
) {
throw new Error(`Expected repeated Enter input and underlying battlefield selection to leave the turn-end prompt open: ${JSON.stringify(finalAllyActionPromptStates)}`);
}
await page.evaluate(() => {
@@ -1028,6 +1076,36 @@ try {
throw new Error(`Expected leader objective to resolve after victory: ${JSON.stringify(victoryState.objectives)}`);
}
const resultDoubleActivationState = await page.evaluate(() => {
const scene = window.__HEROS_GAME__?.scene.getScene('BattleScene');
if (!scene) {
throw new Error('Expected BattleScene for result double-activation guard test.');
}
scene.resultSettlementStatus = 'pending';
scene.refreshResultContinueCta();
scene.handleResultContinue();
scene.handleResultContinue();
return {
activeScenes: window.__HEROS_DEBUG__?.activeScenes?.() ?? [],
battle: window.__HEROS_DEBUG__?.battle()
};
});
const guardedContinueAction = resultDoubleActivationState.battle?.resultActions?.find((action) => action.kind === 'continue');
if (
resultDoubleActivationState.battle?.resultSettlement?.status !== 'complete' ||
resultDoubleActivationState.battle?.resultVisible !== true ||
!resultDoubleActivationState.activeScenes.includes('BattleScene') ||
resultDoubleActivationState.activeScenes.includes('StoryScene') ||
resultDoubleActivationState.activeScenes.includes('CampScene') ||
guardedContinueAction?.interactive !== false
) {
throw new Error(`Expected rapid result activation to finish settlement without leaving the result screen: ${JSON.stringify(resultDoubleActivationState)}`);
}
await page.waitForFunction(() => {
const continueAction = window.__HEROS_DEBUG__?.battle()?.resultActions?.find((action) => action.kind === 'continue');
return continueAction?.interactive === true;
});
await page.screenshot({ path: 'dist/verification-battle-result-victory.png', fullPage: true });
await page.mouse.click(738, 642);