Repository navigation
test(e2e-cucumber): cover #500's whitespace-path approval-preview quoting - #707
jussielo-amd merged 4 commits into
Conversation
tomastola
left a comment
There was a problem hiding this comment.
Requesting changes for one blocking issue: the new dash-35 scenario fails in CI (inline comment on approval_preview_quotes_whitespace_root).
Non-blocking, for you to confirm: accepting either " or ' quoting keeps the test from pinning today's quote character, but it also means a regression that switches quote styles would pass silently. The reasoning in the comment is sound and I would keep it.
Nice touches: the scenario uses the whitespace directory as the spawn_in cwd itself, which reaches the --root argument dash-25 never touches, and the wait for the approval title to clear between the two Esc presses avoids the coalescing race.
| .unwrap_or_else(|e| panic!("the existing-folder browser did not appear: {e}")); | ||
| } | ||
|
|
||
| #[then("the approval preview quotes the whitespace-containing root path")] |
There was a problem hiding this comment.
Blocking: this step times out in CI because the matcher expects a layout the real popup doesn't produce.
E2E tests (Strix Halo, Ubuntu, nightly, current) fails on dash-35 here with timed out after 90s: https://github.com/ROCm/rocm-cli/actions/runs/38902403040/job/116977856347
The step requires --root "<root>" on a single terminal row. The runner's temp path (/mnt/scratch/actions-runner-01/_work/_temp/rocm-e2e-Qce2gv/a b) is about 70 characters, and the popup wraps at word boundaries. The captured screen shows rocm runtimes adopt --root on one row and the quoted path on the next. The product output is correct (the path is quoted on screen); only the matcher is wrong. This also contradicts the "margin to spare" claim in the ADOPT_WHITESPACE_ROOT doc comment, and it makes the result depend on the host's temp-path length. That is probably why WSL2 passed.
Two ways to fix it:
- Match on the popup's own text: slice each screen row between the popup's border columns and join those slices, or match the quoted path
"<root>"without the--rootprefix. - Make the scenario root short and deterministic instead of relying on the ambient
TMPDIR.
Either way, please correct the "margin to spare" comment.
There was a problem hiding this comment.
Fixed — and thanks for the precise diagnosis, that's exactly what was happening.
Dropping the --root prefix (matching the quoted value alone) fixed the CI failure you hit, but re-checking it turned up that it only narrows the flake window rather than closing it: a slightly longer runner path, or one long enough to force a hard mid-word split (ratatui breaks an unbroken token like a bare path with no embedded whitespace, consuming no space at the break), would still time out the same way.
So I went with your first suggestion instead: the step now reconstructs the popup's own body text by finding its content columns from the title row's own border characters, slicing every body row to that span, and rejoining — telling a true word-boundary wrap (which leaves trailing blank padding behind it) apart from a hard mid-word split (which doesn't), so only the former gets a join space back. That holds regardless of host path length rather than depending on one; verified it against the original CI path length plus a much longer one that forces several hard splits across multiple rows.
Also corrected the ADOPT_WHITESPACE_ROOT doc comment's "margin to spare" claim, which stopped being true the moment the matcher depended on anything about path length at all.
… quoting dash-25 proved spawn_in threads a scenario-owned folder into the real onboarding Adopt-folder browser, but its whitespace case lived in a child entry under that folder, not in the spawn_in cwd itself, so it never drove quote_display_arg's quoting fix through the real approval-preview render a user actually sees. Add dash-35: the scenario's own spawn_in cwd has a space in its own name, so choosing "[ use this folder ]" stages an approval whose --root argument is that same whitespace path, and the new assertion checks it renders quoted. Fixes ROCm#693 Signed-off-by: Jussi Elo <jussi.elo@amd.com>
5c0778e to
6a7862f
Compare
The approval popup word-wraps its command line once it outgrows the popup's own width, which a CI runner's long _work/_temp prefix reliably triggers but a short local path doesn't. Matching a fixed-prefix substring against the raw screen grid timed out whenever that happened, even though the product rendered the quoted path correctly. Reconstruct the popup's own body text instead: find its content columns from the title row's own border characters, slice every body row to that span (discarding sibling panels drawn on the same physical rows), and rejoin — distinguishing a true word-boundary wrap (which leaves trailing blank padding) from a hard mid-word split on an unbroken token like a host path (which doesn't), so only the former gets a join space back. This holds regardless of host path length, rather than narrowing the window a fixed-prefix match depended on. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
Two follow-ups from reviewing the previous commit's fix: - The left-edge border walk could in principle walk straight through into an outer box's own border if one were ever flush against this popup with no gap, silently returning the wrong column instead of failing. The left edge turns out to have an exact invariant instead of needing a walk at all: stamp_title always stamps its left bracket 3 columns before the title text, regardless of title length, so that offset is checked directly rather than discovered by walking. The right edge has no equivalent fixed offset (it depends on the box's own width), so it keeps the walk, documented as the weaker of the two checks. - wait_for_popup_body_where discarded every popup_body_text error while polling, including a genuine structural mismatch, so a real bug there would just read as an unexplained timeout. It now carries the last such error into the timeout message. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
const BORDER placed after other statements tripped items_after_statements; threading the last popup_body_text error through a loop variable that was always overwritten before being read tripped unused_assignments. Move the const to the top of the function, and re-derive the diagnostic once at the timeout instead of carrying it across iterations. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
|
On the quote-style question: still accepting either |
tomastola
left a comment
There was a problem hiding this comment.
Re-review of #707: changes since my 2026-10-16 review (head a6f55cc4)
Verdict: approve. The one blocking issue is fixed, and the fix is the more thorough option I suggested.
What changed
Since 5c0778e8 the branch has been rebased onto current main. Main had meanwhile added its own dash-35, the compact GPU VRAM scenario. This PR renumbers its own scenario to dash-36 and updates every reference to it in comments, so the IDs no longer clash. The GPU scenario and the model-serving comment changes come from main, not from this PR.
The PR's own changes are these:
-
The matcher reads the popup's own text now.
approval_preview_quotes_whitespace_rootno longer searches the whole screen for--root "<root>". It calls the newTuiSession::wait_for_popup_body_where, which rebuilds the popup's text usingpopup_body_text(ADOPT_APPROVAL_TITLE). It then matches only the quoted value ("<root>"or'<root>'), without the--rootprefix. -
popup_body_textworks out the popup's columns from its title row:- Left edge: a fixed 3-column offset. I checked this against
panel::stamp_title(lb = area.x + 2, which renders╭─╮<title>╭), and it fails loudly if the notch isn't there. - Right edge: a walk through the border characters to the closing
╮.
It then slices each row between the title and
Approve (to those columns and joins the pieces back into one string. A row with blank cells left at its end is treated as a word-boundary wrap and gets a space when joined; a full row is treated as a word split mid-way and gets none. - Left edge: a fixed 3-column offset. I checked this against
-
The
ADOPT_WHITESPACE_ROOTdoc comment no longer claims "margin to spare". It now says plainly that the line wraps on long temp paths and points to the rebuilt text instead.
Against what I raised before
- Blocking: dash-35 timed out in CI. Resolved.
E2E tests (Strix Halo, Ubuntu, nightly, current)now passes, and on the same runner that failed before (/mnt/scratch/actions-runner-01/_work/_temp/rocm-e2e-…). The job log shows dash-36 ran and passedThen the approval preview quotes the whitespace-containing root path; it was not skipped. All other checks are green, including clippy, after the pedantic-lint commit. - Correct the "margin to spare" comment. Done.
- Non-blocking: accepting either quote style. Settled. You're keeping it and explain why in a PR comment. I said last time I'd keep it too.
- Geometry checks I made:
draw_popup_frameusespanel::popup, which has no padding (Padding::ZERO, 1-cell inset). So the sliceleft+1..rightcovers exactly the popup's inner area, and no padding column can look like trailing blank space.- The button row sits directly below the body because
Constraint::Length(2)puts the one-line Paragraph at its top. So stopping atApprove (ends the body at the right place. - On the matcher's argument that
"<root>"can't also match--python's quoted"<root>/bin/python": it holds.
Non-blocking notes
- Non-blocking — one case can still fail, but it's avoidable. If a word wrap lands exactly on the last column, ratatui drops the space and leaves no blank cell, so the code reads it as a mid-word split. The docstring admits this case. Here it can only hit the one space inside
a b. If it happens, the result isab"and the step times out.- The temp-dir suffix is a fixed 6 characters, so each runner's path length is fixed. If a runner hits this, it will fail every time, not intermittently.
- Simpler and fully wrap-proof: remove all whitespace from both the body and the expected string before comparing. Quoting is what this step checks, not the space itself. An unquoted render would still fail because the
"/'would be missing. That would make the trailing-blank logic and its long explanation unnecessary.
- Non-blocking —
popup_body_textslices by character index, not by screen column. The fixed-offset check only covers the title row. A double-width character to the left of the popup on a body row would shift that row's slice by one. Nothing renders one there today, so this is low priority. - Non-blocking — the comments repeat review history. Phrases like "(PR #707 review, 2026-10-16, and a follow-up review of that fix on the same date)" don't belong in the code. The reasoning that follows them is enough without the dates.
None of these block the merge.
Summary
PR #501 added
TuiSession::spawn_in, givingdashscenarios a controllable working directory for the real crossterm event loop. PR #638 landeddash-25, provingspawn_inthreads a scenario-owned folder into onboarding's Adopt-existing-folder browser end to end — butdash-25's whitespace case lives in a child entry (adopt me) under that folder, not in thespawn_incwd itself, so it never drives PR #500'squote_display_argquoting fix through the real approval-preview render a user actually sees.This adds
dash-35(next free index after thedash-26..dash-34quit-confirm scenarios that landed in #595 while this branch was in progress): the scenario's ownspawn_incwd has a space in its own name, so onboarding's Adopt flow (which seeds its folder browser fromstd::env::current_dir()) resolves its start path to that whitespace-containing directory directly. Choosing[ use this folder ]stages an approval whose--rootargument is that same path, and the new assertion checks the rendered preview shows it quoted.PR #500 already has widget-level
TestBackendsnapshot coverage of the quoting in isolation (approval_snapshot_quotes_args_containing_spacesincrates/rocm-dash-tui/tests/wave0_job_bridge.rs); this closes the black-box coverage gap the issue asks for.This is additive test coverage only — no production code changes.
CI lane: runs in the default E2E lane (
@requires-os:linux, same tagging as every other scenario indash.feature; no GPU or special lane needed).How I proved the assertion is load-bearing
The fix (
quote_display_argincrates/rocm-dash-tui/src/ui/exec.rs) is already merged, so I verified the new scenario is a genuine regression test by temporarily hand-editingquote_display_argto a no-op (returning the value unchanged), rebuildingrocm, and re-running the scenario:Thenstep, and the captured screen shows the unquoted, ambiguous preview (--root /tmp/.../a b --python ...).Test plan
cargo xtask e2e -- -n "dash-35"— 13/13 steps passcargo xtask e2e -- -n "dash-(23|25|2[6-9]|3[0-5])"— 12 scenarios / 147 steps pass (onboarding siblingsdash-23/dash-25plus the newly-landeddash-26..dash-34quit-confirm scenarios, confirming no regression from the rebase/renumber)cargo test -p e2e-cucumber --test feature_naming— all 4 naming-invariant tests pass (sequential numbering, unique indexes)cargo clippy -p e2e-cucumber --all-targets -- -D warnings— cleancargo fmt --check -p e2e-cucumber— cleancargo test --workspace --all-targets— full suite greenorigin/main— cleanFixes #693