tts-voice-creator-clone-and.../tests/voice-bundle.spec.js
mARTin-B78 e8c0df027e test: fail any spec that would write to the live API
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 21:00:25 +02:00

51 lines
2.3 KiB
JavaScript

// @ts-check
// Voice bundle export/import in the library toolbar (mocked routes only; never touches the live library).
const { test, expect } = require('./_guard');
async function setup(page, calls) {
await page.route('**/api/voices/import', async route => {
calls.push('import');
const name = route.request().postData() || '';
if (name.includes('bad.zip')) return route.fulfill({ status: 400, json: { detail: 'Hash mismatch: audio.wav' } });
return route.fulfill({ json: { ok: true, voice_id: 'EN_F_x_2', status: 'renamed' } });
});
await page.route('**/api/voices/*/export', route => {
calls.push('export');
return route.fulfill({ body: 'PK', contentType: 'application/zip' });
});
await page.route('**/api/voices*', route => route.fulfill({ json: [] }));
await page.route('**/api/settings*', route => route.fulfill({ json: {} }));
await page.goto('/', { waitUntil: 'domcontentloaded' });
await page.waitForFunction(() => typeof window.importVoiceBundles === 'function', null, { timeout: 15_000 });
}
test('bundle buttons are labelled and at least 44px', async ({ page }) => {
await setup(page, []);
for (const id of ['export-voices-btn', 'import-voices-btn']) {
const b = page.locator('#' + id);
await expect(b).toHaveText(/Export selected|Import bundle/);
const box = await b.boundingBox().catch(() => null);
const h = await b.evaluate(el => parseFloat(getComputedStyle(el).minHeight));
expect(h).toBeGreaterThanOrEqual(44);
if (box) expect(box.height).toBeGreaterThanOrEqual(44);
}
});
test('export downloads a bundle per voice', async ({ page }) => {
const calls = [];
await setup(page, calls);
const dl = page.waitForEvent('download');
await page.evaluate(() => window.exportVoiceBundles(['EN_F_x']));
expect((await dl).suggestedFilename()).toBe('EN_F_x.voice.zip');
expect(calls).toContain('export');
});
test('import reports renamed voices and shows server errors', async ({ page }) => {
const calls = [];
await setup(page, calls);
await page.evaluate(() => window.importVoiceBundles([new File(['PK'], 'ok.zip')]));
await expect(page.locator('#toast')).toContainText('EN_F_x_2 (name was taken)');
await page.evaluate(() => window.importVoiceBundles([new File(['PK'], 'bad.zip')]));
await expect(page.locator('#toast')).toContainText('Import of bad.zip failed: Hash mismatch');
});