From cfdfe8f7e92a0e0120314693af4daa92339ce275 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Wed, 21 Oct 2026 00:57:40 +0000 Subject: [PATCH] test(ui): build the Face and Fine-tuning bundles in the global setup The navigation spec serves the built Fine-tuning bundle, but nothing built it, so two specs failed on a fresh checkout when the dist folder was missing. The spec also built the Face bundle in a hook that every worker runs, and a build rewrites the folder the other workers serve. The global setup now builds Studio, Talk, Face and Fine-tuning once, before the workers start. The spec builds the two bundles itself only when it runs without the global setup. Assisted-by: Claude Code:claude-sonnet-5-5 node Signed-off-by: Ettore Di Giacinto --- core/http/react-ui/e2e/addon-navigation.spec.js | 10 ++++++---- core/http/react-ui/e2e/global-setup.js | 2 +- core/http/react-ui/e2e/studio-addon.js | 8 +++++++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/core/http/react-ui/e2e/addon-navigation.spec.js b/core/http/react-ui/e2e/addon-navigation.spec.js index 3a63df809..cfb6eea95 100644 --- a/core/http/react-ui/e2e/addon-navigation.spec.js +++ b/core/http/react-ui/e2e/addon-navigation.spec.js @@ -3,7 +3,7 @@ import fs from 'node:fs' import path from 'node:path' import { fileURLToPath } from 'node:url' import { ADMIN, MEMBER, app, sessionFor, mockAddons } from './addons-fixtures.js' -import { installStudioAddons, packagedApp } from './studio-addon.js' +import { buildAddonBundles, installStudioAddons, packagedApp } from './studio-addon.js' import { FACE_MODEL, clipFile, faces, match, mockIdentity, people, photoFile } from './identity-fixtures.js' // Studio and Talk are packaged add-ons, not built-in tiles: the specs install @@ -449,14 +449,16 @@ test.describe('Add-on navigation: the Voice recognition page', () => { }) // The built Face module, served the same way. dist/ is not committed, so the -// spec builds it once per run with the builder of the add-on. +// global setup builds it once per run with the builder of the add-on. const FT_DIST = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../addons/fine-tuning/ui/dist') const FACE_DIST = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../addons/face/ui/dist') const FACE_BASE = `/api/addons/face/assets/${'e'.repeat(64)}` test.beforeAll(async () => { - const { build } = await import('../../../../addons/face/ui/build.mjs') - await build() + // The global setup has built the bundles already. A build rewrites the + // dist folder that every worker serves, so a worker must not start one. + if (process.env.E2E_ADDON_BUNDLES_BUILT) return + await buildAddonBundles(['face', 'fine-tuning']) }) const faceApp = () => app({ diff --git a/core/http/react-ui/e2e/global-setup.js b/core/http/react-ui/e2e/global-setup.js index 9139a314b..8d27bdf57 100644 --- a/core/http/react-ui/e2e/global-setup.js +++ b/core/http/react-ui/e2e/global-setup.js @@ -1,6 +1,6 @@ import { buildStudioAddons } from './studio-addon.js' -// Builds the Studio and Talk add-on bundles once, before the workers start. +// Builds the add-on bundles the specs serve once, before the workers start. export default async function globalSetup() { await buildStudioAddons() } diff --git a/core/http/react-ui/e2e/studio-addon.js b/core/http/react-ui/e2e/studio-addon.js index 976b69c32..e2efd995a 100644 --- a/core/http/react-ui/e2e/studio-addon.js +++ b/core/http/react-ui/e2e/studio-addon.js @@ -20,8 +20,14 @@ const built = new Map() const BUILT = 'E2E_ADDON_BUNDLES_BUILT' // Builds the bundles for the whole run. Called by the Playwright global setup. -export async function buildStudioAddons(ids = ['studio', 'talk']) { +export async function buildAddonBundles(ids) { for (const id of ids) await import(path.join(addons, id, 'ui/build.mjs')).then(m => m.build()) +} + +// The add-ons the specs serve from their build output: Studio and Talk through +// installStudioAddons, Face and Fine-tuning through their own routes. +export async function buildStudioAddons(ids = ['studio', 'talk', 'face', 'fine-tuning']) { + await buildAddonBundles(ids) process.env[BUILT] = '1' }