Repository navigation
test: Add find_all and configurable clicks to the UI test harness - #3384
Merged
huacnlee merged 5 commits intoOct 7, 2026
Merged
Conversation
The pointer helpers sent every mouse move, down and up event with `Modifiers::default()`, so a UI test could not reach code that reads `event.modifiers()`, such as a List row confirming with `secondary: e.modifiers().secondary()`. `click_with_modifiers` left-clicks a target with the given modifiers on the move, down and up events. It mirrors GPUI's `VisualTestContext::simulate_click(position, modifiers)` and is available on both `TestWindowExt` and `ScopedWindow`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PRpJSFk3zTwdgAJHehdZFm
`find` and `try_find` panic when an ID matches more than one element, and `within` needs a single scope. A test could not count repeated elements whose paths differ only by generated IDs, such as a stack of notifications that each render a `notification` toast. `find_all` returns every match in the window or scope, or an empty `Vec`. The registry is a `HashMap`, so matches are sorted top to bottom, then left to right by bounds origin, with the path as the tie breaker. `find` now reuses the same lookup and keeps its ambiguity assertion. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PRpJSFk3zTwdgAJHehdZFm
Contributor
Author
Written with OpenAI Codex assistance.
Written with OpenAI Codex assistance.
huacnlee
enabled auto-merge (squash)
October 7, 2026 05:45
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
UI integration tests could neither count repeated local IDs nor exercise clicks with modifiers. This adds collection queries and configurable native clicks through the existing
TestWindowExttrait. The new required methods are an intentional breaking change for downstream trait implementations.TestWindowExt::find_allreturns every registered matching snapshot, including invisible elements. Results follow the current frame's bounds origin (y, then x); equal-origin order is unspecified. This is geometry, not stable identity, paint order, or business order. Existing unique queries still reject ambiguous IDs.TestWindowExtprovidesclick_with_optionsand a centeredclick_with_modifiersconvenience method.ClickOptionscombines local offset, mouse button, positive click count, and modifiers using private fields and builders.ScopedWindowexposes the same new capabilities inside its identity scope.For example:
This change was written with AI assistance (Claude Code and OpenAI Codex).
Public API
gpui-kit::testTestWindowExt::find_all(&self, id: impl Into<ElementId>) -> Vec<ElementSnapshot>: all registered matches from the last completed frame; empty when absent.TestWindowExt::click_with_options(&mut self, id: impl Into<ElementId>, options: ClickOptions, cx: &mut App): dispatches a configured click and restores modifier state.TestWindowExt::click_with_modifiers(&mut self, id: impl Into<ElementId>, modifiers: Modifiers, cx: &mut App): default method for one centered left click with modifiers.pub struct ClickOptions: caller-owned click configuration with private fields; implementsClone,Copy,Debug, andDefault.ClickOptions::new() -> Self: creates a centered single left click without modifiers.ClickOptions::with_offset(self, offset: Point<Pixels>) -> Self: sets a local offset from the target's top-left corner.ClickOptions::offset(&self) -> Option<Point<Pixels>>: returns the offset;Nonemeans center.ClickOptions::with_button(self, button: MouseButton) -> Self: sets the mouse button.ClickOptions::button(&self) -> MouseButton: reads the mouse button.ClickOptions::with_count(self, count: usize) -> Self: sets the click count; panics for zero.ClickOptions::count(&self) -> usize: reads the positive click count.ClickOptions::with_modifiers(self, modifiers: Modifiers) -> Self: sets the modifiers for the sequence.ClickOptions::modifiers(&self) -> Modifiers: reads the modifiers.ScopedWindow::find_all(&self, id: impl Into<ElementId>) -> Vec<ElementSnapshot>: collection query restricted to the scope.ScopedWindow::click_with_options(&mut self, id: impl Into<ElementId>, options: ClickOptions, cx: &mut App): configured click restricted to the scope.ScopedWindow::click_with_modifiers(&mut self, id: impl Into<ElementId>, modifiers: Modifiers, cx: &mut App): centered modified left click restricted to the scope.gpui-base::test_support(internal,#[doc(hidden)])find_all(window: &Window, scope: &[ElementId], id: &ElementId) -> Vec<ElementSnapshot>: lookup behind Kit's collection queries.find(window: &Window, scope: &[ElementId], id: &ElementId) -> Option<ElementSnapshot>delegates to the shared lookup and retains its ambiguity assertion.Breaking Changes
TestWindowExtgains two required methods:find_allandclick_with_options.Downstream implementations must implement both.
click_with_modifiershas a defaultimplementation through
click_with_options. Call sites continue to import onlyTestWindowExtfor all window queries and interactions.impl TestWindowExt for MyTestWindow { // Existing methods remain. + fn find_all(&self, id: impl Into<ElementId>) -> Vec<ElementSnapshot> { + self.window.find_all(id) + } + fn click_with_options(&mut self, id: impl Into<ElementId>, options: ClickOptions, cx: &mut App) { + self.window.click_with_options(id, options, cx); + } }Validation
Linux validation:
cargo check -p gpui-kit --features test-support --tests --lockedcargo test -p gpui-kit --features test-support --test interactions --test window --test collections --test overlays --lockedcargo clippy -p gpui-kit --features test-support --tests --locked --no-deps -- -D warningscargo fmt --all --checkgit diff --checkRegression coverage checks modifiers on pointer events, modifier-change callbacks and restoration of both neutral and pre-existing states, combined offset/right-double-click/Shift on both window and scoped APIs, configuration defaults and invalid zero counts, repeated-ID scope filtering, and stacked notifications. macOS and Windows validation remains with CI.