2
2
3
3
module Ferrum
4
4
class Node
5
+ MOVING_WAIT = ENV . fetch ( "FERRUM_NODE_MOVING_WAIT" , 0.01 ) . to_f
6
+ MOVING_ATTEMPTS = ENV . fetch ( "FERRUM_NODE_MOVING_ATTEMPTS" , 50 ) . to_i
7
+
5
8
attr_reader :page , :target_id , :node_id , :description , :tag_name
6
9
7
10
def initialize ( frame , target_id , node_id , description )
@@ -121,16 +124,42 @@ def inspect
121
124
end
122
125
123
126
def find_position ( x : nil , y : nil , position : :top )
124
- offset_x , offset_y = x , y
125
- quads = get_content_quads
127
+ prev = get_content_quads
128
+
129
+ # FIXME: Case when a few quads returned
130
+ points = Ferrum . with_attempts ( errors : NodeIsMovingError , max : MOVING_ATTEMPTS , wait : 0 ) do
131
+ sleep ( MOVING_WAIT )
132
+ current = get_content_quads
133
+
134
+ if current != prev
135
+ error = NodeIsMovingError . new ( self , prev , current )
136
+ prev = current
137
+ raise ( error )
138
+ end
139
+
140
+ current
141
+ end . map { |q | to_points ( q ) } . first
142
+
143
+ get_position ( points , x , y , position )
144
+ end
145
+
146
+ private
147
+
148
+ def get_content_quads
149
+ quads = page . command ( "DOM.getContentQuads" , nodeId : node_id ) [ "quads" ]
150
+ raise "Node is either not visible or not an HTMLElement" if quads . size == 0
151
+ quads
152
+ end
153
+
154
+ def get_position ( points , offset_x , offset_y , position )
126
155
x = y = nil
127
156
128
157
if offset_x && offset_y && position == :top
129
- point = quads . first
158
+ point = points . first
130
159
x = point [ :x ] + offset_x . to_i
131
160
y = point [ :y ] + offset_y . to_i
132
161
else
133
- x , y = quads . inject ( [ 0 , 0 ] ) do |memo , point |
162
+ x , y = points . inject ( [ 0 , 0 ] ) do |memo , point |
134
163
[ memo [ 0 ] + point [ :x ] ,
135
164
memo [ 1 ] + point [ :y ] ]
136
165
end
@@ -147,19 +176,11 @@ def find_position(x: nil, y: nil, position: :top)
147
176
[ x , y ]
148
177
end
149
178
150
- private
151
-
152
- def get_content_quads
153
- result = page . command ( "DOM.getContentQuads" , nodeId : node_id )
154
- raise "Node is either not visible or not an HTMLElement" if result [ "quads" ] . size == 0
155
-
156
- # FIXME: Case when a few quads returned
157
- result [ "quads" ] . map do |quad |
158
- [ { x : quad [ 0 ] , y : quad [ 1 ] } ,
159
- { x : quad [ 2 ] , y : quad [ 3 ] } ,
160
- { x : quad [ 4 ] , y : quad [ 5 ] } ,
161
- { x : quad [ 6 ] , y : quad [ 7 ] } ]
162
- end . first
179
+ def to_points ( quad )
180
+ [ { x : quad [ 0 ] , y : quad [ 1 ] } ,
181
+ { x : quad [ 2 ] , y : quad [ 3 ] } ,
182
+ { x : quad [ 4 ] , y : quad [ 5 ] } ,
183
+ { x : quad [ 6 ] , y : quad [ 7 ] } ]
163
184
end
164
185
end
165
186
end
0 commit comments