Files
LocalAI/core/http/react-ui/e2e/page-render-smoke.spec.js
T
mudler-agentandEttore Di Giacinto 60254e582d refactor(ui): remove the built-in copies of the add-on pages (#12852)
The Face recognition, Voice recognition, Voice library, Fine-tune and
Quantize pages now live only in their add-ons. The router still kept a
built-in copy of each one and showed it when the add-on was not
installed, which meant two pages to maintain for the same job.

Replace the MovedPage wrapper with a plain redirect. The old addresses
(/app/face, /app/voice, /app/voice-library, /app/fine-tune and the
rest) keep working and always open the add-on route. When the add-on is
not installed or not ready, the add-on shell shows its "not available"
page. The model of /app/face/:model and /app/voice/:model still travels
as ?model=.

Delete the six page files, the components, styles and helpers only they
used, the biometrics translation namespace, and the end-to-end specs
that tested the built-in copies. Drop the two add-on parity tests that
compared the add-on page with the deleted core page. Server APIs and
feature flags are unchanged.


Assisted-by: Claude:claude-sonnet-5-5 [Claude Code]

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
2026-10-23 11:54:53 +02:00

69 lines
2.9 KiB
JavaScript

import { test, expect } from './coverage-fixtures.js'
import { installStudioAddons } from './studio-addon.js'
// Render-smoke coverage. Each page is lazy-loaded and runs its full render +
// initial effects on mount, so a bare visit captures the bulk of a page's
// lines — cheap, real coverage for pages that have no dedicated spec yet.
//
// This is the project's preferred way to keep the UI coverage gate green:
// raise the floor by covering more, rather than loosening the gate's
// tolerance (see CONTRIBUTING.md → "React UI coverage"). Auth is disabled in
// the test server, so RequireAdmin/RequireFeature resolve to isAdmin=true and
// every gated route renders without an auth/capability mock.
//
// Asserts the page mounted (its .page-title header is visible) and that it did
// not bounce to a gate redirect (/login or back to /app home).
const PAGES = [
['/app/usage', 'Usage'],
['/app/traffic', 'Traffic overview'],
['/app/traffic/models', 'Traffic models'],
['/app/traffic/host', 'GPU and host'],
['/app/traffic/prometheus', 'Prometheus'],
['/app/traces', 'Traces'],
['/app/middleware', 'Middleware'],
['/app/account', 'Account'],
['/app/models', 'Models'],
['/app/operate', 'Operate overview'],
['/app/backends', 'Backends'],
['/app/activity', 'Activity'],
['/app/settings', 'Settings'],
['/app/nodes', 'Nodes'],
['/app/scheduling', 'Placement rules'],
['/app/failover', 'Failover'],
['/app/nodes/add', 'Add a node'],
['/app/p2p', 'P2P'],
]
test.describe('Page render smoke', () => {
for (const [path, label] of PAGES) {
test(`renders ${label} (${path})`, async ({ page }) => {
await page.goto(path)
// .page-title for the normal header; .empty-state-title for pages that
// render a gated/empty state (e.g. Account when auth is disabled).
await expect(page.locator('.page-title, .view-bar__title, .empty-state-title, .dk-empty-title, .op-status__title, .op-runtime h1, .sw-page h1, .tf-title, .st-title').first()).toBeVisible({ timeout: 15_000 })
await expect(page).toHaveURL(new RegExp(path.replace(/\//g, '\\/') + '$'))
})
}
})
// Studio and Talk are add-ons: the pages draw inside the add-on shell once the
// built bundles are installed, and the old addresses open them there.
const ADDON_PAGES = [
['/app/addons/talk/talk', 'Talk', '.talk-page'],
['/app/addons/studio/studio', 'Studio', '[data-testid="studio-overview"]'],
['/app/addons/studio/studio/threed', 'Studio 3D', '.ws-title'],
['/app/talk', 'Talk (old address)', '.talk-page'],
['/app/studio/threed', 'Studio 3D (old address)', '.ws-title'],
]
test.describe('Add-on page render smoke', () => {
for (const [path, label, marker] of ADDON_PAGES) {
test(`renders ${label} (${path})`, async ({ page }) => {
await installStudioAddons(page)
await page.goto(path)
await expect(page.locator(marker).first()).toBeVisible({ timeout: 15_000 })
await expect(page).toHaveURL(/\/app\/addons\/(studio|talk)\//)
})
}
})