import { test, expect } from '@playwright/test'; import fs from 'node:fs'; 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(); }); test('assistant config persists and the key is never exported', async ({ page }) => { const SECRET = 'sk-test-DO-NOT-EXPORT-789'; await page.getByLabel('Settings').click(); await page.getByLabel('Enable AI assistant').check(); await page.getByLabel('API key', { exact: true }).fill(SECRET); await page.getByLabel('Model').fill('claude-opus-4-8'); // Persists across reload (rememberKey defaults on) await page.reload(); await page.getByLabel('Settings').click(); await expect(page.getByLabel('Enable AI assistant')).toBeChecked(); await expect(page.getByLabel('API key', { exact: true })).toHaveValue(SECRET); // The backup export (Dexie only) must not contain the localStorage-held key const downloadPromise = page.waitForEvent('download'); await page.getByRole('button', { name: 'Export backup' }).click(); const download = await downloadPromise; const path = await download.path(); const content = fs.readFileSync(path, 'utf8'); expect(content).not.toContain(SECRET); });