import { test, expect } from '@playwright/test'; import fs from 'fs'; import path from 'path'; test.describe('Modals & Clinical Dialogs Suite', () => { test.beforeEach(async ({ page }) => { await page.addInitScript(() => { window.localStorage.clear(); window.localStorage.setItem('cognitive-clarity-settings', JSON.stringify({ voiceName: 'Zephyr', vocalStyle: 'Helpful', genderPreference: 'Neutral', openRouterApiKey: 'sk-or-v1-playwright-test-key', roleplayModel: 'google/gemini-3.8-flash', supervisorModel: 'google/gemini-3.8-flash' })); }); }); test('01 - Settings Modal and Model Selector', async ({ page }, testInfo) => { await page.goto('/'); await page.waitForLoadState('networkidle'); // Click Settings button const settingsBtn = page.locator('button:has(svg)').first(); await settingsBtn.click(); // Verify Settings Modal elements await expect(page.getByRole('heading', { name: 'Application Settings' })).toBeVisible(); await expect(page.getByText('Vocal Profile')).toBeVisible(); await expect(page.getByText('Fenrir (Salt of the Earth)')).toBeVisible(); await expect(page.getByText('Puck')).toBeVisible(); await expect(page.getByText('Kore')).toBeVisible(); await expect(page.getByText('Natural Voice Testing Lab')).toBeVisible(); // Select Fenrir (Salt of the Earth) persona await page.getByText('Fenrir (Salt of the Earth)').click(); await expect(page.getByText(/Auditioning/)).toContainText('Fenrir (Salt of the Earth)'); // Click quick audition demo button const auditionBtn = page.getByRole('button', { name: 'Audition Voice' }); await expect(auditionBtn).toBeVisible(); await auditionBtn.click(); const shotDir = path.join(process.cwd(), 'docs/screenshots', testInfo.project.name); fs.mkdirSync(shotDir, { recursive: true }); await page.screenshot({ path: path.join(shotDir, '04-settings-modal-voice.png'), fullPage: true }); // Switch to OpenRouter AI Tab await page.getByRole('tab', { name: 'OpenRouter AI' }).click(); await expect(page.getByRole('heading', { name: 'OpenRouter API Key' })).toBeVisible(); await expect(page.getByText('Google Gemini 3.8 Flash', { exact: true })).toBeVisible(); await expect(page.getByText('Frontier Ultra Low Latency')).toBeVisible(); await page.screenshot({ path: path.join(shotDir, '05-settings-modal-openrouter.png'), fullPage: true }); // Close Modal await page.getByRole('button', { name: 'Save Preferences' }).click(); await expect(page.getByRole('heading', { name: 'Application Settings' })).not.toBeVisible(); }); test('02 - CBT Clinical Reference Glossary & Concept Search', async ({ page }, testInfo) => { await page.goto('/'); await page.waitForLoadState('networkidle'); // Open Reference Guide await page.getByRole('button', { name: 'Reference Guide' }).click(); await expect(page.getByRole('heading', { name: 'CBT Clinical Reference' })).toBeVisible(); const shotDir = path.join(process.cwd(), 'docs/screenshots', testInfo.project.name); fs.mkdirSync(shotDir, { recursive: true }); await page.screenshot({ path: path.join(shotDir, '06-cbt-reference-all.png'), fullPage: true }); // Filter by Distortion category await page.getByRole('button', { name: 'Distortion', exact: true }).click(); await expect(page.getByRole('heading', { name: 'All-or-Nothing Thinking' })).toBeVisible(); await expect(page.getByRole('heading', { name: 'Catastrophizing' })).toBeVisible(); // Search for a specific concept const searchInput = page.getByPlaceholder('Search concepts, distortions, or definitions...'); await searchInput.fill('Mind Reading'); await expect(page.getByRole('heading', { name: 'Mind Reading' })).toBeVisible(); await expect(page.getByRole('heading', { name: 'All-or-Nothing Thinking' })).not.toBeVisible(); await page.screenshot({ path: path.join(shotDir, '07-cbt-reference-search.png'), fullPage: true }); // Close Reference Guide await page.locator('div.fixed button:has(svg)').first().click(); }); test('03 - Custom Scenario Architect Generator', async ({ page }, testInfo) => { await page.goto('/'); await page.waitForLoadState('networkidle'); // Open Custom Scenario Generator await page.getByRole('button', { name: 'Create Custom' }).first().click(); await expect(page.getByRole('heading', { name: 'Clinical Scenario Architect' })).toBeVisible(); await expect(page.getByText('Target Dynamic & Situation')).toBeVisible(); await expect(page.getByText('Emotional Resistance & Difficulty')).toBeVisible(); const shotDir = path.join(process.cwd(), 'docs/screenshots', testInfo.project.name); fs.mkdirSync(shotDir, { recursive: true }); await page.screenshot({ path: path.join(shotDir, '08-scenario-generator-modal.png'), fullPage: true }); // Fill scenario prompt await page.getByPlaceholder('e.g. Asking my manager for a delayed performance review').fill( 'Negotiating a contract renewal with a skeptical supplier who wants to raise rates by 40%.' ); // Select difficulty await page.getByRole('button', { name: 'Advanced Severe Friction' }).click(); // Select CBT focus distortion await page.getByRole('button', { name: 'Emotional Reasoning' }).click(); await page.screenshot({ path: path.join(shotDir, '09-scenario-generator-filled.png'), fullPage: true }); // Cancel modal await page.getByRole('button', { name: 'Cancel' }).click(); await expect(page.getByRole('heading', { name: 'Clinical Scenario Architect' })).not.toBeVisible(); }); });