import { test, expect } from '@playwright/test'; /** * Home Page E2E Tests * * Tests the study list page at / * Covers: study loading, topic expansion, navigation */ test.describe('Home Page - Study List', () => { test.beforeEach(async ({ page }) => { // Navigate to home page await page.goto('/'); }); test('displays page header', async ({ page }) => { // Check header is visible await expect(page.locator('header')).toBeVisible(); // Check for key header elements - Studies heading (exact match to avoid Inbox Studies) await expect(page.getByRole('heading', { name: 'Studies', exact: true })).toBeVisible({ timeout: 10000 }); }); test('shows aggregate statistics cards', async ({ page }) => { // Wait for stats to load await expect(page.getByText('Total Studies')).toBeVisible(); await expect(page.getByText('Running')).toBeVisible(); await expect(page.getByText('Total Trials')).toBeVisible(); await expect(page.getByText('Best Overall')).toBeVisible(); }); test('loads studies table with topic folders', async ({ page }) => { // Wait for studies section (exact match to avoid Inbox Studies) await expect(page.getByRole('heading', { name: 'Studies', exact: true })).toBeVisible(); // Wait for loading to complete - either see folders or empty state // Folders have "trials" text in them const folderLocator = page.locator('button:has-text("trials")'); const emptyStateLocator = page.getByText('No studies found'); // Wait for either studies loaded or empty state (10s timeout) await expect(folderLocator.first().or(emptyStateLocator)).toBeVisible({ timeout: 10000 }); }); test('expands topic folder to show studies', async ({ page }) => { // Wait for folders to load const folderButton = page.locator('button:has-text("trials")').first(); // Wait for folder to be visible (studies loaded) await expect(folderButton).toBeVisible({ timeout: 10000 }); // Click to expand await folderButton.click(); // After expansion, study rows should be visible (they have status badges) // Status badges contain: running, completed, idle, paused, not_started const statusBadges = page.locator('span:has-text("running"), span:has-text("completed"), span:has-text("idle"), span:has-text("paused"), span:has-text("not_started")'); await expect(statusBadges.first()).toBeVisible({ timeout: 5000 }); }); test('clicking study shows preview panel', async ({ page }) => { // Wait for and expand first folder const folderButton = page.locator('button:has-text("trials")').first(); await expect(folderButton).toBeVisible({ timeout: 10000 }); await folderButton.click(); // Wait for expanded content and click first study row const studyRow = page.locator('.bg-dark-850\\/50 > div').first(); await expect(studyRow).toBeVisible({ timeout: 5000 }); await studyRow.click(); // Preview panel should show with buttons - use exact match to avoid header nav button await expect(page.getByRole('button', { name: 'Canvas', exact: true })).toBeVisible({ timeout: 5000 }); await expect(page.getByRole('button', { name: 'Open' })).toBeVisible(); }); test('Open button navigates to dashboard', async ({ page }) => { // Wait for and expand first folder const folderButton = page.locator('button:has-text("trials")').first(); await expect(folderButton).toBeVisible({ timeout: 10000 }); await folderButton.click(); // Wait for and click study row const studyRow = page.locator('.bg-dark-850\\/50 > div').first(); await expect(studyRow).toBeVisible({ timeout: 5000 }); await studyRow.click(); // Wait for and click Open button const openButton = page.getByRole('button', { name: 'Open' }); await expect(openButton).toBeVisible({ timeout: 5000 }); await openButton.click(); // Should navigate to dashboard await expect(page).toHaveURL(/\/dashboard/); }); test('Canvas button navigates to canvas view', async ({ page }) => { // Wait for and expand first folder const folderButton = page.locator('button:has-text("trials")').first(); await expect(folderButton).toBeVisible({ timeout: 10000 }); await folderButton.click(); // Wait for and click study row const studyRow = page.locator('.bg-dark-850\\/50 > div').first(); await expect(studyRow).toBeVisible({ timeout: 5000 }); await studyRow.click(); // Wait for and click Canvas button (exact match to avoid header nav) const canvasButton = page.getByRole('button', { name: 'Canvas', exact: true }); await expect(canvasButton).toBeVisible({ timeout: 5000 }); await canvasButton.click(); // Should navigate to canvas await expect(page).toHaveURL(/\/canvas\//); }); test('refresh button reloads studies', async ({ page }) => { // Find the main studies section refresh button (the one with visible text "Refresh") const refreshButton = page.getByText('Refresh'); await expect(refreshButton).toBeVisible({ timeout: 5000 }); // Click refresh await refreshButton.click(); // Should show loading state or complete quickly // Just verify no errors occurred (exact match to avoid Inbox Studies) await expect(page.getByRole('heading', { name: 'Studies', exact: true })).toBeVisible(); }); }); /** * Inbox Section Tests * * Tests the new study intake workflow */ test.describe('Home Page - Inbox Section', () => { test.beforeEach(async ({ page }) => { await page.goto('/'); }); test('displays inbox section with header', async ({ page }) => { // Check for Study Inbox heading (section is expanded by default) const inboxHeading = page.getByRole('heading', { name: 'Study Inbox' }); await expect(inboxHeading).toBeVisible({ timeout: 10000 }); }); test('inbox section shows pending count', async ({ page }) => { // Section should show pending studies count const pendingText = page.getByText(/\d+ pending studies/); await expect(pendingText).toBeVisible({ timeout: 10000 }); }); test('inbox has new study button', async ({ page }) => { // Section is expanded by default, look for the New Study button const newStudyButton = page.getByRole('button', { name: /New Study/ }); await expect(newStudyButton).toBeVisible({ timeout: 10000 }); }); test('clicking new study shows create form', async ({ page }) => { // Click the New Study button const newStudyButton = page.getByRole('button', { name: /New Study/ }); await expect(newStudyButton).toBeVisible({ timeout: 10000 }); await newStudyButton.click(); // Form should expand with input fields const studyNameInput = page.getByPlaceholder(/my_study/i).or(page.locator('input[type="text"]').first()); await expect(studyNameInput).toBeVisible({ timeout: 5000 }); }); });