Some checks failed
ci/woodpecker/push/ci Pipeline failed
Sets up @playwright/test in apps/web with playwright.config.ts targeting localhost:3000. Adds E2E test coverage for all critical paths: auth (login/register/validation), chat (page load, new conversation), projects (list, empty state), settings (4 tab switches), admin (tab switching, role guard), and navigation (sidebar links, route transitions). Includes auth helper, separate tsconfig.e2e.json, and allowDefaultProject ESLint config so e2e files pass the pre-commit hook. Adds pnpm test:e2e script. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
87 lines
2.9 KiB
TypeScript
87 lines
2.9 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import { loginAs, TEST_USER } from './helpers/auth.js';
|
|
|
|
test.describe('Sidebar navigation', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await loginAs(page, TEST_USER.email, TEST_USER.password);
|
|
const url = page.url();
|
|
test.skip(!url.includes('/chat'), 'No seeded test user — skipping authenticated tests');
|
|
});
|
|
|
|
test('sidebar shows Mosaic brand link', async ({ page }) => {
|
|
await page.goto('/chat');
|
|
await expect(page.getByRole('link', { name: /mosaic/i }).first()).toBeVisible();
|
|
});
|
|
|
|
test('Chat nav link navigates to /chat', async ({ page }) => {
|
|
await page.goto('/settings');
|
|
await page
|
|
.getByRole('link', { name: /^chat$/i })
|
|
.first()
|
|
.click();
|
|
await expect(page).toHaveURL(/\/chat/);
|
|
});
|
|
|
|
test('Projects nav link navigates to /projects', async ({ page }) => {
|
|
await page.goto('/chat');
|
|
await page
|
|
.getByRole('link', { name: /projects/i })
|
|
.first()
|
|
.click();
|
|
await expect(page).toHaveURL(/\/projects/);
|
|
});
|
|
|
|
test('Settings nav link navigates to /settings', async ({ page }) => {
|
|
await page.goto('/chat');
|
|
await page
|
|
.getByRole('link', { name: /settings/i })
|
|
.first()
|
|
.click();
|
|
await expect(page).toHaveURL(/\/settings/);
|
|
});
|
|
|
|
test('Tasks nav link navigates to /tasks', async ({ page }) => {
|
|
await page.goto('/chat');
|
|
await page.getByRole('link', { name: /tasks/i }).first().click();
|
|
await expect(page).toHaveURL(/\/tasks/);
|
|
});
|
|
|
|
test('active link is visually highlighted', async ({ page }) => {
|
|
await page.goto('/chat');
|
|
// The active link should have a distinct class — check that the Chat link
|
|
// has the active style class (bg-blue-600/20 text-blue-400)
|
|
const chatLink = page.getByRole('link', { name: /^chat$/i }).first();
|
|
const cls = await chatLink.getAttribute('class');
|
|
expect(cls).toContain('blue');
|
|
});
|
|
});
|
|
|
|
test.describe('Route transitions', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await loginAs(page, TEST_USER.email, TEST_USER.password);
|
|
const url = page.url();
|
|
test.skip(!url.includes('/chat'), 'No seeded test user — skipping authenticated tests');
|
|
});
|
|
|
|
test('navigating chat → projects → settings → chat works without errors', async ({ page }) => {
|
|
await page.goto('/chat');
|
|
await expect(page).toHaveURL(/\/chat/);
|
|
|
|
await page.goto('/projects');
|
|
await expect(page.getByRole('heading', { name: /projects/i })).toBeVisible();
|
|
|
|
await page.goto('/settings');
|
|
await expect(page.getByRole('heading', { name: /settings/i })).toBeVisible();
|
|
|
|
await page.goto('/chat');
|
|
await expect(page).toHaveURL(/\/chat/);
|
|
});
|
|
|
|
test('back-button navigation works between pages', async ({ page }) => {
|
|
await page.goto('/chat');
|
|
await page.goto('/projects');
|
|
await page.goBack();
|
|
await expect(page).toHaveURL(/\/chat/);
|
|
});
|
|
});
|