Skip to content

Commit 4fa8126

Browse files
authored
Add support for Node#obscured? (#291)
1 parent ec4b49b commit 4fa8126

File tree

5 files changed

+62
-5
lines changed

5 files changed

+62
-5
lines changed

lib/capybara/cuprite/browser.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ def path(node)
210210
evaluate_on(node: node, expression: "_cuprite.path(this)")
211211
end
212212

213+
def obscured?(node)
214+
evaluate_on(node: node, expression: "_cuprite.isObscured(this)")
215+
end
216+
213217
def all_text(node)
214218
node.text
215219
end

lib/capybara/cuprite/javascripts/index.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,35 @@ class Cuprite {
115115
return `//${selectors.join("/")}`;
116116
}
117117

118+
/**
119+
* Returns true if the node is obscured in the viewport.
120+
*
121+
* @param {Element} node
122+
* @return {boolean} true if the node is obscured, false otherwise
123+
*/
124+
isObscured(node) {
125+
let win = window;
126+
let rect = node.getBoundingClientRect();
127+
let px = rect.left + rect.width / 2;
128+
let py = rect.top + rect.height / 2;
129+
130+
while (win) {
131+
let topNode = win.document.elementFromPoint(px, py);
132+
133+
if (node !== topNode && !node.contains(topNode)) return true;
134+
135+
node = win.frameElement;
136+
if (!node) return false;
137+
138+
rect = node.getBoundingClientRect();
139+
px = rect.left + px;
140+
py = rect.top + py;
141+
win = win.parent;
142+
}
143+
144+
return false;
145+
}
146+
118147
set(node, value) {
119148
if (node.readOnly) return;
120149

lib/capybara/cuprite/node.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,10 @@ def path
213213
command(:path)
214214
end
215215

216+
def obscured?
217+
command(:obscured?)
218+
end
219+
216220
def inspect
217221
%(#<#{self.class} @node=#{@node.inspect}>)
218222
end

spec/features/session_spec.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,31 @@
314314
end
315315
end
316316

317+
describe "Node#obscured?" do
318+
context "when the element is not in the viewport of parent element" do
319+
before do
320+
@session.visit("/cuprite/scroll")
321+
end
322+
323+
it "is is a boolean" do
324+
expect(@session.find_link("Link outside viewport")).to be_obscured
325+
expect(@session.find_link("Below the fold")).to be_obscured
326+
end
327+
end
328+
329+
context "when the element is only overlapped by descendants" do
330+
before do
331+
@session.visit("/with_html")
332+
end
333+
334+
# copied from https://github.com/teamcapybara/capybara/blob/master/lib/capybara/spec/session/node_spec.rb#L328
335+
# as this example is currently disabled on CI in the upstream suite
336+
it "is not obscured" do
337+
expect(@session.first(:css, "p:not(.para)")).not_to be_obscured
338+
end
339+
end
340+
end
341+
317342
it "has no trouble clicking elements when the size of a document changes" do
318343
@session.visit("/cuprite/long_page")
319344
@session.find(:css, "#penultimate").click

spec/spec_helper.rb

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ module TestSessions
3737
RSpec.configure do |config|
3838
config.define_derived_metadata do |metadata|
3939
regexes = <<~REGEXP.split("\n").map { |s| Regexp.quote(s.strip) }.join("|")
40-
node #obscured?
4140
node #drag_to should work with jsTree
4241
node #drag_to should drag and drop an object
4342
node #drag_to should drag and drop if scrolling is needed
@@ -68,10 +67,6 @@ module TestSessions
6867
node #path reports when element in shadow dom
6968
node #shadow_root
7069
node #set should submit single text input forms if ended with
71-
#all with obscured filter should only find nodes on top in the viewport when false
72-
#all with obscured filter should not find nodes on top outside the viewport when false
73-
#all with obscured filter should find top nodes outside the viewport when true
74-
#all with obscured filter should only find non-top nodes when true
7570
#fill_in should fill in a color field
7671
#fill_in should handle carriage returns with line feeds in a textarea correctly
7772
#has_field with valid should be false if field is invalid

0 commit comments

Comments
 (0)