From 2545fb8cbaf82e5b9f7ebbafd86f43ac00e4b22c Mon Sep 17 00:00:00 2001 From: "pulse-triage[bot]" <249995291+pulse-triage[bot]@users.noreply.github.com> Date: Tue, 22 Sep 2026 23:49:13 +0100 Subject: [PATCH] test(web): guard PBS identity rows across snapshot refresh (#1723) The Backups drawer renders Discovery and Metrics Target from the merged host resource, so a snapshot-driven correlation change would silently flip those labels. Add discoveryTarget to the retained real-browser fixture and assert both identity rows stay present and byte-identical across reordered, timer-driven snapshots and datastore switching. The guard passes on the current source; it does not reproduce the reporter's live target-spelling flicker. Change-source: pulse-maintainer --- .../pbs-host-history-correlation.tsx | 3 ++ .../check-pbs-host-history-correlation.cjs | 34 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/frontend-modern/browser-tests/pbs-host-history-correlation.tsx b/frontend-modern/browser-tests/pbs-host-history-correlation.tsx index cbb60a02aa..72e46eb0a3 100644 --- a/frontend-modern/browser-tests/pbs-host-history-correlation.tsx +++ b/frontend-modern/browser-tests/pbs-host-history-correlation.tsx @@ -39,6 +39,7 @@ const pbs = { }, // The PBS service target: correct for the service, but it has no host series. metricsTarget: { resourceType: 'agent', resourceId: 'pbs-1' }, + discoveryTarget: { resourceType: 'agent', resourceId: 'pbs-1' }, platformData: { sources: ['pbs'], pbs: { instanceId: 'proxback', hostname: 'proxback-vm', datastoreCount: 2 }, @@ -60,6 +61,7 @@ const guest = { memory: { current: 16.9, total: 8000, used: 1352, free: 6648 }, agent: sharedAgent, metricsTarget: { resourceType: 'vm', resourceId: 'proxmox:100' }, + discoveryTarget: { resourceType: 'agent', resourceId: 'proxback-vm' }, platformData: { sources: ['proxmox', 'agent'], agent: sharedAgent }, } as unknown as Resource; @@ -76,6 +78,7 @@ const standalone = { lastSeen: Date.now(), agent: sharedAgent, metricsTarget: { resourceType: 'agent', resourceId: 'agent-proxback' }, + discoveryTarget: { resourceType: 'agent', resourceId: 'proxback-vm' }, platformData: { sources: ['agent', 'pbs'], agent: sharedAgent }, } as unknown as Resource; diff --git a/scripts/check-pbs-host-history-correlation.cjs b/scripts/check-pbs-host-history-correlation.cjs index 6b48f45a61..1d0cab8afc 100644 --- a/scripts/check-pbs-host-history-correlation.cjs +++ b/scripts/check-pbs-host-history-correlation.cjs @@ -38,6 +38,23 @@ const launchOptions = { const failures = []; const topologies = ['pbs-only', 'side-by-side', 'guest']; const wrong = 'agent/pbs-1'; + // Reporter avsdev-cw sees the Identity card's "Discovery" and "Metrics + // Target" rows flick between a service id and the correlated host id while + // the table sits idle. Read the rendered rows so a snapshot-driven identity + // change fails the check instead of only being visible to a human. + const readIdentityRows = (detail) => + detail + .locator('[data-testid="resource-identity-section"] tr') + .evaluateAll((rows) => + rows + .map((row) => { + const cells = row.querySelectorAll('td'); + return cells.length >= 2 + ? [cells[0].textContent.trim(), cells[1].textContent.trim()] + : null; + }) + .filter((row) => row && row[0]), + ); try { await server.listen(); browser = await chromium.launch(launchOptions); @@ -170,6 +187,16 @@ const launchOptions = { .locator('[data-testid="guest-history-plot"] path') .count(); assert.ok(pathsBefore > 0); + const identityBefore = await readIdentityRows(detail); + const identityLabels = identityBefore.map(([label]) => label); + assert.ok( + identityLabels.includes('Discovery'), + 'Discovery identity row missing from the drawer', + ); + assert.ok( + identityLabels.includes('Metrics Target'), + 'Metrics Target identity row missing from the drawer', + ); await page .getByRole('button', { name: 'Schedule automatic snapshot' }) .click(); @@ -205,9 +232,16 @@ const launchOptions = { .count(), pathsBefore, ); + const identityAfter = await readIdentityRows(detail); + assert.deepEqual( + identityAfter, + identityBefore, + 'Identity rows changed after a refreshed snapshot', + ); observations.push({ datastore, paths: pathsBefore, + identity: identityAfter, refreshPreservedHistory: true, }); }