While the testing infrastructure is configured, unit test files don’t currently exist in the codebase. When writing unit tests, follow these patterns:Test File Naming:
The Playwright configuration is located in playwright.config.ts with the following key settings:
{ testDir: './e2e', fullyParallel: false, // Required due to Convex Auth refresh token rotation workers: 1, // Single worker to prevent auth conflicts timeout: 60000, // 60 second timeout for SSR apps retries: process.env.CI ? 2 : 1, // Retry flaky tests webServer: { command: 'bun run dev', url: 'http://localhost:3000', reuseExistingServer: !process.env.CI, timeout: 120000, }}
Important: E2E tests run with a single worker (workers: 1) to prevent refresh token rotation conflicts. Convex Auth uses refresh token rotation, which means parallel test execution can cause authentication failures.
import { test, expect } from '@playwright/test';test.describe('Test Creation', () => { test('organizer can create a new test', async ({ page }) => { // Navigate to tests page await page.goto('/app/tests'); // Click create test button await page.click('button:has-text("Create Test")'); // Fill in test details await page.fill('input[name="title"]', 'My New Test'); await page.fill('textarea[name="description"]', 'Test description'); // Submit form await page.click('button[type="submit"]'); // Verify test was created await expect(page.locator('text=My New Test')).toBeVisible(); });});
Example Participant Test:
import { test, expect } from '@playwright/test';test.describe('Taking a Test', () => { test('participant can submit answers', async ({ page }) => { // Navigate to test (using test ID) await page.goto('/s/test-id-here'); // Start the test await page.click('button:has-text("Start Test")'); // Answer a multiple choice question await page.click('text=Option A'); // Submit the test await page.click('button:has-text("Submit Test")'); // Verify submission await expect(page.locator('text=Test Submitted')).toBeVisible(); });});
Reusable test utilities are available in e2e/fixtures/test-helpers.ts to avoid code duplication:
// Example usage in testsimport { createTestWithQuestions } from '../fixtures/test-helpers';test('grading workflow', async ({ page }) => { // Use helper to set up test data const testId = await createTestWithQuestions(page, { title: 'Grading Test', questionCount: 5, }); // Continue with test...});