import { test, expect } from '@playwright/test';
// T067: Test search flow
test.describe('Search Flow (US1)', () => {
test('should display search input and buttons', async ({ page }) => {
await page.goto('/');
await expect(page.locator('input[type="text"]')).toBeVisible();
await expect(page.getByRole('button', { name: /search/i })).toBeVisible();
});
test('should search and display results', async ({ page }) => {
await page.goto('/');
await page.locator('input[type="text"]').fill('oracle');
await page.getByRole('button', { name: /search/i }).click();
// Wait for results - either results appear or "no results" message
await expect(page.locator('.results-list, .no-results, [class*="result"]')).toBeVisible({ timeout: 5000 });
});
test('should filter by type tabs', async ({ page }) => {
await page.goto('/');
await page.locator('input[type="text"]').fill('pattern');
await page.getByRole('button', { name: /search/i }).click();
// Click type filter if available
const principleTab = page.getByRole('button', { name: /principle/i });
if (await principleTab.isVisible()) {
await principleTab.click();
await page.waitForTimeout(500);
}
});
});
// T068: Test browse flow
test.describe('Browse Flow (US2)', () => {
test('should have browse button', async ({ page }) => {
await page.goto('/');
await expect(page.getByRole('button', { name: /browse/i })).toBeVisible();
});
test('should browse documents without search query', async ({ page }) => {
await page.goto('/');
await page.getByRole('button', { name: /browse/i }).click();
// Wait for browse results
await expect(page.locator('.results-list, [class*="result"], [class*="card"]')).toBeVisible({ timeout: 5000 });
});
});
// T069: Test consult and reflect flows
test.describe('Consult Flow (US3)', () => {
test('should have consult button', async ({ page }) => {
await page.goto('/');
await expect(page.getByRole('button', { name: /consult/i })).toBeVisible();
});
test('should display guidance when consulting', async ({ page }) => {
await page.goto('/');
await page.locator('input[type="text"]').fill('should I use force push?');
await page.getByRole('button', { name: /consult/i }).click();
// Wait for guidance response
await page.waitForTimeout(2000);
});
});
test.describe('Reflect Flow (US4)', () => {
test('should have reflect button', async ({ page }) => {
await page.goto('/');
await expect(page.getByRole('button', { name: /reflect/i })).toBeVisible();
});
test('should display random wisdom when reflecting', async ({ page }) => {
await page.goto('/');
await page.getByRole('button', { name: /reflect/i }).click();
// Wait for reflection result
await page.waitForTimeout(2000);
});
});
// T070: Test graph interaction
test.describe('Graph View (US5)', () => {
test('should have graph button', async ({ page }) => {
await page.goto('/');
await expect(page.getByRole('button', { name: /graph/i })).toBeVisible();
});
test('should display graph canvas when clicked', async ({ page }) => {
await page.goto('/');
await page.getByRole('button', { name: /graph/i }).click();
// Wait for canvas to appear
await expect(page.locator('canvas')).toBeVisible({ timeout: 5000 });
});
});
// T071: Test learn modal
test.describe('Learn Modal (US6)', () => {
test('should have learn button', async ({ page }) => {
await page.goto('/');
await expect(page.getByRole('button', { name: /learn/i })).toBeVisible();
});
test('should open learn modal with form', async ({ page }) => {
await page.goto('/');
await page.getByRole('button', { name: /learn/i }).click();
// Check modal content
await expect(page.locator('textarea, [class*="modal"]')).toBeVisible({ timeout: 2000 });
});
});
// T072: Test persona toggle persistence
test.describe('Persona Toggle (US8)', () => {
test('should display Oracle title by default', async ({ page }) => {
await page.goto('/');
await expect(page.locator('text=Oracle')).toBeVisible();
});
test('should toggle to Arthur persona', async ({ page }) => {
await page.goto('/');
// Look for persona toggle button
const toggle = page.locator('[class*="toggle"], button:has-text("Arthur"), button:has-text("Toggle")');
if (await toggle.first().isVisible()) {
await toggle.first().click();
await page.waitForTimeout(500);
}
});
test('should navigate to Arthur page via hash', async ({ page }) => {
await page.goto('/#arthur');
await expect(page.locator('text=ARTHUR')).toBeVisible({ timeout: 3000 });
});
});
// T066: General UI tests
test.describe('General UI', () => {
test('should load without errors', async ({ page }) => {
const errors: string[] = [];
page.on('pageerror', (err) => errors.push(err.message));
await page.goto('/');
await page.waitForTimeout(1000);
expect(errors).toHaveLength(0);
});
test('should display stats header', async ({ page }) => {
await page.goto('/');
// Stats should show document counts or loading state
await expect(page.locator('[class*="header"], [class*="stats"], h1')).toBeVisible();
});
test('should have responsive layout', async ({ page }) => {
await page.setViewportSize({ width: 375, height: 667 });
await page.goto('/');
await expect(page.locator('input[type="text"]')).toBeVisible();
});
});
// Arthur Voice UI tests
test.describe('Arthur Voice UI', () => {
test('should display Arthur interface at hash route', async ({ page }) => {
await page.goto('/#arthur');
await expect(page.locator('.arthur-page, [class*="arthur"]')).toBeVisible({ timeout: 3000 });
});
test('should have text input for messages', async ({ page }) => {
await page.goto('/#arthur');
await expect(page.locator('input[type="text"], .arthur-text-input')).toBeVisible({ timeout: 3000 });
});
test('should have voice button', async ({ page }) => {
await page.goto('/#arthur');
await expect(page.locator('.voice-btn, button:has-text("🎤")')).toBeVisible({ timeout: 3000 });
});
test('should navigate back to Oracle', async ({ page }) => {
await page.goto('/#arthur');
const oracleLink = page.locator('text=ORACLE, a:has-text("Oracle"), button:has-text("Oracle")');
if (await oracleLink.first().isVisible()) {
await oracleLink.first().click();
await page.waitForTimeout(500);
}
});
});