bd6bb240a1
- Command palette (Ctrl/Cmd+K): fuzzy search over pages + active-campaign characters/notes/NPCs/quests + actions; keyboard nav; header ⌘K button - Settings page: theme, full backup export/import (restore replaces all in one transaction), load sample campaign, danger-zone clear-all - Backup lib (src/lib/io/backup.ts) snapshots every table; sample seeder (src/lib/sample.ts) builds a demo campaign - Header gets ⌘K + settings gear; routes + nav wired Backup round-trip unit tests + command-palette/settings e2e. (Deferred from this phase, noted in plan: audio, Discord/Foundry/Roll20, i18n, push notifications.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
30 lines
1.1 KiB
TypeScript
30 lines
1.1 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/');
|
|
await page.evaluate(async () => {
|
|
indexedDB.deleteDatabase('ttrpg-manager');
|
|
localStorage.clear();
|
|
});
|
|
await page.reload();
|
|
});
|
|
|
|
test('command palette navigates', async ({ page }) => {
|
|
await page.keyboard.press('Control+k');
|
|
const input = page.getByLabel('Command search');
|
|
await expect(input).toBeVisible();
|
|
await input.fill('Dice');
|
|
await input.press('Enter');
|
|
await expect(page.getByRole('heading', { name: 'Dice' })).toBeVisible();
|
|
});
|
|
|
|
test('settings loads the sample campaign', async ({ page }) => {
|
|
await page.getByLabel('Settings').click();
|
|
await expect(page.getByRole('heading', { name: 'Settings' })).toBeVisible();
|
|
await page.getByRole('button', { name: 'Load sample campaign' }).click();
|
|
await expect(page.getByRole('heading', { name: 'Sample: Lost Mine' })).toBeVisible();
|
|
// sample seeded characters (use the nav link, not the dashboard card)
|
|
await page.getByLabel('Primary').getByRole('link', { name: 'Characters' }).click();
|
|
await expect(page.getByText('Lia the Brave')).toBeVisible();
|
|
});
|