feat(ui): hover modifier tooltip
Adds ModifierTooltip component that reads MODIFIER_REGISTRY attrs from engine.session for the hovered piece and renders them as labelled rows. The tooltip always appears on piece hover (piece type + color header) and shows modifier rows only when modifier facts are set on the entity. Board.tsx gains an optional onPieceHover callback; GameView.tsx tracks hoveredPieceId and renders the tooltip absolutely in the board wrapper. A 120ms hide-delay prevents flicker when cursor briefly leaves a piece. Two Playwright tests added: hover shows tooltip with piece name; hover over unmodified piece shows zero modifier-tooltip-row elements.
This commit is contained in:
parent
fa1ef765f8
commit
5f252e2dff
4 changed files with 161 additions and 3 deletions
|
|
@ -142,6 +142,55 @@ test.describe('Modifier Profiles', () => {
|
|||
});
|
||||
});
|
||||
|
||||
// ── T24: Hover modifier tooltip ──────────────────────────────────────────
|
||||
|
||||
test.describe('Modifier Profiles — hover tooltip (T24)', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
// Clear autosave so Play Solo starts a fresh game.
|
||||
await page.evaluate(() => {
|
||||
for (let i = localStorage.length - 1; i >= 0; i--) {
|
||||
const key = localStorage.key(i);
|
||||
if (key !== null && key.startsWith('paratype-chess:v2:autosave:')) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
}
|
||||
localStorage.removeItem('paratype-chess:v1:autosave');
|
||||
});
|
||||
|
||||
// Navigate into the game view WITHOUT opening the rules drawer,
|
||||
// so the board is fully interactive (no backdrop overlay).
|
||||
await page.locator('[data-action="play-solo"]').click();
|
||||
await page.waitForURL('**/game');
|
||||
});
|
||||
|
||||
test('hover piece shows modifier tooltip', async ({ page }) => {
|
||||
// Hover white knight at b1 (standard opening position).
|
||||
await page.hover('[data-square="b1"]');
|
||||
await page.waitForTimeout(200);
|
||||
|
||||
// Tooltip must appear and identify the piece.
|
||||
await expect(
|
||||
page.locator('[data-testid="modifier-tooltip"]'),
|
||||
).toBeVisible({ timeout: 1000 });
|
||||
await expect(
|
||||
page.locator('[data-testid="modifier-tooltip"]'),
|
||||
).toContainText(/knight/i);
|
||||
});
|
||||
|
||||
test('hover unmodified piece shows no modifier rows', async ({ page }) => {
|
||||
// Standard solo game — no modifier profile active.
|
||||
await page.hover('[data-square="e2"]'); // white pawn
|
||||
await page.waitForTimeout(200);
|
||||
|
||||
// Tooltip appears (header always shows) but no modifier rows.
|
||||
await expect(
|
||||
page.locator('[data-testid="modifier-tooltip-row"]'),
|
||||
).toHaveCount(0);
|
||||
});
|
||||
});
|
||||
|
||||
// ── T26: Lobby profile picker + GameView badge ─────────────────────────
|
||||
|
||||
test.describe('Modifier Profiles — Lobby integration (T26)', () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue