31 lines
1.8 KiB
JavaScript
31 lines
1.8 KiB
JavaScript
// Single import path for all specs: `const { test, expect } = require('./_guard');`
|
|
// Auto fixture that makes a spec fail if it would send a write (non-GET/HEAD/OPTIONS)
|
|
// to /api/** on the live app. It is registered first, and Playwright consults the
|
|
// most recently registered route first, so spec mocks (page.route in the spec/beforeEach)
|
|
// win; only requests no spec mock fulfilled (or route.fallback()'d) reach this handler.
|
|
const base = require('@playwright/test');
|
|
|
|
const test = base.test.extend({
|
|
// Registered after the guard, before any spec route: the app POSTs its design presets on every
|
|
// page load (voice-clone.js syncDesignPresetsToServer); answer it inertly. Spec mocks still win.
|
|
initWriteMocks: [async ({ page, liveWriteGuard }, use) => {
|
|
await page.route('**/api/voice-design-presets', (r) => (r.request().method() === 'POST' ? r.fulfill({ json: {} }) : r.fallback()));
|
|
// POST /api/voice-sources is the scrape triggered on opening the Studio section.
|
|
await page.route('**/api/voice-sources', (r) => (r.request().method() === 'POST' ? r.fulfill({ json: { total: 0, errors: [], sources: [], voices: [] } }) : r.fallback()));
|
|
await use();
|
|
}, { auto: true }],
|
|
liveWriteGuard: [async ({ page }, use) => {
|
|
const violations = [];
|
|
await page.route('**/api/**', (route) => {
|
|
const { method, url } = { method: route.request().method(), url: route.request().url() };
|
|
if (['GET', 'HEAD', 'OPTIONS'].includes(method)) return route.fallback();
|
|
violations.push(`${method} ${url}`);
|
|
return route.abort('blockedbyclient');
|
|
});
|
|
await use();
|
|
base.expect(violations, `Unmocked write(s) to the live API blocked; add a page.route mock in the spec:\n${violations.join('\n')}`).toEqual([]);
|
|
}, { auto: true }],
|
|
});
|
|
|
|
module.exports = { test, expect: base.expect };
|