tts-voice-creator-clone-and.../tests/rehearser.spec.js
mARTin-B78 40e42590cc Release v1.6.0: a11y (WCAG AA), i18n (DE), PWA, perf, tests, Cast UX
Cast: card/list views, sort & filter, online voice picker, "Hear a line"
sample button, AI character notes, import auto-save.

Platform: WCAG 2.1 AA accessibility pass; German UI translation + language
picker; installable PWA with offline shell; GZip + content-visibility
virtualization + lazy images + Rehearser PCM memory cap (mobile stability);
Playwright suite (desktop + iPhone); opt-in minified bundle build.

Fixes: screenplay parser false characters; Fish-Speech inline-tag tones;
narrator/voice pickers list full library; clone GUI rework; fish.audio
import dedup; voice-ID rename; bulk-delete modal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 14:23:35 +02:00

53 lines
1.9 KiB
JavaScript

// @ts-check
// Functional safety net for the Script Rehearser — guards the parser/cast pipeline
// while rehearser.js is split into smaller modules (#8).
const { test, expect } = require('@playwright/test');
const SCRIPT = `FADE IN
EXT. HARBOR - NIGHT
A ship rocks in the dark.
JACK
We need to find the compass.
GIBBS
Aye, Captain. But the tide is against us.
JACK
Then we sail against the tide.`;
async function navTo(page, section) {
await page.waitForFunction(() => typeof window.navTo === 'function', null, { timeout: 15_000 });
await page.evaluate((s) => window.navTo(s), section);
}
test('parses a screenplay and builds the cast', async ({ page }) => {
await page.goto('/', { waitUntil: 'domcontentloaded' });
await navTo(page, 's-rehearser');
// Go to the Cast tab area: paste a script and parse
await page.waitForSelector('#reh-script-text', { timeout: 10_000 });
await page.fill('#reh-script-text', SCRIPT);
await page.click('#reh-parse-btn');
// Cast cards should appear: Narrator + JACK + GIBBS (title page / FADE IN filtered out)
const cards = page.locator('#reh-cast-list .reh-cast-card');
await expect(cards).toHaveCount(3, { timeout: 10_000 });
await expect(page.locator('#reh-cast-list')).toContainText('JACK');
await expect(page.locator('#reh-cast-list')).toContainText('GIBBS');
// Scene heading / FADE IN must NOT have become characters
await expect(page.locator('#reh-cast-list')).not.toContainText('FADE IN');
await expect(page.locator('#reh-cast-list')).not.toContainText('HARBOR');
// A "Hear a line" sample button appears once a character has a voice assigned
await expect(page.locator('.reh-cc-sample-btn')).toHaveCount(0);
await page.evaluate(() => {
rehState.cast['JACK'].voice = 'EN_Test_Voice';
renderCastList();
});
await expect(page.locator('.reh-cc-sample-btn').first()).toBeVisible();
await expect(page.locator('.reh-cc-sample-btn').first()).toContainText('Hear a line');
});