Files
Randify.pro/tests/dm/initiative.spec.ts
T
emil 1c38df7e74 style(dm): redesign dashboard with purple-gold theme
Redesign DM Dashboard (/dm/, /ru/dm/) with purple-gold theme (#534AB7 + #c8a84b):

Design System:
- Update dm-theme.css with 49 purple-gold tokens (transitions, shadows, hover states)
- Create DmTabs.astro with ARIA, keyboard nav, URL hash sync, localStorage persistence
- Create DmSidebar.astro for desktop navigation
- Redesign DmHeader with gold accent
- Update DmButton, DmCard, DmInput primitives
- Expand i18n to 47 strings

Layout:
- Redesign DmLayout with 3-column dashboard grid (sidebar|main|context)
- Update /dm/index.astro and /ru/dm/index.astro with named slots

Feature Components:
- DiceRoller: empty state, ARIA live, color-coded history, storage key fallback
- InitiativeTracker: HP editing, active highlighting, storage key fallback
- Open5eReference: skeletons, debounce, error retry, gold tabs
- NotesPanel: cross-tab sync, copy-to-clipboard, auto-save
- AuthPanel: VK/Yandex brand colors, pill buttons

Tests:
- Add 50 Playwright E2E tests (smoke, dice, initiative, reference, notes, data-migration)

Fixes:
- Document Open5e client.ts URL bugfix
- Add backward-compatible storage key fallback for dice/initiative
- Preserve legacy sessionStorage data on load
2026-05-15 17:49:32 +03:00

63 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test, expect } from "@playwright/test";
test.describe("Initiative Tracker", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/dm/#initiative");
});
test("add combatant with auto-roll", async ({ page }) => {
await page.fill("[data-testid='init-name-input']", "Гоблин");
await page.fill("[data-testid='init-mod-input']", "2");
await page.click("[data-testid='init-add-btn']");
await expect(page.locator("[data-testid='init-combatant']")).toBeVisible();
await expect(page.locator("[data-testid='init-combatant-name']")).toContainText("Гоблин");
});
test("sort by initiative descending", async ({ page }) => {
await page.fill("[data-testid='init-name-input']", "А");
await page.fill("[data-testid='init-mod-input']", "5");
await page.fill("[data-testid='init-initiative-input']", "25");
await page.click("[data-testid='init-add-btn']");
await page.fill("[data-testid='init-name-input']", "Б");
await page.fill("[data-testid='init-mod-input']", "0");
await page.fill("[data-testid='init-initiative-input']", "10");
await page.click("[data-testid='init-add-btn']");
const scores = await page.locator("[data-testid='init-score']").allTextContents();
expect(Number(scores[0])).toBeGreaterThan(Number(scores[1]));
});
test("next turn cycles active combatant", async ({ page }) => {
await page.fill("[data-testid='init-name-input']", "Гоблин");
await page.fill("[data-testid='init-mod-input']", "2");
await page.fill("[data-testid='init-initiative-input']", "20");
await page.click("[data-testid='init-add-btn']");
await page.fill("[data-testid='init-name-input']", "Орк");
await page.fill("[data-testid='init-mod-input']", "0");
await page.fill("[data-testid='init-initiative-input']", "15");
await page.click("[data-testid='init-add-btn']");
const firstActive = await page.locator("[data-testid='init-combatant'].active").textContent();
await page.click("[data-testid='init-next-btn']");
const secondActive = await page.locator("[data-testid='init-combatant'].active").textContent();
expect(firstActive).not.toBe(secondActive);
});
test("delete combatant", async ({ page }) => {
await page.fill("[data-testid='init-name-input']", "Гоблин");
await page.fill("[data-testid='init-mod-input']", "2");
await page.fill("[data-testid='init-initiative-input']", "20");
await page.click("[data-testid='init-add-btn']");
await page.click("[data-testid='init-delete-btn']");
await expect(page.locator("[data-testid='init-empty-state']")).toBeVisible();
});
test("mobile viewport renders correctly", async ({ page }) => {
await page.setViewportSize({ width: 375, height: 812 });
await expect(page.locator("[data-testid='init-section']")).toBeVisible();
});
});