feat: preview sortie lineup swaps
This commit is contained in:
@@ -399,18 +399,110 @@ try {
|
||||
`Expected all 23 campaign officers to use loaded lightweight portrait cards: ${JSON.stringify(missingMidFormationPortraits)}`
|
||||
);
|
||||
|
||||
await page.mouse.move(530, 260);
|
||||
await page.waitForFunction(() => Boolean(window.__HEROS_DEBUG__?.camp()?.sortieHoveredUnitId), undefined, { timeout: 30000 });
|
||||
const hoveredPortraitUnitId = await page.evaluate(() => window.__HEROS_DEBUG__?.camp()?.sortieHoveredUnitId);
|
||||
const midFormationSelectedBefore = [...(midFormationPortraitState?.selectedSortieUnitIds ?? [])];
|
||||
const midFormationCampaignSelectedBefore = [...(midFormationPortraitState?.campaign?.selectedSortieUnitIds ?? [])];
|
||||
await page.mouse.click(210, 447);
|
||||
await page.waitForFunction(() => window.__HEROS_DEBUG__?.camp()?.sortieFocusedUnitId === 'ma-dai', undefined, { timeout: 30000 });
|
||||
const swapFocusState = await page.evaluate(() => window.__HEROS_DEBUG__?.camp());
|
||||
assert(
|
||||
JSON.stringify(swapFocusState?.selectedSortieUnitIds) === JSON.stringify(midFormationSelectedBefore) &&
|
||||
JSON.stringify(swapFocusState?.campaign?.selectedSortieUnitIds) === JSON.stringify(midFormationCampaignSelectedBefore),
|
||||
`Expected focusing Ma Dai to preserve the actual sortie roster: ${JSON.stringify(swapFocusState?.selectedSortieUnitIds)}`
|
||||
);
|
||||
|
||||
await page.mouse.move(530, 544);
|
||||
await page.waitForFunction(() => {
|
||||
const state = window.__HEROS_DEBUG__?.camp();
|
||||
return state?.sortieHoveredUnitId === 'guan-yu' && state?.sortieComparisonPreview?.source === 'hover-swap';
|
||||
}, undefined, { timeout: 30000 });
|
||||
const midFormationSwapPreviewProbe = await page.evaluate(() => {
|
||||
const scene = window.__HEROS_GAME__?.scene.getScene('CampScene');
|
||||
const view = scene?.sortieComparisonPanelView;
|
||||
return {
|
||||
state: window.__HEROS_DEBUG__?.camp(),
|
||||
panel: {
|
||||
title: view?.title?.text ?? null,
|
||||
headline: view?.headline?.text ?? null,
|
||||
impact: view?.impact?.text ?? null,
|
||||
detail: view?.detail?.text ?? null
|
||||
}
|
||||
};
|
||||
});
|
||||
const midFormationSwapPreviewState = midFormationSwapPreviewProbe.state;
|
||||
const swapPreview = midFormationSwapPreviewState?.sortieComparisonPreview;
|
||||
const expectedProjectedSwapIds = midFormationSelectedBefore.map((unitId) => unitId === 'ma-dai' ? 'guan-yu' : unitId);
|
||||
assert(
|
||||
midFormationPortraitState.sortiePortraitRoster.some(
|
||||
(unit) => unit.id === hoveredPortraitUnitId && unit.portraitReady && unit.portraitTextureKey?.startsWith('portrait-card-')
|
||||
(unit) => unit.id === swapPreview?.incomingUnitId && unit.portraitReady && unit.portraitTextureKey?.startsWith('portrait-card-')
|
||||
),
|
||||
`Expected portrait-card hover feedback for a mapped officer: ${JSON.stringify(hoveredPortraitUnitId)}`
|
||||
`Expected portrait-card hover feedback for a mapped swap candidate: ${JSON.stringify(swapPreview?.incomingUnitId)}`
|
||||
);
|
||||
assert(
|
||||
swapPreview?.mode === 'swap' &&
|
||||
swapPreview?.incomingUnitId === 'guan-yu' &&
|
||||
swapPreview?.outgoingUnitId === 'ma-dai' &&
|
||||
JSON.stringify(swapPreview?.selectedUnitIds) === JSON.stringify(midFormationSelectedBefore) &&
|
||||
JSON.stringify(swapPreview?.projectedSelectedUnitIds) === JSON.stringify(expectedProjectedSwapIds) &&
|
||||
JSON.stringify(swapPreview?.current?.selectedUnitIds) === JSON.stringify(midFormationSelectedBefore) &&
|
||||
JSON.stringify(swapPreview?.projected?.selectedUnitIds) === JSON.stringify(expectedProjectedSwapIds) &&
|
||||
JSON.stringify(swapPreview?.comparison?.current?.selectedUnitIds) === JSON.stringify(midFormationSelectedBefore) &&
|
||||
JSON.stringify(swapPreview?.comparison?.projected?.selectedUnitIds) === JSON.stringify(expectedProjectedSwapIds) &&
|
||||
swapPreview?.metrics?.length === 4 &&
|
||||
swapPreview.metrics.some((metric) => metric.delta !== 0) &&
|
||||
swapPreview?.comparison?.lostRoles?.includes('flank') &&
|
||||
swapPreview?.comparison?.activeBondDelta === 0 &&
|
||||
swapPreview?.comparison?.gainedBonds?.length > 0 &&
|
||||
swapPreview?.comparison?.lostBonds?.length > 0,
|
||||
`Expected a meaningful non-destructive Ma Dai to Guan Yu swap preview: ${JSON.stringify(swapPreview)}`
|
||||
);
|
||||
assert(
|
||||
midFormationSwapPreviewProbe.panel.title === '가상 교체 · 마대 → 관우' &&
|
||||
midFormationSwapPreviewProbe.panel.headline?.includes('OUT 마대') &&
|
||||
midFormationSwapPreviewProbe.panel.headline?.includes('IN 관우') &&
|
||||
midFormationSwapPreviewProbe.panel.impact?.includes('공백 돌파') &&
|
||||
midFormationSwapPreviewProbe.panel.detail?.includes('+맥성 북문') &&
|
||||
midFormationSwapPreviewProbe.panel.detail?.includes('-산길과 말발굽') &&
|
||||
midFormationSwapPreviewProbe.panel.detail?.includes('실제 편성 미변경'),
|
||||
`Expected the visible comparison panel to render the swap preview: ${JSON.stringify(midFormationSwapPreviewProbe.panel)}`
|
||||
);
|
||||
assert(
|
||||
JSON.stringify(midFormationSwapPreviewState?.selectedSortieUnitIds) === JSON.stringify(midFormationSelectedBefore) &&
|
||||
JSON.stringify(midFormationSwapPreviewState?.campaign?.selectedSortieUnitIds) === JSON.stringify(midFormationCampaignSelectedBefore),
|
||||
`Expected hover swap preview to preserve runtime and saved selections: ${JSON.stringify(midFormationSwapPreviewState?.selectedSortieUnitIds)}`
|
||||
);
|
||||
await page.screenshot({ path: `${screenshotDir}/rc-mid-camp-sortie-formation-hover.png`, fullPage: true });
|
||||
await page.mouse.move(40, 710);
|
||||
await page.waitForFunction(() => window.__HEROS_DEBUG__?.camp()?.sortieHoveredUnitId === null, undefined, { timeout: 30000 });
|
||||
await page.waitForFunction(() => {
|
||||
const state = window.__HEROS_DEBUG__?.camp();
|
||||
return state?.sortieHoveredUnitId === null && state?.sortieComparisonPreview?.source === 'focus';
|
||||
}, undefined, { timeout: 30000 });
|
||||
const afterSwapPreviewProbe = await page.evaluate(() => {
|
||||
const scene = window.__HEROS_GAME__?.scene.getScene('CampScene');
|
||||
const view = scene?.sortieComparisonPanelView;
|
||||
return {
|
||||
state: window.__HEROS_DEBUG__?.camp(),
|
||||
panel: {
|
||||
title: view?.title?.text ?? null,
|
||||
headline: view?.headline?.text ?? null
|
||||
}
|
||||
};
|
||||
});
|
||||
const afterSwapPreviewState = afterSwapPreviewProbe.state;
|
||||
assert(
|
||||
JSON.stringify(afterSwapPreviewState?.selectedSortieUnitIds) === JSON.stringify(midFormationSelectedBefore) &&
|
||||
JSON.stringify(afterSwapPreviewState?.campaign?.selectedSortieUnitIds) === JSON.stringify(midFormationCampaignSelectedBefore),
|
||||
`Expected pointerout to restore focus preview without mutating selections: ${JSON.stringify(afterSwapPreviewState?.selectedSortieUnitIds)}`
|
||||
);
|
||||
assert(
|
||||
afterSwapPreviewState?.sortieComparisonPreview?.source === 'focus' &&
|
||||
afterSwapPreviewState?.sortieComparisonPreview?.mode === 'remove' &&
|
||||
afterSwapPreviewState?.sortieComparisonPreview?.unitId === 'ma-dai' &&
|
||||
afterSwapPreviewState?.sortieComparisonPreview?.incomingUnitId === null &&
|
||||
afterSwapPreviewState?.sortieComparisonPreview?.outgoingUnitId === 'ma-dai' &&
|
||||
afterSwapPreviewProbe.panel.title === '편성 변화 · 마대' &&
|
||||
!afterSwapPreviewProbe.panel.headline?.includes('관우'),
|
||||
`Expected pointerout to restore the visible Ma Dai focus preview: ${JSON.stringify(afterSwapPreviewProbe)}`
|
||||
);
|
||||
|
||||
const midFormationFirstPage = await page.evaluate(() => window.__HEROS_DEBUG__?.camp()?.sortiePortraitRosterView);
|
||||
await page.mouse.click(658, 196);
|
||||
|
||||
Reference in New Issue
Block a user