Skip to content

Support Capybara's finder hints in find_css and find_xpath - #347

Open
joeljunstrom wants to merge 1 commit into
rubycdp:mainfrom
joeljunstrom:find-hints
Open

joeljunstrom wants to merge 1 commit into
rubycdp:mainfrom
joeljunstrom:find-hints

Conversation

@joeljunstrom

@joeljunstrom joeljunstrom commented Oct 19, 2026 •

Copy link
Copy Markdown

Capybara passes uses_visibility, texts, styles and position to drivers whose finders accept them, and reads the answers from Node#initial_cache. Cuprite's finders took only the selector, so Capybara asked every candidate for its visibility and text separately, about 8 CDP commands per node.

The browser now answers the hints in the same call that finds the nodes. It returns each node with its answers as JSON, read from the array's handle, so nodes and answers can't come from different pages. Ferrum only resolves arrays that hold nothing but nodes, which is why the handle is read directly.

Text is filtered case-sensitively against all text or visible text, the strings Capybara compares, so nothing Capybara would match is dropped. Selenium's lowercased textContent filter misses a word split by a hidden element.

On a list of 300 items, every third one hidden:

Query Before After
find("li", text: "Item 298") 2603 cmds, 397 ms 8 cmds, 11 ms
all("li", minimum: 1) 1803 cmds, 251 ms 302 cmds, 56 ms
assert_selector("li", text: "Item 2", count: 75) 2603 cmds, 345 ms 595 cmds, 82 ms
first("li", text: "Item 298", below: …) 2919 cmds, 394 ms 157 cmds, 23 ms

In a (well my) Rails app's suite the gain is smaller: about 10–20% fewer commands per test, with no measurable wall-time change, because most finds match few elements.

Browser#find and #find_within still return nodes.

Capybara passes uses_visibility, texts, styles and position to finders that take them and reads the answers from
Node#initial_cache. Without them it asked each candidate for its visibility and text in round trips of its own.

One callFunctionOn returns each node behind its answers as JSON, read from the array's handle with getProperties,
since Ferrum only resolves arrays that hold nothing but nodes. Texts drop a node only when neither all its text nor
its visible text holds them, case sensitively, as Capybara matches. Browser#find and #find_within still return nodes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant