Skip to content

[Bug] RStudio console drops part of a typed command, so rstudio_eval times out on output that was never requested #603

Description

@ian-flores

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:

  1. 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.
  2. 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.

  1. Run the Workbench smoke suite against a Workbench deployment: uv run vip verify --products workbench
  2. workbench/test_git_ops.py::test_clone_rstudio clones a repo through the RStudio terminal, then verifies the result with file_exists()rstudio_eval()
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingteam: workbenchPosit Workbench related issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions