Skip to content

Commit 7f735cd

Browse files
committed
Rework Node#obscured? frame support in JavaScript
Teaches `isObscured` how to traverse nested frames.
1 parent a5a2b63 commit 7f735cd

File tree

2 files changed

+31
-27
lines changed

2 files changed

+31
-27
lines changed

lib/capybara/cuprite/browser.rb

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,11 @@ def path(node)
211211
end
212212

213213
def obscured?(node, x = nil, y = nil)
214-
value = if x && y
215-
evaluate_on(node: node, expression: "_cuprite.isObscured(this, #{x}, #{y})")
216-
else
217-
evaluate_on(node: node, expression: "_cuprite.isObscured(this)")
218-
end
219-
return true if value == true
220-
221-
frame_obscured_at?(*value.values_at("x", "y"))
214+
if x && y
215+
evaluate_on(node: node, expression: "_cuprite.isObscured(this, #{x}, #{y})")
216+
else
217+
evaluate_on(node: node, expression: "_cuprite.isObscured(this)")
218+
end
222219
end
223220

224221
def all_text(node)
@@ -268,21 +265,6 @@ def attach_page(target_id = nil)
268265
target.page = Page.new(target.client, context_id: target.context_id, target_id: target.id)
269266
target.page
270267
end
271-
272-
def frame_obscured_at?(x, y)
273-
frame = page.active_frame
274-
return false if frame.main?
275-
276-
frame_node = frame.evaluate("window.frameElement")
277-
return false unless frame_node
278-
279-
switch_to_frame(:parent)
280-
begin
281-
obscured?(frame_node, x, y)
282-
ensure
283-
switch_to_frame(frame)
284-
end
285-
end
286268
end
287269
end
288270
end

lib/capybara/cuprite/javascripts/index.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,38 @@ 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+
* @param {number} [x] the center position
123+
* @param {number} [y] the center position
124+
* @return {boolean} true if the node is obscured, false otherwise
125+
*/
118126
isObscured(node, x, y) {
127+
let win = window;
119128
let rect = node.getBoundingClientRect();
120-
if (x == null) x = rect.width/2;
121-
if (y == null) y = rect.height/2;
129+
x = x ?? rect.width / 2;
130+
y = y ?? rect.height / 2;
122131

123132
let px = rect.left + x;
124133
let py = rect.top + y;
125-
let e = document.elementFromPoint(px, py);
126134

127-
return !node.contains(e) || { x: px, y: py };
135+
while (win) {
136+
let topNode = win.document.elementFromPoint(px, py);
137+
138+
if (node !== topNode && !node.contains(topNode)) return true;
139+
140+
node = win.frameElement;
141+
if (!node) return false;
142+
143+
rect = node.getBoundingClientRect();
144+
px = rect.left + px;
145+
py = rect.top + py;
146+
win = win.parent;
147+
}
148+
149+
return false;
128150
}
129151

130152
set(node, value) {

0 commit comments

Comments
 (0)