Repository navigation
Read resource row state at every density in dashboard browser tests - #21924
Conversation
#21880 restored single-line compact rows, the dashboard's default density. Compact rows show the state as a dot with its name in the tooltip, so the template and Hosting.Testing browser tests that read the state text after the dot timed out. Read the state from the compact state column's tooltip or the text after the dot, and cover the shared helper at both densities. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 21924Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 21924" |
Tests selector3 / 101 PR test projects · 1 PR job, from 3 changed files. Selected PR test projects (3 / 101)
Selected PR jobs (1)
How these were chosen — grouped by what changed🧪 🧪 Job reasons
Selection computed for commit |
There was a problem hiding this comment.
🔵 Needs a closer look
The targeted Templates and Hosting.Testing outerloop tests in run 42450827141 have not yet executed, leaving browser/container scenarios unverified in this source-only review environment.
No open issues 🎉
What changed in this PR
Updates dashboard browser-test helpers to support the compact resource rows restored by #21880, without changing production dashboard behavior or dropping state assertions.
Changes:
- Reads resource state from compact-row tooltips or visible text at other densities, retrying when state has not rendered.
- Uses density-aware state locators in the AppHost breakpoint test.
- Extends helper regression coverage to default Compact and Comfortable densities on both resource and graph pages.
| File | Description |
|---|---|
| tests/Shared/Playwright/DashboardResourceAssertions.cs | Adds density-aware state reading and matching to shared resource assertions. |
| tests/Aspire.Hosting.Testing.Tests/DashboardUrlTests.cs | Uses the shared locator to verify initial and updated resource states. |
| tests/Aspire.Dashboard.Playwright.Tests/Integration/Playwright/TemplateResourceAssertionsTests.cs | Tests both densities and directly checks state-locator matching. |
Review effort: Balanced
|
✅ No documentation update needed. docs_optional → test_only. No signals triggered (signal_count 0). All 3 changed files match |
…21924) ## Description The scheduled [Outerloop Tests run on main](https://github.com/microsoft/aspire/actions/runs/42437120205) failed in two jobs after #21880: - [Templates (ubuntu-latest)](https://github.com/microsoft/aspire/actions/runs/42437120205/job/128616874013): all 10 `StarterTemplateWithRedisCacheTests` and `StarterTemplateWithRedisCacheTests_Net11` tests timed out waiting for `.resource-row-sub > .state-dot + span` in `DashboardResourceAssertions.CheckResourcesAsync`. - [Hosting.Testing (ubuntu-latest)](https://github.com/microsoft/aspire/actions/runs/42437120205/job/128616874062): `DashboardUrlTests.DashboardDisplaysResourceUpdatesWhileAppHostIsPausedAtBreakpoint` couldn't find the text "Dashboard test initial" in the resource row. The row itself was there. ## Failure stats (14d, attempt 1) `Outerloop Tests` workflow on microsoft/aspire, runs created 2026-10-25 06:28 → 2026-11-08 06:28 UTC, **attempt 1 only**. Denominator: attempt-1 jobs that ran (success or failure). Hits: the failed job's log matches the signature. Jobs that lost their runner, which have no log, are excluded. | | | |---|---| | Signature | Templates: `.resource-row-sub > .state-dot + span` timeout; Hosting.Testing: `Dashboard test initial` not found | | Job | Outerloop Tests: Templates (ubuntu-latest) and Hosting.Testing (ubuntu-latest), main | | main pushes: hits / runs | 2 / 28 (7.14%) | | main scheduled runs, 30d: hits / jobs | 2 / 60 (3.33%), both on 2026-11-08. Templates also failed on main every scheduled run from 2026-10-10 to 2026-11-04 with other causes | | PR runs: hits / runs | n/a (Outerloop PR runs don't run these jobs) | | Combined rate | 2 / 28 = **7.14%** | | Flake check | main: failed on all 4 attempts of the run (not a flake) | | First / last hit | 2026-11-08 / 2026-11-08 | | Still hitting main? | Hit on the latest scheduled main run (2026-11-08); no main run since | | Fix evidence | Local: default-density helper tests fail with the old helper and pass with the new one. Outerloop dispatched on this PR's head: Templates and Hosting.Testing (ubuntu) passed 2/2 attempts. | Failing attempt-1 jobs, most recent first (2 of 2 log-verified hits): | Date (UTC) | Branch | Job | Signature excerpt | |---|---|---|---| | [2026-11-08 02:06](https://github.com/microsoft/aspire/actions/runs/42437120205/job/128604467928) | **main** | Hosting.Testing (ubuntu-latest) | `GetByText("Dashboard test initial", Exact) element(s) not found` | | [2026-11-08 02:06](https://github.com/microsoft/aspire/actions/runs/42437120205/job/128604468061) | **main** | Templates (ubuntu-latest) | `.resource-row-sub > .state-dot + span timeout` | **Verdict: STRONG (real break, not a flake).** The 2026-11-08 scheduled main run failed both jobs on **all 4 attempts** with these signatures. The prior scheduled runs (2026-11-06 and 2026-11-07) passed, and the signature never appeared earlier in the window. Earlier Templates failures (2026-10-27 to 2026-11-04) had other causes. <!-- /failure-stats --> **Why:** #21880 deliberately brought back single-line rows for **Compact**, the dashboard's default density. A compact row shows the state as a dot in a `.resource-row-meta-state` column, and the state's name is in that column's `data-tooltip`. There's no `.resource-row-sub` and no visible state text. These browser tests open the dashboard at its default density, so they no longer found the state. `Aspire.Dashboard.Playwright.Tests` passed because `PlaywrightTestsBase` pins those tests to Comfortable unless they opt into the default. This is a deterministic break, not a flake: the previous scheduled runs on main ([42327544779](https://github.com/microsoft/aspire/actions/runs/42327544779), before #21880) passed, and the only dashboard change in between is #21880. **Fix:** the tests now match the intended markup, and no assertions are dropped: - `DashboardResourceAssertions.GetRowStateAsync` reads a row's state at any density. In compact rows it reads the state column's tooltip. In other densities it reads the text after the dot. `RowState(row, state)` finds the element that shows a given state. - `CheckResourcesAsync` uses `GetRowStateAsync`, and keeps waiting while a row hasn't rendered a state yet. - `DashboardDisplaysResourceUpdatesWhileAppHostIsPausedAtBreakpoint` waits for the initial and then the updated state with `RowState`. - `TemplateResourceAssertionsTests.TemplateHelper_ValidatesSidebarAndDetailsWithoutCards` now runs at both the default (compact) density and Comfortable, and checks `RowState` directly, so the helper is covered against the real dashboard at the density the template tests use. ## Confidence - Locally, the 6 `TemplateResourceAssertionsTests` pass. With the old helper, the two new default-density cases fail with the same `Timeout ... exceeded` as the Templates job. - [Outerloop Tests dispatched on this branch](https://github.com/microsoft/aspire/actions/runs/42450827141) to cover the Templates and Hosting.Testing jobs end to end. I didn't run those two locally; they need the full template build and container runtime. **How we stop this recurring:** the shared helper's own test now runs at the dashboard's default density, so a markup change to default rows fails that test against the dashboard alone, which is fast to run locally while changing row markup and points straight at the helper. It's still an outerloop test, so it doesn't gate PR CI. ## Checklist - Is this feature complete? - [x] Yes. Ready to ship. - [ ] No. Follow-up changes expected. - Are you including unit tests for the changes and scenario tests if relevant? - [x] Yes - [ ] No - Did you add public API? - [ ] Yes - [x] No - Does the change make any security assumptions or guarantees? - [ ] Yes - [x] No **🤖 Posted by AspireAgent (AI Agent)** Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> (cherry picked from commit 01d9682)
…21924) ## Description The scheduled [Outerloop Tests run on main](https://github.com/microsoft/aspire/actions/runs/42437120205) failed in two jobs after #21880: - [Templates (ubuntu-latest)](https://github.com/microsoft/aspire/actions/runs/42437120205/job/128616874013): all 10 `StarterTemplateWithRedisCacheTests` and `StarterTemplateWithRedisCacheTests_Net11` tests timed out waiting for `.resource-row-sub > .state-dot + span` in `DashboardResourceAssertions.CheckResourcesAsync`. - [Hosting.Testing (ubuntu-latest)](https://github.com/microsoft/aspire/actions/runs/42437120205/job/128616874062): `DashboardUrlTests.DashboardDisplaysResourceUpdatesWhileAppHostIsPausedAtBreakpoint` couldn't find the text "Dashboard test initial" in the resource row. The row itself was there. ## Failure stats (14d, attempt 1) `Outerloop Tests` workflow on microsoft/aspire, runs created 2026-10-25 06:28 → 2026-11-08 06:28 UTC, **attempt 1 only**. Denominator: attempt-1 jobs that ran (success or failure). Hits: the failed job's log matches the signature. Jobs that lost their runner, which have no log, are excluded. | | | |---|---| | Signature | Templates: `.resource-row-sub > .state-dot + span` timeout; Hosting.Testing: `Dashboard test initial` not found | | Job | Outerloop Tests: Templates (ubuntu-latest) and Hosting.Testing (ubuntu-latest), main | | main pushes: hits / runs | 2 / 28 (7.14%) | | main scheduled runs, 30d: hits / jobs | 2 / 60 (3.33%), both on 2026-11-08. Templates also failed on main every scheduled run from 2026-10-10 to 2026-11-04 with other causes | | PR runs: hits / runs | n/a (Outerloop PR runs don't run these jobs) | | Combined rate | 2 / 28 = **7.14%** | | Flake check | main: failed on all 4 attempts of the run (not a flake) | | First / last hit | 2026-11-08 / 2026-11-08 | | Still hitting main? | Hit on the latest scheduled main run (2026-11-08); no main run since | | Fix evidence | Local: default-density helper tests fail with the old helper and pass with the new one. Outerloop dispatched on this PR's head: Templates and Hosting.Testing (ubuntu) passed 2/2 attempts. | Failing attempt-1 jobs, most recent first (2 of 2 log-verified hits): | Date (UTC) | Branch | Job | Signature excerpt | |---|---|---|---| | [2026-11-08 02:06](https://github.com/microsoft/aspire/actions/runs/42437120205/job/128604467928) | **main** | Hosting.Testing (ubuntu-latest) | `GetByText("Dashboard test initial", Exact) element(s) not found` | | [2026-11-08 02:06](https://github.com/microsoft/aspire/actions/runs/42437120205/job/128604468061) | **main** | Templates (ubuntu-latest) | `.resource-row-sub > .state-dot + span timeout` | **Verdict: STRONG (real break, not a flake).** The 2026-11-08 scheduled main run failed both jobs on **all 4 attempts** with these signatures. The prior scheduled runs (2026-11-06 and 2026-11-07) passed, and the signature never appeared earlier in the window. Earlier Templates failures (2026-10-27 to 2026-11-04) had other causes. <!-- /failure-stats --> **Why:** #21880 deliberately brought back single-line rows for **Compact**, the dashboard's default density. A compact row shows the state as a dot in a `.resource-row-meta-state` column, and the state's name is in that column's `data-tooltip`. There's no `.resource-row-sub` and no visible state text. These browser tests open the dashboard at its default density, so they no longer found the state. `Aspire.Dashboard.Playwright.Tests` passed because `PlaywrightTestsBase` pins those tests to Comfortable unless they opt into the default. This is a deterministic break, not a flake: the previous scheduled runs on main ([42327544779](https://github.com/microsoft/aspire/actions/runs/42327544779), before #21880) passed, and the only dashboard change in between is #21880. **Fix:** the tests now match the intended markup, and no assertions are dropped: - `DashboardResourceAssertions.GetRowStateAsync` reads a row's state at any density. In compact rows it reads the state column's tooltip. In other densities it reads the text after the dot. `RowState(row, state)` finds the element that shows a given state. - `CheckResourcesAsync` uses `GetRowStateAsync`, and keeps waiting while a row hasn't rendered a state yet. - `DashboardDisplaysResourceUpdatesWhileAppHostIsPausedAtBreakpoint` waits for the initial and then the updated state with `RowState`. - `TemplateResourceAssertionsTests.TemplateHelper_ValidatesSidebarAndDetailsWithoutCards` now runs at both the default (compact) density and Comfortable, and checks `RowState` directly, so the helper is covered against the real dashboard at the density the template tests use. ## Confidence - Locally, the 6 `TemplateResourceAssertionsTests` pass. With the old helper, the two new default-density cases fail with the same `Timeout ... exceeded` as the Templates job. - [Outerloop Tests dispatched on this branch](https://github.com/microsoft/aspire/actions/runs/42450827141) to cover the Templates and Hosting.Testing jobs end to end. I didn't run those two locally; they need the full template build and container runtime. **How we stop this recurring:** the shared helper's own test now runs at the dashboard's default density, so a markup change to default rows fails that test against the dashboard alone, which is fast to run locally while changing row markup and points straight at the helper. It's still an outerloop test, so it doesn't gate PR CI. ## Checklist - Is this feature complete? - [x] Yes. Ready to ship. - [ ] No. Follow-up changes expected. - Are you including unit tests for the changes and scenario tests if relevant? - [x] Yes - [ ] No - Did you add public API? - [ ] Yes - [x] No - Does the change make any security assumptions or guarantees? - [ ] Yes - [x] No **🤖 Posted by AspireAgent (AI Agent)** Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> (cherry picked from commit 01d9682)
…s, trace log previews, test flakes (#22232) The remaining dashboard work for `release/17.0`, as one squashable PR: one commit per change, in this order. **Backported from `main` (cherry-picked with `-x`):** 1. #21500: Fix flaky terminal WebSocket close handshake abort (test only) 2. #21503: Fix bUnit JS timeout flakes in StructuredLogs/Traces/TraceDetails tests (test only) 3. #21471: Fix flaky TerminalWebSocketTests final-output drain (test only) 4. #21924: Read resource row state at every density in dashboard browser tests (test only) 5. #22142: Fix inconsistent dashboard action icon colors. It conflicted with #22188 in `ResourcesLayout.razor`: the resolution keeps the row menu on every row, parameters included, with #22142's icon color. **From open PRs against `main`, applied as they stand:** 6. #22228: Fix resource sidebar hover state after selection 7. #22229: Keep resource picker popup width consistent **New:** 8. Render the trace log preview only for the marker that's hovered or focused. Each log marker rendered its own hidden preview for the tooltip, so a span with many logs built over a million hidden elements. The page now renders one preview, filled on hover or focus. This addresses Copilot's review on #22230. 9. Center tag group chevrons over the state dot column. In the compact sidebar at rest, the rows' state dots form a column at the end of the list, and the group header's chevron sat 13px past it. This replaces #21996. 10. Fix two resource pane Playwright tests: - `Rows_KeepDensity` expected parameter rows in the expanded list to have no overflow menu, but every row has one now. - `FilterAndGrouping` could hover before the feedback prompt pushed the page down 40px, leaving the pointer on the brand. It now waits for the prompt. When `release/17.0` merges back into `main`, the `Rows_KeepDensity` change has to come along with it, because #22228's version of that test expects no menu on parameter rows. Once this is in `release/17.0`, `release/17.0` merges back into `main`. #22228 and #22229 can then close on `main`. ## Customer Impact Fixes and polish to the 17.0 dashboard: icon colors, the resource sidebar and picker, and trace pages with many logs. ## Testing - `Aspire.Dashboard.Components.Tests`: 1,447 passed, 0 failed. - `ResourcePaneResponsiveTests.FilterAndGrouping_*` and `Rows_KeepDensity*`: 11 passed. `FilterAndGrouping` passed 5 runs in a row after the fix; before it, the 2000px cases failed in about half the runs. - The chevron alignment was checked in the browser at 1440px: the chevron and the dots are both centered 25px from the list's end. ## Risk Low. Dashboard-only, and the backports are unchanged apart from the one conflict described above. ## Regression? No. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: David Fowler <davidfowl@gmail.com> Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Maddy Montaquila <maddy@MadBook-Pro-20.local> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: James Newton-King <james@newtonking.com> Co-authored-by: Sébastien Ros <1165805+sebastienros@users.noreply.github.com>
Description
The scheduled Outerloop Tests run on main failed in two jobs after #21880:
StarterTemplateWithRedisCacheTestsandStarterTemplateWithRedisCacheTests_Net11tests timed out waiting for.resource-row-sub > .state-dot + spaninDashboardResourceAssertions.CheckResourcesAsync.DashboardUrlTests.DashboardDisplaysResourceUpdatesWhileAppHostIsPausedAtBreakpointcouldn't find the text "Dashboard test initial" in the resource row. The row itself was there.Failure stats (14d, attempt 1)
Outerloop Testsworkflow on microsoft/aspire, runs created 2026-10-25 06:28 → 2026-11-08 06:28 UTC, attempt 1 only. Denominator: attempt-1 jobs that ran (success or failure). Hits: the failed job's log matches the signature. Jobs that lost their runner, which have no log, are excluded..resource-row-sub > .state-dot + spantimeout; Hosting.Testing:Dashboard test initialnot foundFailing attempt-1 jobs, most recent first (2 of 2 log-verified hits):
GetByText("Dashboard test initial", Exact) element(s) not found.resource-row-sub > .state-dot + span timeoutVerdict: STRONG (real break, not a flake). The 2026-11-08 scheduled main run failed both jobs on all 4 attempts with these signatures. The prior scheduled runs (2026-11-06 and 2026-11-07) passed, and the signature never appeared earlier in the window. Earlier Templates failures (2026-10-27 to 2026-11-04) had other causes.
Why: #21880 deliberately brought back single-line rows for Compact, the dashboard's default density. A compact row shows the state as a dot in a
.resource-row-meta-statecolumn, and the state's name is in that column'sdata-tooltip. There's no.resource-row-suband no visible state text. These browser tests open the dashboard at its default density, so they no longer found the state.Aspire.Dashboard.Playwright.Testspassed becausePlaywrightTestsBasepins those tests to Comfortable unless they opt into the default. This is a deterministic break, not a flake: the previous scheduled runs on main (42327544779, before #21880) passed, and the only dashboard change in between is #21880.Fix: the tests now match the intended markup, and no assertions are dropped:
DashboardResourceAssertions.GetRowStateAsyncreads a row's state at any density. In compact rows it reads the state column's tooltip. In other densities it reads the text after the dot.RowState(row, state)finds the element that shows a given state.CheckResourcesAsyncusesGetRowStateAsync, and keeps waiting while a row hasn't rendered a state yet.DashboardDisplaysResourceUpdatesWhileAppHostIsPausedAtBreakpointwaits for the initial and then the updated state withRowState.TemplateResourceAssertionsTests.TemplateHelper_ValidatesSidebarAndDetailsWithoutCardsnow runs at both the default (compact) density and Comfortable, and checksRowStatedirectly, so the helper is covered against the real dashboard at the density the template tests use.Confidence
TemplateResourceAssertionsTestspass. With the old helper, the two new default-density cases fail with the sameTimeout ... exceededas the Templates job.How we stop this recurring: the shared helper's own test now runs at the dashboard's default density, so a markup change to default rows fails that test against the dashboard alone, which is fast to run locally while changing row markup and points straight at the helper. It's still an outerloop test, so it doesn't gate PR CI.
Checklist
🤖 Posted by AspireAgent (AI Agent)