From 6cb595c0bb778c1b1d7e5e61217cca995971faec Mon Sep 17 00:00:00 2001 From: Sean Doyle Date: Fri, 3 Apr 2026 15:08:58 -0400 Subject: [PATCH] Implement `Capybara::Cuprite::Node#rect` Closes https://github.com/rubycdp/cuprite/issues/276 The implementation's call to [toJSON][] is necessary since the object returned by [Element.getBoundingClientRect][] is an instance of [DOMRect][], and is therefore unable to have its keys iterated and serialized back to Cuprite on its own. [Element.getBoundingClientRect]: https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect [DOMRect]: https://developer.mozilla.org/en-US/docs/Web/API/DOMRect [toJSON]: https://github.com/segment-boneyard/nightmare/issues/723#issuecomment-374683727 --- CHANGELOG.md | 1 + lib/capybara/cuprite/node.rb | 6 ++++++ spec/features/driver_spec.rb | 14 ++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17692300..ddbe0853 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Added - Support time inputs [#245] - Add initial support for shadow_root [#234] +- Support `Capybara::Cuprite::Node#rect` [#276] ### Changed diff --git a/lib/capybara/cuprite/node.rb b/lib/capybara/cuprite/node.rb index 9c7b3d26..6ea95b46 100644 --- a/lib/capybara/cuprite/node.rb +++ b/lib/capybara/cuprite/node.rb @@ -236,6 +236,12 @@ def shadow_root root && self.class.new(driver, root.node) end + def rect + driver.evaluate_script <<~JS, self + arguments[0].getBoundingClientRect().toJSON() + JS + end + def inspect %(#<#{self.class} @node=#{@node.inspect}>) end diff --git a/spec/features/driver_spec.rb b/spec/features/driver_spec.rb index 2f12248f..8041d3e0 100644 --- a/spec/features/driver_spec.rb +++ b/spec/features/driver_spec.rb @@ -1447,6 +1447,20 @@ def create_screenshot(file, *args) end end + context "find" do + before { @session.visit("/cuprite/click_coordinates") } + + it "supports position filters" do + box = @session.find(:css, "#box") + log = @session.find(:css, "#log") + + expect(@session).to have_element(id: "box", above: log) + expect(@session).to have_element(id: "log", below: box) + expect(@session).not_to have_element(id: "box", below: log) + expect(@session).not_to have_element(id: "log", above: box) + end + end + context "set" do before { @session.visit("/cuprite/set") }