Verify composed disk labels without losing paused-read context

Add owning-Web browser proof for the exact combined model after preserving the reviewed backup-reader and original upstream commits. Exercise measured label fit, independent provenance and settled same-VM resumption in Chromium and phone WebKit, while explicitly retaining failed trusted row-tap evidence. Correct only Prettier layout in the additive test resolution; do not repeat the unchanged backup suite or claim native acceptance.

Change-source: pulse-maintainer
Contract-Neutral: Browser fixtures and own-parent receipt for already composed runtime; Prettier-only assertion layout, with no new contract behaviour.
This commit is contained in:
pulse-triage[bot]
2026-10-03 23:42:25 +01:00
parent ffac59b6dc
commit 0f480d23af
5 changed files with 459 additions and 1 deletions
@@ -0,0 +1,313 @@
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const crypto = require('node:crypto');
const { chromium, webkit } = require('playwright');
const root = '/workspace/frontend-modern';
const output = '/workspace/tmp/composed-disk-labels-settled';
const sha256 = (bytes) => crypto.createHash('sha256').update(bytes).digest('hex');
const runtime = [
'frontend-modern/src/components/Workloads/stackedDiskBarModel.ts',
'frontend-modern/src/components/Workloads/StackedDiskBar.tsx',
'frontend-modern/src/components/Workloads/useStackedDiskBarState.ts',
'frontend-modern/src/components/Workloads/GuestRow.tsx',
'frontend-modern/src/components/Workloads/GuestDrawerOverview.tsx',
'frontend-modern/src/components/Workloads/DiskList.tsx',
'frontend-modern/src/utils/workloadGuestPresentation.ts',
'frontend-modern/src/utils/format.ts',
'frontend-modern/src/index.css',
];
(async () => {
fs.mkdirSync(output, { recursive: true });
const playwrightVersion = require('playwright/package.json').version;
assert.equal(
playwrightVersion,
JSON.parse(fs.readFileSync('/workspace/tests/integration/package-lock.json')).packages[
'node_modules/@playwright/test'
].version,
);
const hashes = Object.fromEntries(
runtime.map((file) => [file, sha256(fs.readFileSync(path.join('/workspace', file)))]),
);
assert.equal(
hashes[runtime[0]],
'9f50f630df8379673032052970e7cc6d287c02ecd212b3df5d16f1032be42413',
);
process.chdir(root);
const { createServer } = await import(path.join(root, 'node_modules/vite/dist/node/index.js'));
const server = await createServer({
root,
configFile: path.join(root, 'vite.config.ts'),
cacheDir: path.join(output, 'vite-cache'),
server: { host: '127.0.0.1', port: 5301, strictPort: true },
});
const results = [],
screenshots = [];
let browser;
try {
await server.listen();
for (const [name, engine, width, dark] of [
['chromium-desktop', chromium, 1365, false],
['webkit-phone', webkit, 390, true],
]) {
browser = await engine.launch(
engine === chromium
? { headless: true, channel: 'chromium', args: ['--no-sandbox'] }
: { headless: true },
);
const context = await browser.newContext({
viewport: { width, height: width === 390 ? 844 : 900 },
isMobile: width === 390,
hasTouch: width === 390,
locale: 'en-GB',
timezoneId: 'UTC',
});
const page = await context.newPage();
page.setDefaultTimeout(15000);
page.setDefaultNavigationTimeout(60000);
const errors = [],
requests = [],
checks = [],
fits = [];
page.on('pageerror', (error) => errors.push(error.message));
page.on('request', (request) =>
requests.push({
method: request.method(),
pathname: new URL(request.url()).pathname,
origin: new URL(request.url()).origin,
}),
);
await page.route('http://127.0.0.1:5301/api/**', (route) =>
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
success: true,
data: [],
alerts: [],
anomalies: [],
config: null,
}),
}),
);
await page.addInitScript((value) => {
document.addEventListener('DOMContentLoaded', () => {
if (value) document.documentElement.classList.add('dark');
});
}, dark);
const capture = async (state) => {
const file = path.join(output, `${name}-${state}.png`);
await page.screenshot({ path: file, fullPage: true });
screenshots.push({
path: path.relative('/workspace', file),
sha256: sha256(fs.readFileSync(file)),
});
};
const settle = () =>
page.evaluate(
() =>
new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(resolve))),
);
await page.goto('http://127.0.0.1:5301/browser-tests/composed-disk-labels.html');
await page.waitForFunction(() => window.__composedDiskLabels);
await settle();
const checkFit = async (expectedWidth, roomy) => {
await page.waitForFunction(
(value) =>
Math.abs(
document.querySelector('[data-fit="single"]').getBoundingClientRect().width - value,
) < 0.5,
expectedWidth,
);
await settle();
const state = await page.evaluate(() => {
const boxes = [...document.querySelectorAll('[data-fit]')].map((box) => {
const id = box.getAttribute('data-fit');
const labels = [...box.querySelectorAll('span.whitespace-nowrap')];
return {
id,
width: box.getBoundingClientRect().width,
text: box.innerText,
labels: labels.map((label) => ({
text: label.textContent,
scroll: label.scrollWidth,
client: label.clientWidth,
})),
sublabels: box.querySelectorAll('.metric-sublabel').length,
};
});
return { boxes, presentation: window.__composedDiskLabels.presentation() };
});
for (const box of state.boxes) {
for (const label of box.labels)
assert(
label.scroll <= label.client + 1,
`${name} ${box.id} ${expectedWidth}: rendered label must fit, not be ellipsised`,
);
}
for (const id of ['single', 'anomaly', 'aggregate']) {
const box = state.boxes.find((item) => item.id === id);
assert.equal(box.sublabels, roomy ? 1 : 0, `${id}: optional detail matches actual width`);
}
assert.equal(state.presentation.single.displayLabel, '60%');
assert.equal(state.presentation.anomaly.anomalyRatio, '2.5x');
assert.equal(state.presentation.aggregate.showDiskCount, true);
assert.equal(
await page.locator('[data-fit="vertical"] [data-stacked-disk-max-label]').innerText(),
'67%',
);
assert.equal(
await page.locator('[data-fit="vertical"] [data-stacked-disk-fill="vertical"]').count(),
2,
);
fits.push({ width: expectedWidth, boxes: state.boxes });
};
await checkFit(100, false);
const compactInline = await page.locator('[data-fit="inline"]').innerText();
assert(!compactInline.includes('MMMM'));
assert(compactInline.includes('iiii 67%'));
await capture('compact');
const roomyButton = page.getByRole('button', { name: 'Use roomy bars', exact: true });
if (engine === chromium) {
await roomyButton.focus();
await page.keyboard.press('Enter');
} else await roomyButton.tap();
await checkFit(320, true);
assert((await page.locator('[data-fit="inline"]').innerText()).includes('MMMM 50%'));
assert((await page.locator('[data-fit="inline"]').innerText()).includes('iiii 67%'));
await capture('roomy');
checks.push(
'ResizeObserver drops optional detail at 100px and shows complete un-clipped single/anomaly/max/count and inline labels at 320px; vertical max remains truthful',
);
if (engine === chromium) {
await page.locator('[data-fit="single"] [data-stacked-disk-trigger]').hover();
const tip = page.locator('[data-tooltip-portal="true"]');
await tip.waitFor({ state: 'visible' });
assert((await tip.innerText()).includes('Guest reads paused while a backup is running.'));
assert((await tip.innerText()).includes('/data'));
await page.locator('h1').hover();
await page.getByRole('button', { name: 'Mark observation fresh' }).click();
await page.locator('[data-fit="single"] [data-stacked-disk-trigger]').hover();
await tip.waitFor({ state: 'visible' });
assert(!(await tip.innerText()).includes('Guest reads paused'));
assert((await tip.innerText()).includes('/data'));
await page.locator('h1').hover();
checks.push(
'Caller-owned paused-read tooltip survives measured model; fresh same-disk update removes only status',
);
}
// Exercise the existing production guest callers, but only the combined
// stale-to-fresh boundary, not an unchanged eight-reason acceptance run.
await page.goto('http://127.0.0.1:5301/browser-tests/guest-disk-deferral.html');
await page.waitForFunction(() => window.__guestDiskEvidence);
const row = page.locator('[data-guest-id="fixture-pve:pve-a:101"]');
const cell = row.locator('[data-workload-col="disk"]');
if (engine === chromium) await row.click();
else
// WebKit's trusted tap emitted no click on this production row in the
// separately retained input diagnostic. Check rendering via a mouse
// click, without asserting touch acceptance or masking that failure.
await row
.locator('[data-workload-col="name"]')
.getByText('backup-guest', { exact: true })
.click();
const drawer = page.getByRole('region', { name: 'Guest Overview' });
await drawer.waitFor({ state: 'visible' });
const paused = await cell.getAttribute('title');
assert(paused.startsWith('Using last known disk stats. '));
assert(paused.includes('VM operation lock, such as a backup.'));
assert((await drawer.innerText()).includes(paused));
assert(
(await page.getByRole('region', { name: 'Guest disk list' }).innerText()).includes(paused),
);
assert((await drawer.innerText()).includes('/data'));
if (engine === chromium) {
await page.locator('h1').hover();
await cell.locator('[data-stacked-disk-trigger]').hover();
await page.locator('[data-tooltip-portal="true"]').waitFor({ state: 'visible' });
assert((await page.locator('[data-tooltip-portal="true"]').innerText()).includes(paused));
await page.locator('h1').hover();
}
await capture('guest-paused');
await page.evaluate(() => {
window.__composedOriginalRow = document.querySelector(
'[data-guest-id="fixture-pve:pve-a:101"]',
);
window.__guestDiskEvidence.update({ reason: '', data: true, usage: 75 });
});
await page.waitForFunction(
() => !document.querySelector('[data-workload-col="disk"]').hasAttribute('title'),
);
assert(!(await drawer.innerText()).includes('Using last known disk stats.'));
assert.equal(await drawer.getByRole('progressbar').getAttribute('aria-valuenow'), '75');
assert.equal(
await page.evaluate(
() =>
window.__composedOriginalRow ===
document.querySelector('[data-guest-id="fixture-pve:pve-a:101"]'),
),
true,
);
// AnimatedNumber must finish; do not capture an intermediate old percent
// beside the new capacity and claim that it is a settled observation.
await page.waitForFunction(() =>
document.querySelector('[data-workload-col="disk"]').textContent.includes('75%'),
);
await capture('guest-fresh');
checks.push(
'Production GuestRow, Overview and disk list retain paused provenance; same-VM resumption clears notice and updates to 75% without remount',
);
assert.equal(
await page.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth),
true,
);
assert.deepEqual(errors, []);
assert(
requests.every(
(request) => request.origin === 'http://127.0.0.1:5301' && request.method === 'GET',
),
);
results.push({
name,
browserVersion: browser.version(),
viewport: { width, height: width === 390 ? 844 : 900 },
dark,
checks,
fits,
errors,
requestCount: requests.length,
});
await context.close();
await browser.close();
browser = null;
}
fs.writeFileSync(
path.join(output, 'result.json'),
JSON.stringify(
{
result: 'passed',
verifiedAt: new Date().toISOString(),
playwrightVersion,
runtimeHashes: hashes,
results,
screenshots,
limitations:
'Synthetic component/CSS/browser composition only; not native QGA, thaw, appliance acceptance, installation, release qualification or availability.',
},
null,
2,
),
);
process.stdout.write(
`COMPOSED_DISK_LABELS_PASSED ${results.length} browsers / ${screenshots.length} screenshots\n`,
);
} finally {
if (browser) await browser.close();
await server.close();
}
})().catch((error) => {
process.stderr.write(`${error.stack}\n`);
process.exitCode = 1;
});
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Composed disk label verification</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="./composed-disk-labels.tsx"></script>
</body>
</html>
@@ -0,0 +1,93 @@
// Production disk model, shell, ResizeObserver and CSS; synthetic observations.
// This fixture verifies composition, not collection, thaw or native recovery.
import { createSignal, For } from 'solid-js';
import { render } from 'solid-js/web';
import { StackedDiskBar } from '../src/components/Workloads/StackedDiskBar';
import {
buildStackedDiskBarPresentation,
type StackedDiskBarProps,
} from '../src/components/Workloads/stackedDiskBarModel';
import type { Disk } from '../src/types/api';
import type { AnomalyReport } from '../src/types/aiIntelligence';
import '../src/index.css';
const GiB = 1024 ** 3;
const disk = (mountpoint: string, total: number, used: number): Disk => ({
mountpoint,
total: total * GiB,
used: used * GiB,
free: (total - used) * GiB,
usage: (used / total) * 100,
type: 'ext4',
});
const single = [disk('/data', 440, 265)];
const multiple = [disk('/MMMM', 180, 90), disk('/iiii', 260, 175)];
const anomaly: AnomalyReport = {
resource_id: 'fixture-pve:pve-a:101',
resource_name: 'backup-guest',
resource_type: 'vm',
metric: 'disk',
current_value: 60,
baseline_mean: 24,
baseline_std_dev: 4,
z_score: 9,
severity: 'high',
description: 'Synthetic disk anomaly',
};
const cases: { id: string; label: string; props: StackedDiskBarProps }[] = [
{ id: 'single', label: 'Single filesystem', props: { disks: single } },
{ id: 'anomaly', label: 'Filesystem with anomaly', props: { disks: single, anomaly } },
{
id: 'aggregate',
label: 'Aggregate with fullest disk and count',
props: { disks: multiple, mode: 'aggregate', showDiskCount: true },
},
{ id: 'inline', label: 'Equal slots, different glyph widths', props: { disks: multiple } },
{
id: 'vertical',
label: 'Host micro-bars and fullest disk',
props: { disks: multiple, mode: 'vertical-bars' },
},
];
function Fixture() {
const [width, setWidth] = createSignal(100);
const [status, setStatus] = createSignal(
'Using last known disk stats. Guest reads paused while a backup is running.',
);
(window as any).__composedDiskLabels = {
width: setWidth,
presentation: () =>
Object.fromEntries(
cases.map((item) => [item.id, buildStackedDiskBarPresentation(item.props, width())]),
),
};
return (
<main class="min-h-screen space-y-5 bg-surface p-3 text-base-content">
<h1 class="text-base font-semibold">Composed disk evidence</h1>
<div class="flex flex-wrap gap-2">
<button class="rounded-sm border border-border p-2" onClick={() => setWidth(100)}>
Use compact bars
</button>
<button class="rounded-sm border border-border p-2" onClick={() => setWidth(320)}>
Use roomy bars
</button>
<button class="rounded-sm border border-border p-2" onClick={() => setStatus('')}>
Mark observation fresh
</button>
</div>
<For each={cases}>
{(item) => (
<section aria-label={item.label} class="space-y-2">
<h2 class="text-sm font-medium">{item.label}</h2>
<div data-fit={item.id} style={{ width: `${width()}px` }}>
<StackedDiskBar {...item.props} statusMessage={status()} />
</div>
</section>
)}
</For>
</main>
);
}
render(() => <Fixture />, document.getElementById('root')!);
@@ -0,0 +1,37 @@
{
"version": 1,
"base_sha": "ffac59b6dcccaf03f52fb4ba747b6f99a79ba9b0",
"verified_at": "2026-10-03T22:38:46.141Z",
"result": "passed",
"changed_paths": [
"frontend-modern/src/components/Workloads/stackedDiskBarModel.ts"
],
"content_sha256": {
"frontend-modern/src/components/Workloads/stackedDiskBarModel.ts": "9f50f630df8379673032052970e7cc6d287c02ecd212b3df5d16f1032be42413"
},
"routes": [
"/browser-tests/composed-disk-labels.html",
"/browser-tests/guest-disk-deferral.html"
],
"viewports": [
{
"width": 1365,
"height": 900
},
{
"width": 390,
"height": 844
}
],
"states": [
"Exact combined deferred-read statusMessage and measured-glyph disk model; production StackedDiskBar, ResizeObserver, GuestRow, Overview, disk list and stylesheet, synthetic observations only. Playwright 1.56.1 matches the integration lock; Chromium 141.0.7390.37 light desktop and WebKit 26.0 dark 390px phone.",
"100px bars retain percentages and omit optional capacity detail; equal inline slots retain iiii 67% but drop the wider MMMM label. 320px bars show whole capacity, anomaly, fullest-disk/count and inline labels without ellipsis. The micro-bars keep a truthful 67% highest-disk label.",
"Paused guest evidence retains last-known disk values and caller-owned VM-operation-lock context in row, Overview, disk list and desktop tooltip. Same-VM fresh observations clear stale context without remount; row, Overview and disk list settle at 75%. All eight final screenshots inspected.",
"Phone drawer rendering is verified using an emulated mouse click on the guest name. Separate trusted WebKit row/name taps emitted no click and did not open the drawer; this pass does not establish touch acceptance or clear that adverse observation. No native collection, QGA/thaw, installation or release claim."
],
"interactions": [
"Chromium keyboard focus and Enter / WebKit tap on the native Roomy button drive ResizeObserver from 100px to 320px. Independent DOM scrollWidth/clientWidth checks verify rendered label fit.",
"Desktop hover reads paused provenance beside unchanged /data evidence, then confirms fresh same-disk update removes only that status. Production GuestRow/Overview/list callers are exercised at both viewports; the phone guest is opened by mouse click, not a claimed tap success.",
"Fresh source update preserves the same row node, clears stale status, updates the Overview progressbar and waits for AnimatedNumber to settle at 75% before capture. No page error, off-origin request, non-GET request or horizontal page overflow."
]
}
@@ -1516,7 +1516,10 @@ describe('Docker native tables', () => {
expect(screen.getByText('2')).toBeInTheDocument();
// The snake_case rollout token reads as words; the raw token stays in the title.
expect(screen.getByText('Rollback started')).toBeInTheDocument();
expect(screen.getByText('Rollback started')).toHaveClass('whitespace-normal', 'wrap-break-word');
expect(screen.getByText('Rollback started')).toHaveClass(
'whitespace-normal',
'wrap-break-word',
);
expect(
screen.getByText('Rollback started').closest('[title]')?.getAttribute('title'),
).toContain('rollback_started');