mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-26 05:29:45 +00:00
fix(e2e): preserve accessible controls and deep drawer navigation
Preserve source provenance in REST-loaded resources so owning-snapshot consumers retain provider context and host placement. Keep visible control wording in accessible names and retain readable command and navigation text in both themes. Token fixtures now await mounted browser bootstrap before handing control to the next journey. Measure bounded platform table items together with their inline details so scrolling down a tall drawer cannot unmount the resource being inspected. Retain regression coverage for bootstrap timing, drawer state and scroll extent, responsive controls, Patrol and availability, and align navigation assertions with current read-only capabilities and composed resource queries. Provider fixtures retain one authoritative inventory across transport updates.
This commit is contained in:
@@ -15,6 +15,19 @@
|
||||
|
||||
## Purpose
|
||||
|
||||
Infrastructure Add shortcuts and update chips follow the frontend primitives
|
||||
visible-label naming contract. Their names preserve `Add` or the displayed
|
||||
update wording and append source or host context, while keeping the existing
|
||||
installer destination and affected-agent scope. An Agent Doctor destination
|
||||
does not replace the update chip's visible action in its accessible name.
|
||||
Agent Doctor keeps evidence at its notice tone's full text contrast. Its
|
||||
scrollable repair, inspection, removal and credential commands are native
|
||||
keyboard focus targets with visible focus, so long commands remain readable
|
||||
without a pointer; copy actions and execution authority are unchanged.
|
||||
The command-access description in the installer must remain readable against
|
||||
its consent panel in both themes through the shared semantic text tokens. The
|
||||
operator needs that explanation before choosing host command authority.
|
||||
|
||||
### Command access is a named token-step choice, not a legacy option (21 October 2026)
|
||||
|
||||
The installer's command-access checkbox reads **Allow Pulse to run commands on
|
||||
|
||||
@@ -2830,7 +2830,10 @@ thought-signature, and provider-result normalization as Assistant and MCP —
|
||||
destination in `AppLayout`'s tab lists shares the nav identity-stability
|
||||
contract owned by `frontend-primitives` (`stableNavTabs.ts`): a websocket
|
||||
state frame with structurally unchanged tab content must not recreate the
|
||||
Patrol button DOM or its attention-count badge element. Patrol and the peer
|
||||
Patrol button DOM or its attention-count badge element. Utility chrome
|
||||
shares the app-shell light/dark accessibility proof, including
|
||||
readable small count badges, without changing their attention or capability
|
||||
sources. Patrol and the peer
|
||||
utility destinations commit navigation without awaiting best-effort module
|
||||
warming, so lazy-route work cannot make the shared shell drop or defer a
|
||||
tap.
|
||||
|
||||
@@ -3334,6 +3334,9 @@ a new API state machine, queue contract, or verification-accounting field.
|
||||
attention projection by severity, then actionable review posture, then
|
||||
observation recency, but it must preserve every API-owned lifecycle,
|
||||
evidence, protection, action, and verification fact in selected detail.
|
||||
Attention-row control names expose the displayed record in source order,
|
||||
through the Patrol and frontend primitives visible-label contract; rendering
|
||||
must not replace those facts with a title-only accessible name.
|
||||
The first-party `Inbox`, `Protection`, and `Activity` modes are a mutually
|
||||
exclusive presentation boundary, not API query modes: Inbox consumes the
|
||||
canonical attention projection, Protection consumes retained objectives,
|
||||
|
||||
@@ -1072,7 +1072,10 @@ responsive shell appear to ignore an operator.
|
||||
App-shell navigation rendered by `frontend-modern/src/AppLayout.tsx` must
|
||||
also keep decorative icon titles out of tab accessible names, so hosted and
|
||||
self-hosted chrome announce the canonical tab label plus meaningful badge
|
||||
counts rather than duplicating branded SVG titles. The Patrol-owned utility
|
||||
counts rather than duplicating branded SVG titles. Small navigation counts
|
||||
must retain readable contrast in
|
||||
both themes; changing a theme must not replace a readable critical badge
|
||||
with a lighter background that fails text contrast. The Patrol-owned utility
|
||||
destination remains `Patrol` over the same `/patrol` route; it must not
|
||||
alter hosted org bootstrap, entitlement loading, or commercial posture
|
||||
loading. Its badge may consume only the existing Patrol attention summary.
|
||||
|
||||
@@ -3014,6 +3014,14 @@ artifact-selection behaviour.
|
||||
deterministic token authentication after setup, and may use the server setup
|
||||
API as a fallback only when the UI wizard fails to complete cleanly under the
|
||||
managed hot-dev runtime.
|
||||
A successful token probe and a protected workspace URL do not establish
|
||||
completed browser bootstrap. Token and cookie reuse must wait for the mounted
|
||||
authenticated app shell before returning control to a journey, so a pending
|
||||
workspace redirect cannot overwrite its next deep link. Browser rejection
|
||||
remains an authentication failure rather than a reason to accept the URL or
|
||||
retry login. `tests/integration/scripts/fixture-auth.test.mjs` exercises the
|
||||
actual token helper with delayed and rejected bootstrap; the runtime-home
|
||||
onboarding browser contract also holds a real protected-state request.
|
||||
The built `index.html` must not modulepreload lazy route chunks: the SRI
|
||||
plugin runs with `preloadDynamicChunks: false` so cold start fetches only the
|
||||
entry and its static vendor imports (route-level code splitting stays
|
||||
@@ -6487,6 +6495,13 @@ truth inside Playwright helpers. `tests/integration/tests/helpers.ts` may
|
||||
offer request trackers for browser-shell contract proofs, but those helpers
|
||||
must observe page-originated traffic only and must not blur browser runtime
|
||||
requests together with `page.request` or other direct API helper calls.
|
||||
Provider inventory fixtures must own every inventory input consumed by their
|
||||
journey. `tests/integration/tests/vmware-workload-fixture.ts` serves its canonical
|
||||
REST snapshot with a mocked empty socket so a live frame cannot replace its VM
|
||||
identity during drawer inspection. Its resource-detail and exclusion-integrity
|
||||
browser proofs exercise read-only context and retain provider-admin prohibitions.
|
||||
This synthetic fixture does not establish live vCenter or websocket acceptance.
|
||||
|
||||
The shared authenticated browser fixture must not report the default mock
|
||||
runtime ready from inventory alone while historical chart initialization is
|
||||
still running. When Core E2E requests the default mock-readiness gate, the
|
||||
|
||||
@@ -165,7 +165,23 @@ native QGA/backup or update-permission recovery.
|
||||
shared history query and Docs with synthetic observations at desktop/phone
|
||||
widths, including keyboard/touch guidance and same-node updates.
|
||||
|
||||
### Navigation labels retain their visible badge text (24 October 2026)
|
||||
### Control names retain their visible wording
|
||||
|
||||
Action names include their visible text in source order. Context may extend a
|
||||
short label, but must not replace it with a different action name. Infrastructure
|
||||
group shortcuts retain `Add` before their source label; update chips retain
|
||||
their visible count and update wording before the host context. Patrol attention
|
||||
rows use their native button contents so severity, title, summary and observation
|
||||
age remain part of the name as the displayed record changes.
|
||||
Scrollable command displays are native keyboard focus targets with visible
|
||||
focus. A sibling Copy button does not make the command's own scroll area
|
||||
keyboard reachable.
|
||||
Semantic muted text must meet normal-text contrast on the surface and hover
|
||||
backgrounds where controls and disclosures use it in either theme. Dark muted
|
||||
text uses slate-300 so slate-700 hover/consent panels remain readable; individual
|
||||
callers must not compensate for an inaccessible shared token. The authenticated
|
||||
browser accessibility proof covers both themes and an explicitly hovered
|
||||
Patrol row as well as expanded installer and Agent Doctor states.
|
||||
|
||||
Desktop and mobile utility links include their visible label and badge numbers
|
||||
contiguously, in source order, in the accessible name (WCAG 2.5.3). Mobile
|
||||
@@ -1316,6 +1332,14 @@ the mounted window advances far faster than the real scroll position and drops a
|
||||
group's rows mid-scroll. The controller samples several leading siblings and
|
||||
keeps the tallest, so uniform tables still measure their real row height while
|
||||
mixed group/content lists keep a content-scale estimate.
|
||||
Native table rows additionally measure each mounted item's summary and any
|
||||
`InlineDetailTableRow` marked `data-inline-detail-row` as one logical item.
|
||||
Keyed measurements own prefix offsets, native spacer extent and pixel-to-item
|
||||
lookup, so scrolling within a tall drawer cannot advance past and unmount its
|
||||
owner. Offscreen items retain their last measured size until remeasured.
|
||||
Resize and direct-child mutation observers update those measurements outside
|
||||
the scroll/wheel path. The mounted-item budget and native touch path remain
|
||||
unchanged. List surfaces retain representative height estimation.
|
||||
|
||||
Shared workload, node, Docker-host, and resource-drawer history presentation
|
||||
must scope retained observations to the exact resource type, resource ID and
|
||||
|
||||
@@ -15,6 +15,16 @@
|
||||
|
||||
## Purpose
|
||||
|
||||
Attention-row buttons derive their accessible names from their visible content,
|
||||
following the frontend primitives control-name contract. Severity, title,
|
||||
summary and relative observation age remain available to assistive technology
|
||||
in display order. A title-only override must not hide the other visible label
|
||||
text; selection, keyboard review and detail focus restoration keep their existing
|
||||
owners.
|
||||
Mobile return controls retain `Back to list` in their contextual names. The
|
||||
expanded resource-copy control retains its visible `Copy ID` name, including
|
||||
after copying; the fuller explanation remains its tooltip.
|
||||
|
||||
### One-page Patrol setup on the Patrol page
|
||||
|
||||
When Patrol is blocked because no provider is connected, Pulse Intelligence
|
||||
|
||||
@@ -1777,6 +1777,13 @@ change may globally weaken the Task 03 lifecycle-state idempotency invariant.
|
||||
state, mounted-row budgets, viewport sync, and reveal timing; it must not
|
||||
fork the repeated `TableRow` / `TableCell` / surface-alt / click-containment
|
||||
shell inside workload, infrastructure, or platform table render paths.
|
||||
Bounded platform tables use keyed measured item heights, including their
|
||||
native inline details, when mapping scroll pixels to their mounted runway
|
||||
and spacers. Reading a tall drawer must keep its owner mounted without
|
||||
disabling windowing or increasing the row budget. Measurements update on
|
||||
resize and row mutation rather than adding per-row layout reads to each
|
||||
scroll event. The mounted `PlatformWindowedRows.test.tsx` regression covers
|
||||
retained editing state inside a tall drawer and its offscreen scroll extent.
|
||||
Pod-mode workload filters must use the workload-owned
|
||||
`K8s cluster` / `All K8s clusters` labels for Kubernetes context selection,
|
||||
rather than a generic `Cluster` label that can be confused with Proxmox
|
||||
|
||||
@@ -1884,7 +1884,8 @@
|
||||
"frontend-modern/src/api/__tests__/agentProfiles.test.ts",
|
||||
"frontend-modern/src/api/__tests__/monitoring.test.ts",
|
||||
"frontend-modern/src/components/Settings/__tests__/InfrastructureOperationsModel.test.tsx",
|
||||
"frontend-modern/src/components/Settings/__tests__/settingsArchitecture.test.ts"
|
||||
"frontend-modern/src/components/Settings/__tests__/settingsArchitecture.test.ts",
|
||||
"tests/integration/tests/83-product-trust-accessibility.spec.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -4430,7 +4431,8 @@
|
||||
"exact_files": [
|
||||
"frontend-modern/src/__tests__/App.architecture.test.ts",
|
||||
"frontend-modern/src/utils/__tests__/apiClient.issue1640.test.ts",
|
||||
"frontend-modern/src/utils/__tests__/apiClient.org.test.ts"
|
||||
"frontend-modern/src/utils/__tests__/apiClient.org.test.ts",
|
||||
"tests/integration/tests/83-product-trust-accessibility.spec.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -4732,6 +4734,7 @@
|
||||
"tests/integration/scripts/relay-mobile-token-helper.go",
|
||||
"tests/integration/tests/helpers.ts",
|
||||
"tests/integration/tests/runtime-defaults.ts",
|
||||
"tests/integration/tests/vmware-workload-fixture.ts",
|
||||
"VERSION"
|
||||
],
|
||||
"release_cycle_artifact_globs": [
|
||||
@@ -5238,6 +5241,20 @@
|
||||
"tests/integration/tests/16-dev-runtime-recovery.spec.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "browser-fixture-helpers",
|
||||
"label": "authenticated browser fixture and onboarding handoff proof",
|
||||
"match_prefixes": [],
|
||||
"match_files": [
|
||||
"tests/integration/tests/helpers.ts"
|
||||
],
|
||||
"allow_same_subsystem_tests": false,
|
||||
"test_prefixes": [],
|
||||
"exact_files": [
|
||||
"tests/integration/scripts/fixture-auth.test.mjs",
|
||||
"tests/integration/tests/62-runtime-home-onboarding-contract.spec.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "dev-runtime-orchestration",
|
||||
"label": "dev runtime orchestration proof",
|
||||
@@ -5264,7 +5281,6 @@
|
||||
"tests/integration/README.md",
|
||||
"tests/integration/scripts/managed-dev-runtime.mjs",
|
||||
"tests/integration/scripts/managed-local-backend.mjs",
|
||||
"tests/integration/tests/helpers.ts",
|
||||
"tests/integration/tests/runtime-defaults.ts"
|
||||
],
|
||||
"allow_same_subsystem_tests": false,
|
||||
@@ -5352,6 +5368,20 @@
|
||||
"scripts/installtests/native_unix_contract_runner_test.go",
|
||||
"scripts/tests/test_native_installer_contract_runner.py"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "browser-provider-inventory-fixture",
|
||||
"label": "authoritative browser provider inventory fixture proof",
|
||||
"match_prefixes": [],
|
||||
"match_files": [
|
||||
"tests/integration/tests/vmware-workload-fixture.ts"
|
||||
],
|
||||
"allow_same_subsystem_tests": false,
|
||||
"test_prefixes": [],
|
||||
"exact_files": [
|
||||
"tests/integration/tests/39-vmware-resource-detail-drawer.spec.ts",
|
||||
"tests/integration/tests/41-vmware-phase1-exclusion-integrity.spec.ts"
|
||||
]
|
||||
}
|
||||
],
|
||||
"match_files": null
|
||||
@@ -5583,7 +5613,8 @@
|
||||
"test_prefixes": [],
|
||||
"exact_files": [
|
||||
"frontend-modern/src/__tests__/App.architecture.test.ts",
|
||||
"frontend-modern/src/__tests__/AppLayout.test.tsx"
|
||||
"frontend-modern/src/__tests__/AppLayout.test.tsx",
|
||||
"tests/integration/tests/83-product-trust-accessibility.spec.ts"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -6131,6 +6162,7 @@
|
||||
"frontend-modern/src/components/Workloads/__tests__/DrawerDiskListCard.readings.test.tsx",
|
||||
"frontend-modern/src/components/Workloads/__tests__/HostDrawer.filesystem-readings.test.tsx",
|
||||
"frontend-modern/src/components/Workloads/__tests__/NodeDrawerOverview.updateEvidence.test.tsx",
|
||||
"frontend-modern/src/features/platformPage/__tests__/PlatformWindowedRows.test.tsx",
|
||||
"frontend-modern/src/features/proxmox/__tests__/ProxmoxNodesTable.test.tsx",
|
||||
"frontend-modern/src/utils/__tests__/proxmoxUpdateEvidence.test.ts"
|
||||
]
|
||||
|
||||
@@ -1943,6 +1943,10 @@ recovery scope, or a storage/recovery-owned secret source.
|
||||
when the policy exposes them, and they must not add edition- or
|
||||
license-sniffing of their own to re-suppress or re-expose paid prompts.
|
||||
3. Route canonical storage/recovery resource selection through `frontend-modern/src/hooks/useUnifiedResources.ts` and the owning `unified-resources` contract
|
||||
REST projection retains its validated source list on `resource.sources` as
|
||||
well as platform metadata, so owning-snapshot consumers keep the same
|
||||
provider context as websocket consumers. That provenance describes inventory;
|
||||
it supplies no fresh storage observation, protection verdict or recovery grant.
|
||||
That shared hook now also projects resource `clusterId` through the shared cluster-name helper, so storage and recovery links keep the same cluster-context label as other unified-resource consumers instead of rebuilding a local fallback chain.
|
||||
That shared hook plus the adjacent websocket/store adapter path must keep
|
||||
realtime transport merges canonical for storage/recovery consumers too:
|
||||
|
||||
@@ -23,6 +23,15 @@ and sort the complete canonical change table while startup and ingestion wait.
|
||||
|
||||
## Purpose
|
||||
|
||||
### REST snapshots retain canonical source provenance
|
||||
|
||||
`useUnifiedResources` preserves the validated source list on the canonical
|
||||
resource as well as its platform metadata. Owning-snapshot consumers such as
|
||||
Workloads derive their provider context from `resource.sources`; a REST refresh
|
||||
must not erase vCenter placement, host grouping or source-specific behavior
|
||||
that the websocket projection supplies. The REST mapping regression and the
|
||||
authoritative VMware drawer browser fixture cover that consuming boundary.
|
||||
|
||||
### Drawer history follows current source authority
|
||||
|
||||
Resource drawers withdraw current chart fallbacks and cached live-only replies
|
||||
|
||||
Reference in New Issue
Block a user