VIP version
2026.8.1
Affected area
Workbench tests
What happened?
workbench/test_git_ops.py::test_clone_rstudio failed on the scheduled Workbench smoke run against Workbench 2026.06.0 (the release and 2026.05.1 legs of the same run passed): https://github.com/posit-dev/vip/actions/runs/32216835358/job/95959852227
The clone itself succeeded — the console shows Cloning into 'posit-cli'... and VIP_DONE_<uid>:0. What failed was the follow-up file.exists("/tmp/posit-cli") verification.
rstudio_eval types its marker-wrapped command into the console and presses Enter without checking either step:
console_input.click()
console_input.type(wrapped)
console_input.press("Enter")
On this eval only 142 of the command's 171 characters landed. Reconstructing what _wrap_r_expr would have produced for that run's sentinel uid and diffing it against the console dump:
- landed:
…cat("\n", "<<VIP-END-23106314fa39", "45cbb
- never arrived:
0e569f3d94a800d>>\n", sep="")
- the trailing
") visible in the dump is RStudio's auto-close filling in the still-open " and cat(
The truncated line was also still sitting in the console input when the assertion gave up 30s later, so it was never submitted at all. The end marker therefore never printed and expect(console_output).to_contain_text(end) timed out.
#rstudio_console_input is an Ace editor div rather than an <input> (Locator.fill() and input_value() both raise on it). Per-character typing walks Ace through every intermediate state of the line, which is where its auto-close and path-completion machinery can rewrite or swallow characters, and where a completion popup opened by the quotes in the marker literals can consume the Enter.
Two things make this much harder to diagnose than it should be:
rstudio_eval catches PlaywrightTimeoutError around the marker assertion, but Playwright's expect() raises AssertionError — see AssertionsBase._expect_impl, which constructs AssertionError directly. The handler is dead code, so its intended one-line explanation never reaches the report.
- What reaches the report instead is Playwright's full failure dump: the console panel's text, its call log, and its aria snapshot — roughly 8KB, including a long run of filler characters from Ace's hidden font-measurement node.
What did you expect to happen?
test_clone_rstudio should verify the cloned directory and pass, since the clone succeeded.
Failing that, the failure should say that the command never landed in the console intact and was never submitted, rather than printing the whole console pane and leaving that to be reconstructed by hand.
Steps to reproduce
Not reliably reproducible on demand — this is a race in how RStudio's Ace console consumes synthetic keystrokes, and it hit one of three product legs in the same run.
- Run the Workbench smoke suite against a Workbench deployment:
uv run vip verify --products workbench
workbench/test_git_ops.py::test_clone_rstudio clones a repo through the RStudio terminal, then verifies the result with file_exists() → rstudio_eval()
- When Ace drops part of the typed command, the test fails 30s later with the console dump above
The failure needs no special configuration: any rstudio_eval call can hit it, and the surrounding tests (test_packages, test_data_sources, test_runtime_versions, test_jobs) drive the console the same way.
Relevant logs or output
workbench/test_git_ops.py::test_clone_rstudio[chromium] FAILED [ 46%]
=================================== FAILURES ===================================
_________________________ test_clone_rstudio[chromium] _________________________
test_clone_rstudio[chromium]: Locator expected to contain text '<<VIP-END-23106314fa3945cbb0e569f3d94a800d>>'
Actual value: R 4.4.3·~/ ... R version 4.4.3 (2025-02-28) -- "Trophy Case" ...
> cat("<<VIP-START-a222ec1e048", "64cf1a7368da5577fc4f6>>\n", sep=""); ...
<<VIP-START-a222ec1e04864cf1a7368da5577fc4f6>> Cloning into 'posit-cli'... <<VIP-END-a222ec1e04864cf1a7368da5577fc4f6>>
> cat("<<VIP-START-c9f33a35367", "14148955c738067bb5e23>>\n", sep=""); ...
<<VIP-START-c9f33a3536714148955c738067bb5e23>> Cloning into 'posit-cli'... VIP_DONE_55ca2d3133174365a9acee2c6c92228d:0 <<VIP-END-c9f33a3536714148955c738067bb5e23>>
> cat("<<VIP-START-23106314fa3", "945cbb0e569f3d94a800d>>\n", sep=""); file.exists("/tmp/posit-cli"); cat("\n", "<<VIP-END-23106314fa39", "45cbb")
Call log:
- Expect "to_contain_text" with timeout 30000ms
- waiting for locator("#rstudio_workbench_panel_console")
- 63 × locator resolved to <div role="tabpanel" aria-label="Console" ...>
Aria snapshot:
- textbox "Cursor at row 1": cat("<<VIP-START-23106314fa3", "945cbb0e569f3d94a800d>>\n", sep=""); file.exists("/tmp/posit-cli"); cat("\n", "<<VIP-END-23106314fa39", "45cbb
====== 1 failed, 19 passed, 10 skipped, 5 deselected in 705.13s (0:11:45) ======
Note the last line of the aria snapshot: the command is in the textbox, not in the console output — it was never submitted.
Environment
- Runner:
ubuntu-24.04, Python 3.12.3
- pytest 9.1.1, pytest-playwright 0.8.0, posit-vip 2026.8.1
- Workbench under test: 2026.06.0 (failed);
release and 2026.05.1 in the same run passed
- Browser: chromium
VIP version
2026.8.1
Affected area
Workbench tests
What happened?
workbench/test_git_ops.py::test_clone_rstudiofailed on the scheduled Workbench smoke run against Workbench 2026.06.0 (thereleaseand2026.05.1legs of the same run passed): https://github.com/posit-dev/vip/actions/runs/32216835358/job/95959852227The clone itself succeeded — the console shows
Cloning into 'posit-cli'...andVIP_DONE_<uid>:0. What failed was the follow-upfile.exists("/tmp/posit-cli")verification.rstudio_evaltypes its marker-wrapped command into the console and presses Enter without checking either step:On this eval only 142 of the command's 171 characters landed. Reconstructing what
_wrap_r_exprwould have produced for that run's sentinel uid and diffing it against the console dump:…cat("\n", "<<VIP-END-23106314fa39", "45cbb0e569f3d94a800d>>\n", sep="")")visible in the dump is RStudio's auto-close filling in the still-open"andcat(The truncated line was also still sitting in the console input when the assertion gave up 30s later, so it was never submitted at all. The end marker therefore never printed and
expect(console_output).to_contain_text(end)timed out.#rstudio_console_inputis an Ace editor div rather than an<input>(Locator.fill()andinput_value()both raise on it). Per-character typing walks Ace through every intermediate state of the line, which is where its auto-close and path-completion machinery can rewrite or swallow characters, and where a completion popup opened by the quotes in the marker literals can consume the Enter.Two things make this much harder to diagnose than it should be:
rstudio_evalcatchesPlaywrightTimeoutErroraround the marker assertion, but Playwright'sexpect()raisesAssertionError— seeAssertionsBase._expect_impl, which constructsAssertionErrordirectly. The handler is dead code, so its intended one-line explanation never reaches the report.What did you expect to happen?
test_clone_rstudioshould verify the cloned directory and pass, since the clone succeeded.Failing that, the failure should say that the command never landed in the console intact and was never submitted, rather than printing the whole console pane and leaving that to be reconstructed by hand.
Steps to reproduce
Not reliably reproducible on demand — this is a race in how RStudio's Ace console consumes synthetic keystrokes, and it hit one of three product legs in the same run.
uv run vip verify --products workbenchworkbench/test_git_ops.py::test_clone_rstudioclones a repo through the RStudio terminal, then verifies the result withfile_exists()→rstudio_eval()The failure needs no special configuration: any
rstudio_evalcall can hit it, and the surrounding tests (test_packages,test_data_sources,test_runtime_versions,test_jobs) drive the console the same way.Relevant logs or output
Note the last line of the aria snapshot: the command is in the
textbox, not in the console output — it was never submitted.Environment
ubuntu-24.04, Python 3.12.3releaseand 2026.05.1 in the same run passed