cuprite 0.12 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,294 +2,288 @@
2
2
 
3
3
  require "forwardable"
4
4
 
5
- module Capybara::Cuprite
6
- class Node < Capybara::Driver::Node
7
- attr_reader :node
5
+ module Capybara
6
+ module Cuprite
7
+ class Node < Capybara::Driver::Node
8
+ attr_reader :node
8
9
 
9
- extend Forwardable
10
+ extend Forwardable
10
11
 
11
- delegate %i(description) => :node
12
- delegate %i(browser) => :driver
12
+ delegate %i[description] => :node
13
+ delegate %i[browser] => :driver
13
14
 
14
- def initialize(driver, node)
15
- super(driver, self)
16
- @node = node
17
- end
15
+ def initialize(driver, node)
16
+ super(driver, self)
17
+ @node = node
18
+ end
18
19
 
19
- def command(name, *args)
20
- browser.send(name, node, *args)
21
- rescue Ferrum::NodeNotFoundError => e
22
- raise ObsoleteNode.new(self, e.response)
23
- rescue Ferrum::BrowserError => e
24
- case e.message
25
- when "Cuprite.MouseEventFailed"
26
- raise MouseEventFailed.new(self, e.response)
27
- else
28
- raise
20
+ def command(name, *args)
21
+ browser.send(name, node, *args)
22
+ rescue Ferrum::NodeNotFoundError => e
23
+ raise ObsoleteNode.new(self, e.response)
24
+ rescue Ferrum::BrowserError => e
25
+ case e.message
26
+ when "Cuprite.MouseEventFailed"
27
+ raise MouseEventFailed.new(self, e.response)
28
+ else
29
+ raise
30
+ end
29
31
  end
30
- end
31
32
 
32
- def parents
33
- command(:parents).map do |parent|
34
- self.class.new(driver, parent)
33
+ def parents
34
+ command(:parents).map do |parent|
35
+ self.class.new(driver, parent)
36
+ end
35
37
  end
36
- end
37
38
 
38
- def find_xpath(selector)
39
- find(:xpath, selector)
40
- end
39
+ def find_xpath(selector)
40
+ find(:xpath, selector)
41
+ end
41
42
 
42
- def find_css(selector)
43
- find(:css, selector)
44
- end
43
+ def find_css(selector)
44
+ find(:css, selector)
45
+ end
45
46
 
46
- def find(method, selector)
47
- command(:find_within, method, selector).map do |node|
48
- self.class.new(driver, node)
47
+ def find(method, selector)
48
+ command(:find_within, method, selector).map do |node|
49
+ self.class.new(driver, node)
50
+ end
49
51
  end
50
- end
51
52
 
52
- def all_text
53
- filter_text(command(:all_text))
54
- end
53
+ def all_text
54
+ filter_text(command(:all_text))
55
+ end
55
56
 
56
- def visible_text
57
- if Capybara::VERSION.to_f < 3.0
58
- filter_text(command(:visible_text))
59
- else
57
+ def visible_text
60
58
  command(:visible_text).to_s
61
59
  .gsub(/\A[[:space:]&&[^\u00a0]]+/, "")
62
60
  .gsub(/[[:space:]&&[^\u00a0]]+\z/, "")
63
61
  .gsub(/\n+/, "\n")
64
62
  .tr("\u00a0", " ")
65
63
  end
66
- end
67
64
 
68
- def property(name)
69
- command(:property, name)
70
- end
71
-
72
- def [](name)
73
- # Although the attribute matters, the property is consistent. Return that in
74
- # preference to the attribute for links and images.
75
- if (tag_name == "img" && name == "src") ||
76
- (tag_name == "a" && name == "href")
77
- # if attribute exists get the property
78
- return command(:attribute, name) && command(:property, name)
65
+ def property(name)
66
+ command(:property, name)
79
67
  end
80
68
 
81
- value = property(name)
82
- value = command(:attribute, name) if value.nil? || value.is_a?(Hash)
69
+ def [](name)
70
+ # Although the attribute matters, the property is consistent. Return that in
71
+ # preference to the attribute for links and images.
72
+ if (tag_name == "img" && name == "src") ||
73
+ (tag_name == "a" && name == "href")
74
+ # if attribute exists get the property
75
+ return command(:attribute, name) && command(:property, name)
76
+ end
83
77
 
84
- value
85
- end
78
+ value = property(name)
79
+ value = command(:attribute, name) if value.nil? || value.is_a?(Hash)
86
80
 
87
- def attributes
88
- command(:attributes)
89
- end
81
+ value
82
+ end
90
83
 
91
- def value
92
- command(:value)
93
- end
84
+ def attributes
85
+ command(:attributes)
86
+ end
94
87
 
95
- def set(value, options = {})
96
- warn "Options passed to Node#set but Cuprite doesn't currently support any - ignoring" unless options.empty?
97
-
98
- if tag_name == "input"
99
- case self[:type]
100
- when "radio"
101
- click
102
- when "checkbox"
103
- click if value != checked?
104
- when "file"
105
- files = value.respond_to?(:to_ary) ? value.to_ary.map(&:to_s) : value.to_s
106
- command(:select_file, files)
107
- when "color"
108
- node.evaluate("this.setAttribute('value', '#{value}')")
109
- else
88
+ def value
89
+ command(:value)
90
+ end
91
+
92
+ def set(value, options = {})
93
+ warn "Options passed to Node#set but Cuprite doesn't currently support any - ignoring" unless options.empty?
94
+
95
+ if tag_name == "input"
96
+ case self[:type]
97
+ when "radio"
98
+ click
99
+ when "checkbox"
100
+ click if value != checked?
101
+ when "file"
102
+ files = value.respond_to?(:to_ary) ? value.to_ary.map(&:to_s) : value.to_s
103
+ command(:select_file, files)
104
+ when "color"
105
+ node.evaluate("this.setAttribute('value', '#{value}')")
106
+ else
107
+ command(:set, value.to_s)
108
+ end
109
+ elsif tag_name == "textarea"
110
110
  command(:set, value.to_s)
111
+ elsif self[:isContentEditable]
112
+ command(:delete_text)
113
+ send_keys(value.to_s)
111
114
  end
112
- elsif tag_name == "textarea"
113
- command(:set, value.to_s)
114
- elsif self[:isContentEditable]
115
- command(:delete_text)
116
- send_keys(value.to_s)
117
115
  end
118
- end
119
116
 
120
- def select_option
121
- command(:select, true)
122
- end
117
+ def select_option
118
+ command(:select, true)
119
+ end
123
120
 
124
- def unselect_option
125
- command(:select, false) ||
126
- raise(Capybara::UnselectNotAllowed, "Cannot unselect option from single select box.")
127
- end
121
+ def unselect_option
122
+ command(:select, false) ||
123
+ raise(Capybara::UnselectNotAllowed, "Cannot unselect option from single select box.")
124
+ end
128
125
 
129
- def tag_name
130
- @tag_name ||= description["nodeName"].downcase
131
- end
126
+ def tag_name
127
+ @tag_name ||= description["nodeName"].downcase
128
+ end
132
129
 
133
- def visible?
134
- command(:visible?)
135
- end
130
+ def visible?
131
+ command(:visible?)
132
+ end
136
133
 
137
- def checked?
138
- self[:checked]
139
- end
134
+ def checked?
135
+ self[:checked]
136
+ end
140
137
 
141
- def selected?
142
- !!self[:selected]
143
- end
138
+ def selected?
139
+ !!self[:selected]
140
+ end
144
141
 
145
- def disabled?
146
- command(:disabled?)
147
- end
142
+ def disabled?
143
+ command(:disabled?)
144
+ end
148
145
 
149
- def click(keys = [], **options)
150
- prepare_and_click(:left, __method__, keys, options)
151
- end
146
+ def click(keys = [], **options)
147
+ prepare_and_click(:left, __method__, keys, options)
148
+ end
152
149
 
153
- def right_click(keys = [], **options)
154
- prepare_and_click(:right, __method__, keys, options)
155
- end
150
+ def right_click(keys = [], **options)
151
+ prepare_and_click(:right, __method__, keys, options)
152
+ end
156
153
 
157
- def double_click(keys = [], **options)
158
- prepare_and_click(:double, __method__, keys, options)
159
- end
154
+ def double_click(keys = [], **options)
155
+ prepare_and_click(:double, __method__, keys, options)
156
+ end
160
157
 
161
- def hover
162
- command(:hover)
163
- end
158
+ def hover
159
+ command(:hover)
160
+ end
164
161
 
165
- def drag_to(other)
166
- command(:drag, other)
167
- end
162
+ def drag_to(other, **options)
163
+ options[:steps] ||= 1
168
164
 
169
- def drag_by(x, y)
170
- command(:drag_by, x, y)
171
- end
165
+ command(:drag, other.node, options[:steps], options[:delay])
166
+ end
172
167
 
173
- def trigger(event)
174
- command(:trigger, event)
175
- end
168
+ def drag_by(x, y, **options)
169
+ options[:steps] ||= 1
176
170
 
177
- def scroll_to(element, location, position = nil)
178
- if element.is_a?(Node)
179
- scroll_element_to_location(element, location)
180
- elsif location.is_a?(Symbol)
181
- scroll_to_location(location)
182
- else
183
- scroll_to_coords(*position)
171
+ command(:drag_by, x, y, options[:steps], options[:delay])
184
172
  end
185
- self
186
- end
187
173
 
188
- def scroll_by(x, y)
189
- driver.execute_script <<~JS, self, x, y
190
- var el = arguments[0];
191
- if (el.scrollBy){
192
- el.scrollBy(arguments[1], arguments[2]);
193
- } else {
194
- el.scrollTop = el.scrollTop + arguments[2];
195
- el.scrollLeft = el.scrollLeft + arguments[1];
196
- }
197
- JS
198
- end
174
+ def trigger(event)
175
+ command(:trigger, event)
176
+ end
199
177
 
200
- def ==(other)
201
- node == other.native.node
202
- end
178
+ def scroll_to(element, location, position = nil)
179
+ if element.is_a?(Node)
180
+ scroll_element_to_location(element, location)
181
+ elsif location.is_a?(Symbol)
182
+ scroll_to_location(location)
183
+ else
184
+ scroll_to_coords(*position)
185
+ end
186
+ self
187
+ end
203
188
 
204
- def send_keys(*keys)
205
- command(:send_keys, keys)
206
- end
207
- alias_method :send_key, :send_keys
189
+ def scroll_by(x, y)
190
+ driver.execute_script <<~JS, self, x, y
191
+ var el = arguments[0];
192
+ if (el.scrollBy){
193
+ el.scrollBy(arguments[1], arguments[2]);
194
+ } else {
195
+ el.scrollTop = el.scrollTop + arguments[2];
196
+ el.scrollLeft = el.scrollLeft + arguments[1];
197
+ }
198
+ JS
199
+ end
208
200
 
209
- def path
210
- command(:path)
211
- end
201
+ def ==(other)
202
+ node == other.native.node
203
+ end
212
204
 
213
- def inspect
214
- %(#<#{self.class} @node=#{@node.inspect}>)
215
- end
205
+ def send_keys(*keys)
206
+ command(:send_keys, keys)
207
+ end
208
+ alias send_key send_keys
216
209
 
217
- # @api private
218
- def to_json(*)
219
- JSON.generate(as_json)
220
- end
210
+ def path
211
+ command(:path)
212
+ end
221
213
 
222
- # @api private
223
- def as_json(*)
224
- # FIXME: Where is this method used and why attr is called id?
225
- { ELEMENT: { node: node, id: node.node_id } }
226
- end
214
+ def inspect
215
+ %(#<#{self.class} @node=#{@node.inspect}>)
216
+ end
227
217
 
228
- private
218
+ # @api private
219
+ def to_json(*)
220
+ JSON.generate(as_json)
221
+ end
229
222
 
230
- def prepare_and_click(mode, name, keys, options)
231
- delay = options[:delay].to_i
232
- x, y = options.values_at(:x, :y)
233
- offset = { x: x, y: y, position: options[:offset] || :top }
234
- command(:before_click, name, keys, offset)
235
- node.click(mode: mode, keys: keys, offset: offset, delay: delay)
236
- end
223
+ # @api private
224
+ def as_json(*)
225
+ # FIXME: Where is this method used and why attr is called id?
226
+ { ELEMENT: { node: node, id: node.node_id } }
227
+ end
228
+
229
+ private
237
230
 
238
- def filter_text(text)
239
- if Capybara::VERSION.to_f < 3
240
- Capybara::Helpers.normalize_whitespace(text.to_s)
241
- else
231
+ def prepare_and_click(mode, name, keys, options)
232
+ delay = options[:delay].to_i
233
+ x, y = options.values_at(:x, :y)
234
+ offset = { x: x, y: y, position: options[:offset] || :top }
235
+ command(:before_click, name, keys, offset)
236
+ node.click(mode: mode, keys: keys, offset: offset, delay: delay)
237
+ end
238
+
239
+ def filter_text(text)
242
240
  text.gsub(/[\u200b\u200e\u200f]/, "")
243
241
  .gsub(/[\ \n\f\t\v\u2028\u2029]+/, " ")
244
242
  .gsub(/\A[[:space:]&&[^\u00a0]]+/, "")
245
243
  .gsub(/[[:space:]&&[^\u00a0]]+\z/, "")
246
244
  .tr("\u00a0", " ")
247
245
  end
248
- end
249
246
 
250
- def scroll_element_to_location(element, location)
251
- scroll_opts = case location
252
- when :top
253
- 'true'
254
- when :bottom
255
- 'false'
256
- when :center
257
- "{behavior: 'instant', block: 'center'}"
258
- else
259
- raise ArgumentError, "Invalid scroll_to location: #{location}"
260
- end
261
- driver.execute_script <<~JS, element
262
- arguments[0].scrollIntoView(#{scroll_opts})
263
- JS
264
- end
247
+ def scroll_element_to_location(element, location)
248
+ scroll_opts = case location
249
+ when :top
250
+ "true"
251
+ when :bottom
252
+ "false"
253
+ when :center
254
+ "{behavior: 'instant', block: 'center'}"
255
+ else
256
+ raise ArgumentError, "Invalid scroll_to location: #{location}"
257
+ end
258
+ driver.execute_script <<~JS, element
259
+ arguments[0].scrollIntoView(#{scroll_opts})
260
+ JS
261
+ end
265
262
 
266
- def scroll_to_location(location)
267
- scroll_y = case location
268
- when :top
269
- '0'
270
- when :bottom
271
- 'arguments[0].scrollHeight'
272
- when :center
273
- '(arguments[0].scrollHeight - arguments[0].clientHeight)/2'
274
- end
275
- driver.execute_script <<~JS, self
276
- if (arguments[0].scrollTo){
277
- arguments[0].scrollTo(0, #{scroll_y});
278
- } else {
279
- arguments[0].scrollTop = #{scroll_y};
280
- }
281
- JS
282
- end
263
+ def scroll_to_location(location)
264
+ height = { top: "0",
265
+ bottom: "arguments[0].scrollHeight",
266
+ center: "(arguments[0].scrollHeight - arguments[0].clientHeight)/2" }
267
+
268
+ driver.execute_script <<~JS, self
269
+ if (arguments[0].scrollTo){
270
+ arguments[0].scrollTo(0, #{height[location]});
271
+ } else {
272
+ arguments[0].scrollTop = #{height[location]};
273
+ }
274
+ JS
275
+ end
283
276
 
284
- def scroll_to_coords(x, y)
285
- driver.execute_script <<~JS, self, x, y
286
- if (arguments[0].scrollTo){
287
- arguments[0].scrollTo(arguments[1], arguments[2]);
288
- } else {
289
- arguments[0].scrollTop = arguments[2];
290
- arguments[0].scrollLeft = arguments[1];
291
- }
292
- JS
277
+ def scroll_to_coords(x, y)
278
+ driver.execute_script <<~JS, self, x, y
279
+ if (arguments[0].scrollTo){
280
+ arguments[0].scrollTo(arguments[1], arguments[2]);
281
+ } else {
282
+ arguments[0].scrollTop = arguments[2];
283
+ arguments[0].scrollLeft = arguments[1];
284
+ }
285
+ JS
286
+ end
293
287
  end
294
288
  end
295
289
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ferrum
4
+ class Browser
5
+ class Options
6
+ attr_writer :window_size
7
+ attr_accessor :url_blacklist, :url_whitelist
8
+
9
+ def reset_window_size
10
+ @window_size = @options[:window_size]
11
+ end
12
+ end
13
+ end
14
+ end