ci(web): Phase P6 — vite build + headless E2E gate on every trunk merge (#1445) (#1454)
ci/woodpecker/push/publish Pipeline was successful

This commit was merged in pull request #1454.
This commit is contained in:
2026-08-27 15:26:10 +00:00
parent b5ee692843
commit e605c83b27
19 changed files with 592 additions and 120 deletions
+19 -26
View File
@@ -1,45 +1,38 @@
import { test, expect } from '@playwright/test';
import { loginAs, TEST_USER } from './helpers/auth.js';
import { loginAs, REQUIRE_SEEDED_AUTH, TEST_USER } from './helpers/auth.js';
test.describe('Chat page', () => {
test.beforeEach(async ({ page }) => {
await loginAs(page, TEST_USER.email, TEST_USER.password);
// If login failed (no seeded user in env) we may be on /login — skip
const url = page.url();
test.skip(!url.includes('/chat'), 'No seeded test user — skipping authenticated tests');
test.skip(
!REQUIRE_SEEDED_AUTH && !url.includes('/chat'),
'No seeded test user — skipping authenticated tests',
);
});
test('chat page loads and shows the welcome message or conversation list', async ({ page }) => {
test('chat page loads and shows the conversation area', async ({ page }) => {
await page.goto('/chat');
// Either there are conversations listed or the welcome empty-state is shown
const hasWelcome = await page
.getByRole('heading', { name: /welcome to mosaic chat/i })
.isVisible()
.catch(() => false);
const hasConversationPanel = await page
.locator('[data-testid="conversation-list"], nav, aside')
.first()
.isVisible()
.catch(() => false);
expect(hasWelcome || hasConversationPanel).toBe(true);
await expect(page.getByRole('heading', { level: 1, name: /chat/i })).toBeVisible({
timeout: 10_000,
});
await expect(page.getByRole('log', { name: /conversation/i })).toBeVisible();
});
test('new conversation button is visible', async ({ page }) => {
test('message composer input is visible', async ({ page }) => {
await page.goto('/chat');
// "Start new conversation" button or a "+" button in the sidebar
const newConvButton = page.getByRole('button', { name: /new conversation|start new/i }).first();
await expect(newConvButton).toBeVisible({ timeout: 10_000 });
await expect(page.getByLabel('Message')).toBeVisible({ timeout: 10_000 });
});
test('clicking new conversation shows a chat input area', async ({ page }) => {
test('command panel lists /new and exposes the run controls', async ({ page }) => {
await page.goto('/chat');
// Find any button that creates a new conversation
const newBtn = page.getByRole('button', { name: /new conversation|start new/i }).first();
await newBtn.click();
// After creating, a text input for sending messages should appear
const chatInput = page.getByRole('textbox').or(page.locator('textarea')).first();
await expect(chatInput).toBeVisible({ timeout: 10_000 });
// Conversations are command-driven: /new starts one via the commands panel.
const commandList = page.getByRole('list', { name: /available commands/i });
await expect(commandList).toBeVisible({ timeout: 10_000 });
await expect(commandList.getByText('/new', { exact: true })).toBeVisible();
await expect(page.getByLabel('Command name')).toBeVisible();
await expect(page.getByRole('button', { name: /run command/i })).toBeVisible();
});
test('sidebar navigation is present on chat page', async ({ page }) => {