ci/woodpecker/pr/ci Pipeline was successful
- ci.yml: build step (vite build via turbo) runs on every PR pipeline after test - publish.yml: e2e step boots the gateway from built dist (HOME/cwd-isolated throwaway PGlite) and runs the Playwright suite headless inside mcr.microsoft.com/playwright:v1.58.2-noble against the SPA bundle served exactly as production serves it; both kaniko publishes now gate on e2e - serve-spa.ts: strip query strings before asset resolution; immutable cache-control for hashed assets (onSend hook); e2e spec covers both - e2e suite hardened: globalSetup seeds admin+member through real bootstrap/better-auth APIs (Origin header for CSRF), loginAs waits for the post-login redirect (fixes 27-skipped race), stale #152-era assertions rewritten to the current command-driven UI, strict-mode violations fixed with level-1 heading queries and .or() auto-retrying locators - verify-release mirrors the new build stage; playwright artifacts ignored
41 lines
1.7 KiB
TypeScript
41 lines
1.7 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import { loginAs, 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('chat page loads and shows the conversation area', async ({ page }) => {
|
|
await page.goto('/chat');
|
|
await expect(page.getByRole('heading', { level: 1, name: /chat/i })).toBeVisible({
|
|
timeout: 10_000,
|
|
});
|
|
await expect(page.getByRole('log', { name: /conversation/i })).toBeVisible();
|
|
});
|
|
|
|
test('message composer input is visible', async ({ page }) => {
|
|
await page.goto('/chat');
|
|
await expect(page.getByLabel('Message')).toBeVisible({ timeout: 10_000 });
|
|
});
|
|
|
|
test('command panel lists /new and exposes the run controls', async ({ page }) => {
|
|
await page.goto('/chat');
|
|
// 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 }) => {
|
|
await page.goto('/chat');
|
|
// The app-shell sidebar should be visible
|
|
await expect(page.getByRole('link', { name: /chat/i }).first()).toBeVisible();
|
|
});
|
|
});
|