mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-26 19:12:50 +00:00
The two apps had drifted into unrelated themes. The portal's carried a full type scale, radius scale, shadow ramp and component defaults; the backoffice's had none of them — 55 lines defining two colour ramps and little else. With nothing to inherit, its 23 features each invented their own sizing, which is the real source of the inconsistency the UI reads with. Promote the portal's structure to `libs/shared` as `baseTheme`, and reduce both themes to what they should differ on: brand. The backoffice keeps #1e40af and the portal keeps Coastal Modern — a distinct accent tells an officer which of the two systems they are in, and the ramps are not interchangeable in contrast. Both export names are preserved, so no consumer import changes. Two properties are deliberately held back rather than shared: - `colors.gray`: the portal's blue-tinted neutrals retint every dimmed label, neutral badge and table border. The backoffice adopts them as its own reviewed change, not as a side effect of sharing a base. - `primaryShade.dark`: moves every filled control in dark mode; waits until dark mode is verified end to end. Also fixes a live bug: PageLoader coloured its primary label `navy.9`, which is defined in neither theme. Mantine drops unresolved colour keys silently, so the label in a component used by 20 files had been rendering an inherited colour. Adds a visual-regression harness to make all of this reviewable. It runs against a static gallery route rather than real pages, so it needs no API, database or auth — a theme diff cannot be masked by a migration or an expired token. The portal is the control group: it is pixel-identical across all four light/dark × desktop/tablet baselines, which is what makes the refactor provably lossless. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
66 lines
2.2 KiB
TypeScript
66 lines
2.2 KiB
TypeScript
import { defineConfig, devices } from '@playwright/test';
|
|
|
|
/**
|
|
* Visual-regression suite for theme work.
|
|
*
|
|
* Deliberately separate from `playwright.config.ts`. That suite drives real
|
|
* cross-app workflows and therefore needs the API, a database and migrations;
|
|
* this one only needs to know what the theme renders. Loading the same
|
|
* dependencies here would make a screenshot diff fail for reasons that have
|
|
* nothing to do with the theme — a migration, a seeded row, an expired token.
|
|
*
|
|
* So: static routes only, `vite preview` over an already-built bundle, no
|
|
* backend. Run `vite build` for both apps first.
|
|
*/
|
|
|
|
const PORTAL_PORT = Number(process.env.VISUAL_PORTAL_PORT ?? 4312);
|
|
const BACKOFFICE_PORT = Number(process.env.VISUAL_BACKOFFICE_PORT ?? 4313);
|
|
|
|
export const VISUAL = {
|
|
portalUrl: `http://localhost:${PORTAL_PORT}`,
|
|
backofficeUrl: `http://localhost:${BACKOFFICE_PORT}`,
|
|
};
|
|
|
|
export default defineConfig({
|
|
testDir: './visual',
|
|
workers: 1,
|
|
fullyParallel: false,
|
|
forbidOnly: !!process.env.CI,
|
|
// A visual diff that passes on a retry is a flake, and a flake here would
|
|
// mask exactly the regressions this suite exists to catch.
|
|
retries: 0,
|
|
timeout: 60_000,
|
|
expect: {
|
|
// Anti-aliasing differs slightly between runs; a handful of pixels is not
|
|
// a regression. Anything the theme actually changed is far larger.
|
|
toHaveScreenshot: { maxDiffPixelRatio: 0.01, animations: 'disabled' },
|
|
},
|
|
reporter: [['list'], ['html', { outputFolder: '../../dist/visual-report', open: 'never' }]],
|
|
|
|
use: {
|
|
trace: 'retain-on-failure',
|
|
actionTimeout: 15_000,
|
|
},
|
|
|
|
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
|
|
|
|
webServer: [
|
|
{
|
|
name: 'portal',
|
|
command: `npx vite preview --config apps/portal/vite.config.mts --port ${PORTAL_PORT} --strictPort`,
|
|
cwd: '../..',
|
|
url: VISUAL.portalUrl,
|
|
reuseExistingServer: !process.env.CI,
|
|
timeout: 120_000,
|
|
},
|
|
{
|
|
name: 'backoffice',
|
|
command: `npx vite preview --config apps/backoffice/vite.config.mts --port ${BACKOFFICE_PORT} --strictPort`,
|
|
cwd: '../..',
|
|
url: VISUAL.backofficeUrl,
|
|
reuseExistingServer: !process.env.CI,
|
|
timeout: 120_000,
|
|
},
|
|
],
|
|
});
|