mirror of
https://github.com/mudler/LocalAI.git
synced 2026-05-31 12:07:45 -04:00
* Curate the highlight.js build to ~29 languages (lib/core + the common set) instead of the full ~190-grammar default: -787 KB raw / -230 KB gz on the base bundle. * Code-split every route via React.lazy with a per-layout <Suspense> in App.jsx so the sidebar stays mounted on navigation. Initial entry chunk drops from 3194 KB raw / 887 KB gz to 397 KB / 122 KB (-87%). Warm chunks on sidebar hover/focus/touch via a preload registry so the click finds the chunk already in flight or cached. * Migrate Playwright coverage from istanbul (build-time counters) to native Chromium V8 coverage, with per-worker accumulation + conversion. Suite drops from 71s to 30s at 20 workers (~58%) at the non-instrumented floor. * Keep the coverage gate bundling-invariant: the coverage build inlines dynamic imports so every shipped source file lands in the denominator (otherwise untested page chunks silently drop out and inflate the percentage). Production builds stay code-split. * Add UI_TEST_WORKERS=N Makefile knob; tighten coverage tolerance to 0.8pp now that jitter sits near istanbul's ~0.5pp again. Assisted-by: Claude:claude-opus-4-7 [Claude Code] Signed-off-by: Richard Palethorpe <io@richiejp.com>
74 lines
2.5 KiB
JavaScript
74 lines
2.5 KiB
JavaScript
// Playwright test fixture that harvests istanbul code coverage.
|
|
//
|
|
// When the app is built with COVERAGE=true (see vite.config.js), every source
|
|
// module is instrumented and exposes its counters on window.__coverage__. This
|
|
// fixture writes that object to .nyc_output/ after each test so `nyc report`
|
|
// can merge the runs into a per-file coverage report.
|
|
//
|
|
// The app is a React SPA (client-side routing), so window.__coverage__
|
|
// accumulates across in-app navigation within a single test; only a full page
|
|
// reload / fresh page.goto resets it. Specs import { test, expect } from this
|
|
// module instead of '@playwright/test' so collection is automatic.
|
|
import { test as base, expect } from '@playwright/test'
|
|
import { mkdirSync, writeFileSync } from 'node:fs'
|
|
import { randomUUID } from 'node:crypto'
|
|
import path from 'node:path'
|
|
|
|
const COVERAGE_DIR = path.resolve(process.cwd(), '.nyc_output')
|
|
const V8_COVERAGE = process.env.PW_V8_COVERAGE === '1'
|
|
|
|
const withCoverage = base.extend({
|
|
// Worker-scoped V8 coverage accumulator: collects every test's native
|
|
// Chromium coverage and converts it to istanbul ONCE at worker teardown
|
|
// (conversion is expensive; see e2e/v8-coverage.js). null when V8 mode is off.
|
|
_v8acc: [
|
|
async ({}, use) => {
|
|
if (!V8_COVERAGE) {
|
|
await use(null)
|
|
return
|
|
}
|
|
const { createAccumulator } = await import('./v8-coverage.js')
|
|
const acc = createAccumulator()
|
|
await use(acc)
|
|
await acc.flush()
|
|
},
|
|
{ scope: 'worker' },
|
|
],
|
|
|
|
page: async ({ page, _v8acc }, use) => {
|
|
// V8 coverage path: collect native Chromium coverage (cheap), hand it to the
|
|
// worker accumulator on teardown. Avoids running an instrumented bundle.
|
|
if (V8_COVERAGE) {
|
|
const { startV8 } = await import('./v8-coverage.js')
|
|
await startV8(page)
|
|
await use(page)
|
|
try {
|
|
_v8acc.add(await page.coverage.stopJSCoverage())
|
|
} catch {
|
|
// page already closed — nothing to collect
|
|
}
|
|
return
|
|
}
|
|
|
|
await use(page)
|
|
|
|
let coverage
|
|
try {
|
|
coverage = await page.evaluate(() => window.__coverage__)
|
|
} catch {
|
|
// Page was already closed by the test — nothing to collect.
|
|
return
|
|
}
|
|
if (!coverage) return // build wasn't instrumented (COVERAGE unset)
|
|
|
|
mkdirSync(COVERAGE_DIR, { recursive: true })
|
|
writeFileSync(
|
|
path.join(COVERAGE_DIR, `playwright-${randomUUID()}.json`),
|
|
JSON.stringify(coverage),
|
|
)
|
|
},
|
|
})
|
|
|
|
export const test = withCoverage
|
|
export { expect }
|