// @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'); });