mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-09-29 07:05:14 -07:00
test: Playwright E2E with real backend + fake TTS engine
e2e/ drives the web build (vite preview) against a per-worker uvicorn: each Playwright worker boots its own backend on its own port with a temp cwd, so SQLite and audio files are fully isolated and parallel- safe. The page fixture seeds the persisted voicebox-server store with the worker's URL before any script runs. VOICEBOX_FAKE_TTS=1 short-circuits get_tts_backend_for_engine to a backend that synthesizes a sine tone sized to the text — the real task queue, SSE progress, history rows, and audio serving all run, only inference is fake. backend/requirements-ci.txt is the slim dependency set validated to boot the app on a CPU-only runner. Specs: startup, settings layout, seeded profile in /voices, and generate-to-completed-audio through the full pipeline.
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { expect, test } from '../fixtures';
|
||||
import { seedProfile } from '../helpers/api';
|
||||
|
||||
test('generate speech end to end through the fake TTS pipeline', async ({ page, backend }) => {
|
||||
const profile = await seedProfile(backend.url, 'Narrator');
|
||||
|
||||
await page.goto('/');
|
||||
|
||||
// Select the seeded voice, type into the generate box, and submit.
|
||||
await page.getByText(profile.name).first().click();
|
||||
const input = page.getByRole('textbox').first();
|
||||
await input.click();
|
||||
await page.keyboard.type('The quick brown fox jumps over the lazy dog.');
|
||||
await page.getByRole('button', { name: 'Generate speech' }).click();
|
||||
|
||||
// The row lands in history and completes via the real queue + SSE.
|
||||
await expect(page.getByText('The quick brown fox', { exact: false }).first()).toBeVisible({
|
||||
timeout: 15_000,
|
||||
});
|
||||
|
||||
await expect
|
||||
.poll(
|
||||
async () => {
|
||||
const res = await fetch(`${backend.url}/history?limit=10`);
|
||||
const body = (await res.json()) as { items: { status: string }[] };
|
||||
return body.items[0]?.status;
|
||||
},
|
||||
{ timeout: 20_000 },
|
||||
)
|
||||
.toBe('completed');
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
import { expect, test } from '../fixtures';
|
||||
|
||||
test('app boots against the backend and shows the main editor', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Voicebox' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Create Voice' }).first()).toBeVisible();
|
||||
});
|
||||
|
||||
test('settings layout renders its pages', async ({ page }) => {
|
||||
await page.goto('/settings/about');
|
||||
|
||||
await expect(page.getByText('General', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('Changelog', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('About', { exact: true })).toBeVisible();
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
import { expect, test } from '../fixtures';
|
||||
import { seedProfile } from '../helpers/api';
|
||||
|
||||
test('a seeded voice profile appears in the voices tab', async ({ page, backend }) => {
|
||||
const profile = await seedProfile(backend.url, 'Marcus Aurelius');
|
||||
|
||||
await page.goto('/voices');
|
||||
|
||||
await expect(page.getByText(profile.name).first()).toBeVisible();
|
||||
});
|
||||
Reference in New Issue
Block a user