test: separate asset fallback from WebGL presentation

This commit is contained in:
2026-07-29 14:11:31 +09:00
parent 0392a28a32
commit 147a366681

View File

@@ -510,25 +510,71 @@ async function waitForBattleReady(page, battleId) {
}, battleId, { timeout: 120000 }).then((handle) => handle.jsonValue());
}
async function waitForBattlePlayable(page, battleId) {
return page.waitForFunction((expectedBattleId) => {
try {
async function waitForBattlePlayable(page, battleId, timeout = 30000) {
try {
const handle = await page.waitForFunction((expectedBattleId) => {
try {
const state = window.__HEROS_DEBUG__?.battle();
return (
state?.scene === 'BattleScene' &&
state?.battleId === expectedBattleId &&
state?.phase === 'idle' &&
state?.mapBackgroundReady === true &&
(state?.combatAssets?.status === 'ready' || state?.combatAssets?.status === 'degraded') &&
state?.triggeredBattleEvents?.includes('opening') &&
state?.resultVisible === false
)
? { phase: state.phase, combatAssets: state.combatAssets }
: false;
} catch {
return false;
}
}, battleId, { timeout });
return handle.jsonValue();
} catch (error) {
const diagnostic = await page.evaluate(() => ({
activeScenes: window.__HEROS_DEBUG__?.activeScenes() ?? [],
battle: window.__HEROS_DEBUG__?.battle() ?? null
}));
throw new Error(
`Battle did not become playable during performance measurement: ${JSON.stringify({ battleId, timeout, diagnostic })}`,
{ cause: error }
);
}
}
async function waitForCombatAssetFallbackSettlement(page, battleId, kind) {
try {
const handle = await page.waitForFunction((expected) => {
const state = window.__HEROS_DEBUG__?.battle();
return (
state?.scene === 'BattleScene' &&
state?.battleId === expectedBattleId &&
state?.battleId === expected.battleId &&
state?.phase === 'idle' &&
state?.mapBackgroundReady === true &&
(state?.combatAssets?.status === 'ready' || state?.combatAssets?.status === 'degraded') &&
state?.triggeredBattleEvents?.includes('opening') &&
state?.combatAssets?.status === 'degraded' &&
state.combatAssets.pendingDeploymentConfirmation === false &&
state.combatAssets.settlementCount === 1 &&
state?.resultVisible === false
)
? { phase: state.phase, combatAssets: state.combatAssets }
? {
phase: state.phase,
combatAssets: state.combatAssets,
triggeredBattleEvents: state.triggeredBattleEvents
}
: false;
} catch {
return false;
}
}, battleId, { timeout: 30000 }).then((handle) => handle.jsonValue());
}, { battleId }, { timeout: 15000 });
return handle.jsonValue();
} catch (error) {
const diagnostic = await page.evaluate(() => ({
activeScenes: window.__HEROS_DEBUG__?.activeScenes() ?? [],
battle: window.__HEROS_DEBUG__?.battle() ?? null
}));
throw new Error(
`The ${kind} stall watchdog did not settle combat assets and resume deployment: ${JSON.stringify({ battleId, diagnostic })}`,
{ cause: error }
);
}
}
async function verifyCombatAssetStallFallback(browserInstance, baseUrl, kind) {
@@ -572,14 +618,22 @@ async function verifyCombatAssetStallFallback(browserInstance, baseUrl, kind) {
);
await clickBattleDeploymentStart(page);
const playable = await waitForBattlePlayable(page, 'first-battle-zhuo-commandery');
const fallbackSettlement = await waitForCombatAssetFallbackSettlement(
page,
'first-battle-zhuo-commandery',
kind
);
const playable = await waitForBattlePlayable(page, 'first-battle-zhuo-commandery', 90000);
const settled = await page.evaluate(() => window.__HEROS_DEBUG__?.battle()?.combatAssets ?? null);
assert(stalledUrl, `Expected ${kind} stall QA to intercept one deferred asset request.`);
assert(
fallbackSettlement.combatAssets?.status === 'degraded' &&
fallbackSettlement.combatAssets?.pendingDeploymentConfirmation === false &&
fallbackSettlement.combatAssets?.settlementCount === 1 &&
playable.combatAssets?.status === 'degraded' &&
settled?.pendingDeploymentConfirmation === false &&
settled?.settlementCount === 1,
`Expected ${kind} stall watchdog to settle once and resume pending combat: ${JSON.stringify({ playable, settled, stalledUrl })}`
`Expected ${kind} stall watchdog to settle once and resume pending combat: ${JSON.stringify({ fallbackSettlement, playable, settled, stalledUrl })}`
);
const fallback = await page.evaluate((assetKind) => {