hud chrome: remove Map window, pin top bar, dockable left/right panels (v0.5.0)
CI / build + unit + e2e (pull_request) Successful in 2m18s
CI / build + unit + e2e (pull_request) Successful in 2m18s
This commit is contained in:
@@ -419,3 +419,101 @@ test.describe('History — URL deep-linking (#/game/<id>)', () => {
|
||||
await waitHash(page, '#/');
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* HUD revamp (issues #4 and #5). The floating "Map" zoom window is gone — the
|
||||
* full-bleed map is driven directly by wheel/trackpad + drag. The top bar is a
|
||||
* *pinned* element: fixed, non-movable, centered at the top a few px down. The
|
||||
* dossier / feed / action panels can each be docked into a full-height left or
|
||||
* right pane (persisted in `localStorage`); the legend stays a small floating
|
||||
* widget.
|
||||
*/
|
||||
test.describe('History — HUD revamp (pinned top bar, dockable panels, no Map window)', () => {
|
||||
test('Map window is gone; top bar is pinned top-center; panels dock left/right', async ({
|
||||
page,
|
||||
}) => {
|
||||
test.setTimeout(90000);
|
||||
await createUkGame(page);
|
||||
await expect(page.getByTestId('world-map')).toBeVisible();
|
||||
await expect(page.getByTestId('turn-count')).toHaveText('1');
|
||||
|
||||
const vw = page.viewportSize()!.width;
|
||||
const vh = page.viewportSize()!.height;
|
||||
|
||||
// --- #4: the "Map" zoom window is gone --------------------------------
|
||||
// No zoom window element, and no zoom-in/zoom-out buttons anywhere on the
|
||||
// game screen.
|
||||
await expect(page.locator('[data-float-window="zoom"]')).toHaveCount(0);
|
||||
await expect(page.getByTestId('zoom-in')).toHaveCount(0);
|
||||
await expect(page.getByTestId('zoom-out')).toHaveCount(0);
|
||||
|
||||
// --- #5a: the top bar is pinned, centered at the top ------------------
|
||||
const topBar = page.getByTestId('top-bar');
|
||||
await expect(topBar).toBeVisible();
|
||||
const barBox = (await topBar.boundingBox())!;
|
||||
// Horizontally centered: x ≈ (viewportWidth − width) / 2 …
|
||||
expect(Math.abs(barBox.x - (vw - barBox.width) / 2)).toBeLessThanOrEqual(3);
|
||||
// …and a few px down from the top edge (y ≈ 8).
|
||||
expect(barBox.y).toBeGreaterThanOrEqual(6);
|
||||
expect(barBox.y).toBeLessThanOrEqual(10);
|
||||
|
||||
// A pointer-drag attempted on the pinned bar must not move it (it has no
|
||||
// drag handlers; the map behind it never receives a mousedown).
|
||||
await page.mouse.move(barBox.x + barBox.width / 2, barBox.y + barBox.height / 2);
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(barBox.x + barBox.width / 2 + 60, barBox.y + barBox.height / 2 + 40, {
|
||||
steps: 6,
|
||||
});
|
||||
await page.mouse.up();
|
||||
const barBoxAfter = (await topBar.boundingBox())!;
|
||||
expect(Math.abs(barBoxAfter.x - barBox.x)).toBeLessThanOrEqual(1);
|
||||
expect(Math.abs(barBoxAfter.y - barBox.y)).toBeLessThanOrEqual(1);
|
||||
|
||||
// --- #5b: the dossier docks into a full-height left pane --------------
|
||||
const dossier = page.getByTestId('panel-dossier');
|
||||
await dossier.getByTestId('dock-left').click();
|
||||
const dBox = (await dossier.boundingBox())!;
|
||||
// Pinned to the left edge, filling the viewport height.
|
||||
expect(dBox.x).toBeLessThanOrEqual(2);
|
||||
expect(dBox.y).toBeLessThanOrEqual(2);
|
||||
expect(Math.abs(dBox.height - vh)).toBeLessThanOrEqual(3);
|
||||
expect(Math.abs(dBox.width - 300)).toBeLessThanOrEqual(3);
|
||||
|
||||
// --- #5b: the event feed docks into a full-height right pane ----------
|
||||
const feed = page.getByTestId('panel-feed');
|
||||
await feed.getByTestId('dock-right').click();
|
||||
const fBox = (await feed.boundingBox())!;
|
||||
// Pinned to the right edge: its right side sits on the viewport edge.
|
||||
expect(Math.abs(fBox.x + fBox.width - vw)).toBeLessThanOrEqual(3);
|
||||
expect(Math.abs(fBox.height - vh)).toBeLessThanOrEqual(3);
|
||||
|
||||
// The "Your move" deck is still a floating panel (we never docked it).
|
||||
await expect(page.getByTestId('panel-action')).toBeVisible();
|
||||
});
|
||||
|
||||
test('a dock choice survives a page reload (persisted in localStorage)', async ({
|
||||
page,
|
||||
}) => {
|
||||
test.setTimeout(90000);
|
||||
await createUkGame(page);
|
||||
await expect(page.getByTestId('world-map')).toBeVisible();
|
||||
const vh = page.viewportSize()!.height;
|
||||
|
||||
// Dock the dossier into the left pane.
|
||||
const dossier = page.getByTestId('panel-dossier');
|
||||
await dossier.getByTestId('dock-left').click();
|
||||
const before = (await dossier.boundingBox())!;
|
||||
expect(before.x).toBeLessThanOrEqual(2);
|
||||
expect(Math.abs(before.height - vh)).toBeLessThanOrEqual(3);
|
||||
|
||||
// Reload: the persisted dock choice must restore the docked layout, and the
|
||||
// deep link restores the game.
|
||||
await page.reload();
|
||||
await expect(page.getByTestId('world-map')).toBeVisible();
|
||||
await expect(page.getByTestId('turn-count')).toHaveText('1', { timeout: 20000 });
|
||||
const after = (await page.getByTestId('panel-dossier').boundingBox())!;
|
||||
expect(after.x).toBeLessThanOrEqual(2);
|
||||
expect(Math.abs(after.height - vh)).toBeLessThanOrEqual(3);
|
||||
expect(Math.abs(after.width - 300)).toBeLessThanOrEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user