test(cua-driver): desktop-scope modality harness test + test-suite docs#2038
Conversation
…modality (#1968) Adds harness_desktop_scope_test.rs covering the Phase-1 desktop-scope (foreground, vision-only, screen-absolute) modality that the existing background-modality tests don't exercise: - set_config capture_scope=desktop → get_desktop_state returns a full-display capture with real screen_width/height - window-less screen-absolute click + scroll land via WindowFromPoint - negative gate: window-less click under capture_scope=window is rejected (desktop_scope_disabled) Drives a single long-lived MCP server (capture_scope is a session override that persists per-connection, not across stateless 'cua-driver call' processes). #[ignore] (needs a real desktop session), same conventions as e2e_windows_bg_input_test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KMXCW4M5uK1HRGjjH4wueZ
Two visual docs for the cua-driver test layer: - TEST_HARNESS_STRUCTURE.md — harness apps topology (scenarios.json single-source-of-truth, apps/build/tests wiring, coverage matrix). - TEST_SUITE.md — the Rust integration-test suite: inventory of all ~135 test fns, the test→MCP-server→app loop, and modality coverage (background well-covered; foreground/desktop-scope now covered by the new harness_desktop_scope_test). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
📝 WalkthroughWalkthroughAdds a Windows-only integration test for ChangesWindows desktop-scope validation
Sequence Diagram(s)sequenceDiagram
participant Fixture
participant cua_driver_exe as cua-driver.exe
participant WPF_harness as WPF harness
Fixture->>cua_driver_exe: initialize over stdio
Fixture->>cua_driver_exe: set_config capture_scope
Fixture->>WPF_harness: launch harness and find CuaTestHarness
Fixture->>cua_driver_exe: click / scroll with x,y only
Fixture->>cua_driver_exe: get_desktop_state
Fixture->>cua_driver_exe: click with x,y only under capture_scope=window
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@libs/cua-driver/rust/crates/cua-driver/tests/harness_desktop_scope_test.rs`:
- Around line 223-227: The desktop-scope test only checks that get_desktop_state
returns nonzero screen dimensions, but it does not verify the screenshot is in
true screen pixels. Update the assertions in harness_desktop_scope_test around
get_desktop_state to also read screenshot_width and screenshot_height from the
structured response and compare them against screen_width and screen_height.
Keep the existing checks, and add explicit equality assertions for the
screenshot dimensions to enforce the desktop-scope contract.
- Around line 176-195: The harness window selection in the desktop scope test is
matching only by title, which can pick an already-open CuaTestHarness instead of
the newly launched WPF process. Capture the spawned child PID from app.id() in
the spawn_in_job block before pushing it into fx._bag, then update the
list_windows scan in the same test to require w["pid"] to equal that PID before
calling assign_pid_to_job and returning the window center.
- Around line 257-264: Update window_scope_rejects_windowless_click to assert
the exact desktop_scope_disabled rejection from call/result_text instead of
accepting any is_error() outcome; keep the existing setup via spawn_driver,
set_scope, and call, but make the assertion verify the structured error
code/message for the click action rather than unrelated transport or startup
failures.
In `@libs/cua-driver/test-harness/TEST_HARNESS_STRUCTURE.md`:
- Line 7: The fenced code block in TEST_HARNESS_STRUCTURE.md is missing a
language declaration, which triggers markdownlint MD040. Update the opening
fence in this markdown snippet to specify an appropriate language such as text,
and keep the rest of the block unchanged.
- Around line 38-45: Add harness_desktop_scope_test.rs to the consumer tree in
TEST_HARNESS_STRUCTURE.md and update the WPF coverage row so the new
desktop-scope integration test is listed alongside the existing
harness_*_test.rs consumers. Keep the structure overview consistent with the
current test harness layout by editing the sections that enumerate
crates/cua-driver/tests and the coverage table entry for WPF.
In `@libs/cua-driver/test-harness/TEST_SUITE.md`:
- Line 47: The fenced ASCII diagram block in TEST_SUITE.md is missing a language
tag, which violates MD040. Update the Markdown fence for the modality diagram to
use an explicit text language identifier, and keep the diagram content unchanged
so the block is still rendered as plain text. Refer to the fenced block in
TEST_SUITE.md when making the change.
- Around line 77-78: The “Status of the new test” note in TEST_SUITE.md is a
pre-PR status update that will be stale once merged. Update this section to
remove references to the side branch, “Not yet PR’d,” and the pending PR
decision, and keep only stable guidance about how to compile-verify and run the
harness test using harness_desktop_scope_test.rs and the interactive-session
method.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 429c1d55-f82b-494f-ae4d-b417c3e90294
📒 Files selected for processing (3)
libs/cua-driver/rust/crates/cua-driver/tests/harness_desktop_scope_test.rslibs/cua-driver/test-harness/TEST_HARNESS_STRUCTURE.mdlibs/cua-driver/test-harness/TEST_SUITE.md
| let app = spawn_in_job(Command::new(&exe).stdout(Stdio::null()).stderr(Stdio::null())).ok()?; | ||
| fx._bag.push(app); | ||
| let deadline = Instant::now() + Duration::from_secs(15); | ||
| while Instant::now() < deadline { | ||
| let r = call(&mut fx.stdin, &fx.rx, 50, "list_windows", serde_json::json!({})); | ||
| if let Some(arr) = structured(&r)["windows"].as_array() { | ||
| for w in arr { | ||
| let title = w["title"].as_str().unwrap_or(""); | ||
| if !title.contains("CuaTestHarness") { continue; } | ||
| let pid = w["pid"].as_u64().unwrap_or(0) as u32; | ||
| // #2018: bounds is nested {x,y,width,height} on Windows. | ||
| let b = &w["bounds"]; | ||
| let (x, y, ww, h) = ( | ||
| b["x"].as_i64().unwrap_or(0) as i32, b["y"].as_i64().unwrap_or(0) as i32, | ||
| b["width"].as_i64().unwrap_or(0) as i32, b["height"].as_i64().unwrap_or(0) as i32, | ||
| ); | ||
| if pid != 0 && ww > 0 && h > 0 { | ||
| assign_pid_to_job(pid); | ||
| fx._bag.track_pid(pid); | ||
| return Some((pid, x + ww / 2, y + h / 2)); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Match the launched WPF instance by PID.
This loop accepts the first CuaTestHarness title it sees, so an already-open harness window can satisfy the test and send input to the wrong process. Capture app.id() before pushing the child into the bag and require w["pid"] to match it.
Suggested fix
- let app = spawn_in_job(Command::new(&exe).stdout(Stdio::null()).stderr(Stdio::null())).ok()?;
- fx._bag.push(app);
+ let app = spawn_in_job(Command::new(&exe).stdout(Stdio::null()).stderr(Stdio::null())).ok()?;
+ let launched_pid = app.id();
+ fx._bag.push(app);
@@
- let pid = w["pid"].as_u64().unwrap_or(0) as u32;
+ let pid = w["pid"].as_u64().unwrap_or(0) as u32;
+ if pid != launched_pid { continue; }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| let app = spawn_in_job(Command::new(&exe).stdout(Stdio::null()).stderr(Stdio::null())).ok()?; | |
| fx._bag.push(app); | |
| let deadline = Instant::now() + Duration::from_secs(15); | |
| while Instant::now() < deadline { | |
| let r = call(&mut fx.stdin, &fx.rx, 50, "list_windows", serde_json::json!({})); | |
| if let Some(arr) = structured(&r)["windows"].as_array() { | |
| for w in arr { | |
| let title = w["title"].as_str().unwrap_or(""); | |
| if !title.contains("CuaTestHarness") { continue; } | |
| let pid = w["pid"].as_u64().unwrap_or(0) as u32; | |
| // #2018: bounds is nested {x,y,width,height} on Windows. | |
| let b = &w["bounds"]; | |
| let (x, y, ww, h) = ( | |
| b["x"].as_i64().unwrap_or(0) as i32, b["y"].as_i64().unwrap_or(0) as i32, | |
| b["width"].as_i64().unwrap_or(0) as i32, b["height"].as_i64().unwrap_or(0) as i32, | |
| ); | |
| if pid != 0 && ww > 0 && h > 0 { | |
| assign_pid_to_job(pid); | |
| fx._bag.track_pid(pid); | |
| return Some((pid, x + ww / 2, y + h / 2)); | |
| let app = spawn_in_job(Command::new(&exe).stdout(Stdio::null()).stderr(Stdio::null())).ok()?; | |
| let launched_pid = app.id(); | |
| fx._bag.push(app); | |
| let deadline = Instant::now() + Duration::from_secs(15); | |
| while Instant::now() < deadline { | |
| let r = call(&mut fx.stdin, &fx.rx, 50, "list_windows", serde_json::json!({})); | |
| if let Some(arr) = structured(&r)["windows"].as_array() { | |
| for w in arr { | |
| let title = w["title"].as_str().unwrap_or(""); | |
| if !title.contains("CuaTestHarness") { continue; } | |
| let pid = w["pid"].as_u64().unwrap_or(0) as u32; | |
| if pid != launched_pid { continue; } | |
| // `#2018`: bounds is nested {x,y,width,height} on Windows. | |
| let b = &w["bounds"]; | |
| let (x, y, ww, h) = ( | |
| b["x"].as_i64().unwrap_or(0) as i32, b["y"].as_i64().unwrap_or(0) as i32, | |
| b["width"].as_i64().unwrap_or(0) as i32, b["height"].as_i64().unwrap_or(0) as i32, | |
| ); | |
| if pid != 0 && ww > 0 && h > 0 { | |
| assign_pid_to_job(pid); | |
| fx._bag.track_pid(pid); | |
| return Some((pid, x + ww / 2, y + h / 2)); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@libs/cua-driver/rust/crates/cua-driver/tests/harness_desktop_scope_test.rs`
around lines 176 - 195, The harness window selection in the desktop scope test
is matching only by title, which can pick an already-open CuaTestHarness instead
of the newly launched WPF process. Capture the spawned child PID from app.id()
in the spawn_in_job block before pushing it into fx._bag, then update the
list_windows scan in the same test to require w["pid"] to equal that PID before
calling assign_pid_to_job and returning the window center.
| let r = call(&mut fx.stdin, &fx.rx, 20, "get_desktop_state", serde_json::json!({})); | ||
| assert!(!is_error(&r), "get_desktop_state errored: {r}"); | ||
| let sw = structured(&r)["screen_width"].as_u64().unwrap_or(0); | ||
| let sh = structured(&r)["screen_height"].as_u64().unwrap_or(0); | ||
| assert!(sw > 0 && sh > 0, "get_desktop_state returned no/zero screen size: {r}"); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Assert the screenshot is not downscaled.
Right now this passes as long as screen_width/screen_height are nonzero. It does not verify the desktop-scope contract that the captured image is in true screen pixels. Compare screenshot_width/screenshot_height against the reported screen dimensions as well.
Suggested fix
let sw = structured(&r)["screen_width"].as_u64().unwrap_or(0);
let sh = structured(&r)["screen_height"].as_u64().unwrap_or(0);
+ let cw = structured(&r)["screenshot_width"].as_u64().unwrap_or(0);
+ let ch = structured(&r)["screenshot_height"].as_u64().unwrap_or(0);
assert!(sw > 0 && sh > 0, "get_desktop_state returned no/zero screen size: {r}");
+ assert_eq!((cw, ch), (sw, sh), "get_desktop_state returned a downscaled capture: {r}");📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| let r = call(&mut fx.stdin, &fx.rx, 20, "get_desktop_state", serde_json::json!({})); | |
| assert!(!is_error(&r), "get_desktop_state errored: {r}"); | |
| let sw = structured(&r)["screen_width"].as_u64().unwrap_or(0); | |
| let sh = structured(&r)["screen_height"].as_u64().unwrap_or(0); | |
| assert!(sw > 0 && sh > 0, "get_desktop_state returned no/zero screen size: {r}"); | |
| let r = call(&mut fx.stdin, &fx.rx, 20, "get_desktop_state", serde_json::json!({})); | |
| assert!(!is_error(&r), "get_desktop_state errored: {r}"); | |
| let sw = structured(&r)["screen_width"].as_u64().unwrap_or(0); | |
| let sh = structured(&r)["screen_height"].as_u64().unwrap_or(0); | |
| let cw = structured(&r)["screenshot_width"].as_u64().unwrap_or(0); | |
| let ch = structured(&r)["screenshot_height"].as_u64().unwrap_or(0); | |
| assert!(sw > 0 && sh > 0, "get_desktop_state returned no/zero screen size: {r}"); | |
| assert_eq!((cw, ch), (sw, sh), "get_desktop_state returned a downscaled capture: {r}"); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@libs/cua-driver/rust/crates/cua-driver/tests/harness_desktop_scope_test.rs`
around lines 223 - 227, The desktop-scope test only checks that
get_desktop_state returns nonzero screen dimensions, but it does not verify the
screenshot is in true screen pixels. Update the assertions in
harness_desktop_scope_test around get_desktop_state to also read
screenshot_width and screenshot_height from the structured response and compare
them against screen_width and screen_height. Keep the existing checks, and add
explicit equality assertions for the screenshot dimensions to enforce the
desktop-scope contract.
| fn window_scope_rejects_windowless_click() { | ||
| let Some(mut fx) = spawn_driver() else { return }; | ||
| set_scope(&mut fx, "window"); | ||
| let r = call(&mut fx.stdin, &fx.rx, 30, "click", serde_json::json!({"x": 100, "y": 100})); | ||
| let txt = result_text(&r).to_lowercase(); | ||
| assert!( | ||
| is_error(&r) || txt.contains("desktop scope") || txt.contains("desktop_scope_disabled"), | ||
| "window-scope window-less click was NOT rejected: {r}" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Check the specific desktop_scope_disabled rejection.
This assertion currently passes on any error, including unrelated transport/startup failures. The implementation advertises a structured desktop_scope_disabled contract here, so the test should assert that exact code instead of treating all failures as success.
Suggested fix
let r = call(&mut fx.stdin, &fx.rx, 30, "click", serde_json::json!({"x": 100, "y": 100}));
- let txt = result_text(&r).to_lowercase();
- assert!(
- is_error(&r) || txt.contains("desktop scope") || txt.contains("desktop_scope_disabled"),
- "window-scope window-less click was NOT rejected: {r}"
- );
+ assert!(is_error(&r), "window-scope window-less click was NOT rejected: {r}");
+ assert_eq!(
+ structured(&r)["code"].as_str(),
+ Some("desktop_scope_disabled"),
+ "unexpected rejection payload: {r}"
+ );📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| fn window_scope_rejects_windowless_click() { | |
| let Some(mut fx) = spawn_driver() else { return }; | |
| set_scope(&mut fx, "window"); | |
| let r = call(&mut fx.stdin, &fx.rx, 30, "click", serde_json::json!({"x": 100, "y": 100})); | |
| let txt = result_text(&r).to_lowercase(); | |
| assert!( | |
| is_error(&r) || txt.contains("desktop scope") || txt.contains("desktop_scope_disabled"), | |
| "window-scope window-less click was NOT rejected: {r}" | |
| fn window_scope_rejects_windowless_click() { | |
| let Some(mut fx) = spawn_driver() else { return }; | |
| set_scope(&mut fx, "window"); | |
| let r = call(&mut fx.stdin, &fx.rx, 30, "click", serde_json::json!({"x": 100, "y": 100})); | |
| assert!(is_error(&r), "window-scope window-less click was NOT rejected: {r}"); | |
| assert_eq!( | |
| structured(&r)["code"].as_str(), | |
| Some("desktop_scope_disabled"), | |
| "unexpected rejection payload: {r}" | |
| ); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@libs/cua-driver/rust/crates/cua-driver/tests/harness_desktop_scope_test.rs`
around lines 257 - 264, Update window_scope_rejects_windowless_click to assert
the exact desktop_scope_disabled rejection from call/result_text instead of
accepting any is_error() outcome; keep the existing setup via spawn_driver,
set_scope, and call, but make the assertion verify the structured error
code/message for the click action rather than unrelated transport or startup
failures.
|
|
||
| ## Directory layout | ||
|
|
||
| ``` |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Add a language to this fenced block.
markdownlint is right here: the opening fence should declare a language (for example text) to satisfy MD040.
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 7-7: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@libs/cua-driver/test-harness/TEST_HARNESS_STRUCTURE.md` at line 7, The fenced
code block in TEST_HARNESS_STRUCTURE.md is missing a language declaration, which
triggers markdownlint MD040. Update the opening fence in this markdown snippet
to specify an appropriate language such as text, and keep the rest of the block
unchanged.
Source: Linters/SAST tools
| libs/cua-driver/rust/crates/cua-driver/tests/ ◀── the CONSUMERS (Rust integration tests) | ||
| ├── harness_wpf_test.rs (Windows) | ||
| ├── harness_winui3_test.rs (Windows) | ||
| ├── harness_web_windows_test.rs (Windows — WebView2 + Electron via CDP) | ||
| ├── harness_bg_modality_test.rs (Windows — focus-steal sentinel + capture_mode) | ||
| ├── harness_lo_vcl_test.rs (Windows — LibreOffice VCL/SAL via MSAA) | ||
| ├── harness_appkit_test.rs (macOS) | ||
| └── harness_swiftui_test.rs (macOS) |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Add harness_desktop_scope_test.rs to the consumer lists.
This doc still omits the new desktop-scope test from the crates/cua-driver/tests/ tree and from the WPF coverage row, so the structure overview is already stale relative to this PR.
Suggested fix
libs/cua-driver/rust/crates/cua-driver/tests/ ◀── the CONSUMERS (Rust integration tests)
├── harness_wpf_test.rs (Windows)
├── harness_winui3_test.rs (Windows)
├── harness_web_windows_test.rs (Windows — WebView2 + Electron via CDP)
├── harness_bg_modality_test.rs (Windows — focus-steal sentinel + capture_mode)
+├── harness_desktop_scope_test.rs (Windows — desktop-scope / foreground modality)
├── harness_lo_vcl_test.rs (Windows — LibreOffice VCL/SAL via MSAA)
@@
-| `windows/wpf` | Windows | `wpf` | UIA Invoke, PostMessage type, right/double-click, scroll, modal MessageBox, owned + layered popups, native child HWNDs, accelerators | `harness_wpf_test`, `harness_bg_modality_test` |
+| `windows/wpf` | Windows | `wpf` | UIA Invoke, PostMessage type, right/double-click, scroll, modal MessageBox, owned + layered popups, native child HWNDs, accelerators | `harness_wpf_test`, `harness_bg_modality_test`, `harness_desktop_scope_test` |Also applies to: 95-95
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@libs/cua-driver/test-harness/TEST_HARNESS_STRUCTURE.md` around lines 38 - 45,
Add harness_desktop_scope_test.rs to the consumer tree in
TEST_HARNESS_STRUCTURE.md and update the WPF coverage row so the new
desktop-scope integration test is listed alongside the existing
harness_*_test.rs consumers. Keep the structure overview consistent with the
current test harness layout by editing the sections that enumerate
crates/cua-driver/tests and the coverage table entry for WPF.
|
|
||
| ## Modality coverage — the two halves | ||
|
|
||
| ``` |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Add a language to this fenced block.
The ASCII modality diagram should use a language tag such as text to satisfy MD040.
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 47-47: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@libs/cua-driver/test-harness/TEST_SUITE.md` at line 47, The fenced ASCII
diagram block in TEST_SUITE.md is missing a language tag, which violates MD040.
Update the Markdown fence for the modality diagram to use an explicit text
language identifier, and keep the diagram content unchanged so the block is
still rendered as plain text. Refer to the fenced block in TEST_SUITE.md when
making the change.
Source: Linters/SAST tools
| ## Status of the new test | ||
| `harness_desktop_scope_test.rs` is on branch **`test/desktop-scope-harness`** (off latest `main`, which already has #2019). Compile-verifying on the Windows VM; a live run uses the interactive-session method. Not yet PR'd — pending decision on its own PR vs. folding into the harness suite. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Drop the pre-PR status note before merging.
This file ships in the PR, so saying the test is “Not yet PR'd” and tied to a side branch will become false immediately. Replace this section with stable runtime guidance only.
Suggested fix
## Status of the new test
-`harness_desktop_scope_test.rs` is on branch **`test/desktop-scope-harness`** (off latest `main`, which already has `#2019`). Compile-verifying on the Windows VM; a live run uses the interactive-session method. Not yet PR'd — pending decision on its own PR vs. folding into the harness suite.
+`harness_desktop_scope_test.rs` is `#[ignore]` and requires a real interactive Windows desktop session for live execution. Compile checks can run on a Windows VM; the behavior checks require the interactive-session method described above.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ## Status of the new test | |
| `harness_desktop_scope_test.rs` is on branch **`test/desktop-scope-harness`** (off latest `main`, which already has #2019). Compile-verifying on the Windows VM; a live run uses the interactive-session method. Not yet PR'd — pending decision on its own PR vs. folding into the harness suite. | |
| `harness_desktop_scope_test.rs` is `#[ignore]` and requires a real interactive Windows desktop session for live execution. Compile checks can run on a Windows VM; the behavior checks require the interactive-session method described above. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@libs/cua-driver/test-harness/TEST_SUITE.md` around lines 77 - 78, The “Status
of the new test” note in TEST_SUITE.md is a pre-PR status update that will be
stale once merged. Update this section to remove references to the side branch,
“Not yet PR’d,” and the pending PR decision, and keep only stable guidance about
how to compile-verify and run the harness test using
harness_desktop_scope_test.rs and the interactive-session method.
Linux visual regression artifactsMatrix jobs now run independently. Download visual artifacts from this workflow run.
|
What
Adds the first dedicated test for the desktop-scope / foreground modality (#1968 / #2019), plus two visual docs of the cua-driver test layer.
Test —
harness_desktop_scope_test.rs(Windows, 3#[ignore]integration tests)Foreground/desktop-scope was previously only exercised incidentally by
harness_lo_vcl_test(dispatch:"foreground"for VCL edge cases). This is the first test that targets the modality directly:desktop_scope_capture_returns_screen_dims—set_config capture_scope=desktop→get_desktop_statereturns a full-display capture with realscreen_width/height.desktop_scope_windowless_click_and_scroll_land— screen-absoluteclick+scrollwith no pid/window_id land viaWindowFromPoint, reported as(desktop scope).window_scope_rejects_windowless_click— undercapture_scope=window, a window-less click is rejected (desktop_scope_disabled), not silently retargeted.Reuses the
e2e_windows_bg_input_testharness pattern (kill-on-close Job Object,ChildBagDrop guard, JSON-RPC stdio helpers). One long-lived MCP server per test — required becauseset_configoverrides are session-scoped.Docs (
libs/cua-driver/test-harness/)TEST_HARNESS_STRUCTURE.md— harness-apps topology:scenarios.jsonsingle-source-of-truth, apps/build/tests wiring, coverage matrix.TEST_SUITE.md— the Rust integration-test suite: inventory of ~135 test fns, the test→MCP-server→app loop, and the background vs. foreground/desktop-scope modality coverage breakdown.Verification
cargo test --no-run -p cua-driver --test harness_desktop_scope_test, exit 0) againstcua-driver v0.6.8.#[ignore](need a real interactive desktop;get_desktop_statefails in Session 0). Run with:cargo test -p cua-driver --test harness_desktop_scope_test -- --ignored --nocapture --test-threads=1🤖 Generated with Claude Code
Summary by CodeRabbit
Tests
Documentation