// @ts-check
// Verifies the opt-in production bundle (npm run minify → static/dist/main.min.js):
// the app must load and behave identically through the single-bundle path.
const { test, expect } = require('@playwright/test');

// Block the service worker so request visibility is deterministic (the SW can serve
// cached responses without a network request, hiding them from page.on('request')).
test.use({ serviceWorkers: 'block' });

test('app works through the production bundle (?bundle=1)', async ({ page }) => {
  const errors = [];
  page.on('pageerror', (e) => errors.push(String(e)));

  let bundleRequested = false;
  page.on('request', (r) => { if (r.url().includes('/static/dist/main.min.js')) bundleRequested = true; });

  await page.addInitScript(() => { window.APP_USE_BUNDLE = true; });
  await page.goto('/?bundle=1', { waitUntil: 'domcontentloaded' });
  await expect(page.locator('#sidebar')).toBeVisible();

  // Wait for the JS pipeline to finish (navTo is defined by nav.js, loaded AFTER the
  // feature bundle) — only then is it valid to check what was loaded.
  await page.waitForFunction(() => typeof window.navTo === 'function', null, { timeout: 15_000 });

  // The bundle (not the individual feature files) must have served the modules
  expect(bundleRequested).toBeTruthy();

  // Global API from a bundled module must still be reachable (names are preserved)
  await page.evaluate(() => window.navTo('s-clone'));
  await expect(page.getByText(/Clone a Voice/i).first()).toBeVisible({ timeout: 10_000 });

  const real = errors.filter(e => /ReferenceError|TypeError|SyntaxError|is not defined|is not a function/.test(e));
  expect(real, real.join('\n')).toHaveLength(0);
});
