cuprite 0.14.3 → 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.
- checksums.yaml +4 -4
- data/README.md +9 -9
- data/lib/capybara/cuprite/browser.rb +61 -30
- data/lib/capybara/cuprite/driver.rb +26 -18
- data/lib/capybara/cuprite/javascripts/index.js +45 -25
- data/lib/capybara/cuprite/node.rb +8 -4
- data/lib/capybara/cuprite/options.rb +14 -0
- data/lib/capybara/cuprite/page.rb +21 -32
- data/lib/capybara/cuprite/version.rb +1 -1
- data/lib/capybara/cuprite.rb +3 -0
- metadata +8 -133
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78b7dde58d02147e2985473da0a7527d338ff086e4a4aaf0fd9302e5faf3ee11
|
4
|
+
data.tar.gz: 777726c6161975950df923a305b0bdb9da54b5531b7a5339ed0d4beaf264beb6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04e88a47d9d2d2df68ad11dca8224f6d24001340b1743f538e6fdb64e818381037da7987b9db25284336b469c986d9d9e883192743749c4c6cad6c43adc160a1
|
7
|
+
data.tar.gz: a059dae9790af13c8a56999d6d76d5920e863e217b346a721a4051f0cc786e295a35c0e574c00e425b87e2d0c7a8b140c991183ab3246d1678566318745c9ecf
|
data/README.md
CHANGED
@@ -4,9 +4,7 @@ Cuprite is a pure Ruby driver (read as _no_ Selenium/WebDriver/ChromeDriver
|
|
4
4
|
dependency) for [Capybara](https://github.com/teamcapybara/capybara). It allows
|
5
5
|
you to run Capybara tests on a headless Chrome or Chromium. Under the hood it
|
6
6
|
uses [Ferrum](https://github.com/rubycdp/ferrum#index) which is high-level API
|
7
|
-
to the browser by CDP protocol.
|
8
|
-
[Poltergeist](https://github.com/teampoltergeist/poltergeist) as possible though
|
9
|
-
it's not a goal.
|
7
|
+
to the browser by CDP protocol.
|
10
8
|
|
11
9
|
|
12
10
|
## Install
|
@@ -43,8 +41,7 @@ browser = page.driver.browser
|
|
43
41
|
browser.mouse.move(x: 123, y: 456).down.up
|
44
42
|
```
|
45
43
|
|
46
|
-
|
47
|
-
Selenium you better check your code for `manage` calls because it works
|
44
|
+
For Selenium you better check your code for `manage` calls because it works
|
48
45
|
differently in Cuprite, see the documentation below.
|
49
46
|
|
50
47
|
|
@@ -64,8 +61,8 @@ end
|
|
64
61
|
`Cuprite`-specific options are:
|
65
62
|
|
66
63
|
* options `Hash`
|
67
|
-
* `:url_blacklist` (Array) - array of
|
68
|
-
* `:url_whitelist` (Array) - array of
|
64
|
+
* `:url_blacklist` (Array) - array of regexes to match against requested URLs
|
65
|
+
* `:url_whitelist` (Array) - array of regexes to match against requested URLs
|
69
66
|
|
70
67
|
|
71
68
|
## Debugging
|
@@ -183,6 +180,9 @@ Besides capybara screenshot method you can get image as Base64:
|
|
183
180
|
## Authorization
|
184
181
|
|
185
182
|
* `page.driver.basic_authorize(user, password)`
|
183
|
+
|
184
|
+
## Proxy
|
185
|
+
|
186
186
|
* `page.driver.set_proxy(ip, port, type, user, password)`
|
187
187
|
|
188
188
|
|
@@ -192,14 +192,14 @@ Cuprite supports URL blacklisting, which allows you to prevent scripts from
|
|
192
192
|
running on designated domains:
|
193
193
|
|
194
194
|
```ruby
|
195
|
-
page.driver.browser.url_blacklist =
|
195
|
+
page.driver.browser.url_blacklist = %r{http://www.example.com}
|
196
196
|
```
|
197
197
|
|
198
198
|
and also URL whitelisting, which allows scripts to only run on designated
|
199
199
|
domains:
|
200
200
|
|
201
201
|
```ruby
|
202
|
-
page.driver.browser.url_whitelist =
|
202
|
+
page.driver.browser.url_whitelist = %r{http://www.example.com}
|
203
203
|
```
|
204
204
|
|
205
205
|
If you are experiencing slower run times, consider creating a URL whitelist of
|
@@ -11,48 +11,65 @@ module Capybara
|
|
11
11
|
find_modal accept_confirm dismiss_confirm accept_prompt
|
12
12
|
dismiss_prompt reset_modals] => :page
|
13
13
|
|
14
|
-
attr_reader :url_blacklist, :url_whitelist
|
15
|
-
|
16
14
|
def initialize(options = nil)
|
17
|
-
options ||= {}
|
18
|
-
@client = nil
|
19
|
-
self.url_blacklist = options[:url_blacklist]
|
20
|
-
self.url_whitelist = options[:url_whitelist]
|
21
|
-
|
22
15
|
super
|
23
|
-
|
16
|
+
|
17
|
+
@options.url_blacklist = prepare_wildcards(options&.dig(:url_blacklist))
|
18
|
+
@options.url_whitelist = prepare_wildcards(options&.dig(:url_whitelist))
|
19
|
+
|
20
|
+
@page = nil
|
24
21
|
end
|
25
22
|
|
26
|
-
def
|
23
|
+
def command(...)
|
27
24
|
super
|
28
|
-
|
25
|
+
rescue Ferrum::DeadBrowserError
|
26
|
+
restart
|
27
|
+
raise
|
29
28
|
end
|
30
29
|
|
31
30
|
def page
|
32
|
-
raise Ferrum::NoSuchPageError if @page
|
31
|
+
raise Ferrum::NoSuchPageError if @page&.closed?
|
33
32
|
|
34
33
|
@page ||= attach_page
|
35
34
|
end
|
36
35
|
|
37
36
|
def reset
|
38
37
|
super
|
39
|
-
@
|
38
|
+
@options.reset_window_size
|
39
|
+
@page = nil
|
40
40
|
end
|
41
41
|
|
42
42
|
def quit
|
43
43
|
super
|
44
|
-
@page =
|
44
|
+
@page = nil
|
45
45
|
end
|
46
46
|
|
47
|
+
def resize(**options)
|
48
|
+
@options.window_size = [options[:width], options[:height]]
|
49
|
+
super
|
50
|
+
end
|
51
|
+
|
52
|
+
def url_whitelist
|
53
|
+
@options.url_whitelist
|
54
|
+
end
|
55
|
+
alias url_allowlist url_whitelist
|
56
|
+
|
47
57
|
def url_whitelist=(patterns)
|
48
|
-
@url_whitelist = prepare_wildcards(patterns)
|
49
|
-
page.network.
|
58
|
+
@options.url_whitelist = prepare_wildcards(patterns)
|
59
|
+
page.network.whitelist = @options.url_whitelist if @client && @options.url_whitelist.any?
|
60
|
+
end
|
61
|
+
alias url_allowlist= url_whitelist=
|
62
|
+
|
63
|
+
def url_blacklist
|
64
|
+
@options.url_blacklist
|
50
65
|
end
|
66
|
+
alias url_blocklist url_blacklist
|
51
67
|
|
52
68
|
def url_blacklist=(patterns)
|
53
|
-
@url_blacklist = prepare_wildcards(patterns)
|
54
|
-
page.network.
|
69
|
+
@options.url_blacklist = prepare_wildcards(patterns)
|
70
|
+
page.network.blacklist = @options.url_blacklist if @client && @options.url_blacklist.any?
|
55
71
|
end
|
72
|
+
alias url_blocklist= url_blacklist=
|
56
73
|
|
57
74
|
def visit(*args)
|
58
75
|
goto(*args)
|
@@ -105,8 +122,13 @@ module Capybara
|
|
105
122
|
target = targets[target_id]
|
106
123
|
raise Ferrum::NoSuchPageError unless target
|
107
124
|
|
108
|
-
@page =
|
125
|
+
@page = ClosedPage.new if @page.target_id == target.id
|
109
126
|
target.page.close
|
127
|
+
targets.delete(target_id) # page.close is async, delete target asap
|
128
|
+
end
|
129
|
+
|
130
|
+
def active_element
|
131
|
+
evaluate("document.activeElement")
|
110
132
|
end
|
111
133
|
|
112
134
|
def browser_error
|
@@ -117,24 +139,26 @@ module Capybara
|
|
117
139
|
raise NotImplementedError
|
118
140
|
end
|
119
141
|
|
120
|
-
def drag(node, other)
|
142
|
+
def drag(node, other, steps, delay = nil)
|
121
143
|
x1, y1 = node.find_position
|
122
144
|
x2, y2 = other.find_position
|
123
145
|
|
124
146
|
mouse.move(x: x1, y: y1)
|
125
147
|
mouse.down
|
126
|
-
|
148
|
+
sleep delay if delay
|
149
|
+
mouse.move(x: x2, y: y2, steps: steps)
|
127
150
|
mouse.up
|
128
151
|
end
|
129
152
|
|
130
|
-
def drag_by(node, x, y)
|
153
|
+
def drag_by(node, x, y, steps, delay = nil)
|
131
154
|
x1, y1 = node.find_position
|
132
155
|
x2 = x1 + x
|
133
156
|
y2 = y1 + y
|
134
157
|
|
135
158
|
mouse.move(x: x1, y: y1)
|
136
159
|
mouse.down
|
137
|
-
|
160
|
+
sleep delay if delay
|
161
|
+
mouse.move(x: x2, y: y2, steps: steps)
|
138
162
|
mouse.up
|
139
163
|
end
|
140
164
|
|
@@ -199,24 +223,31 @@ module Capybara
|
|
199
223
|
raise
|
200
224
|
end
|
201
225
|
|
202
|
-
def prepare_wildcards(
|
203
|
-
|
204
|
-
|
205
|
-
|
226
|
+
def prepare_wildcards(patterns)
|
227
|
+
string_passed = false
|
228
|
+
|
229
|
+
Array(patterns).map do |pattern|
|
230
|
+
if pattern.is_a?(Regexp)
|
231
|
+
pattern
|
206
232
|
else
|
207
|
-
|
208
|
-
|
233
|
+
string_passed = true
|
234
|
+
pattern = pattern.gsub("*", ".*")
|
235
|
+
Regexp.new(pattern, Regexp::IGNORECASE)
|
209
236
|
end
|
210
237
|
end
|
238
|
+
ensure
|
239
|
+
if string_passed
|
240
|
+
warn "Passing strings to blacklist/whitelist is deprecated, pass regexp at #{caller(4..4).first}"
|
241
|
+
end
|
211
242
|
end
|
212
243
|
|
213
244
|
def attach_page(target_id = nil)
|
214
245
|
target = targets[target_id] if target_id
|
215
246
|
target ||= default_context.default_target
|
216
|
-
return target.page if target.
|
247
|
+
return target.page if target.connected?
|
217
248
|
|
218
249
|
target.maybe_sleep_if_new_window
|
219
|
-
target.page = Page.new(target.
|
250
|
+
target.page = Page.new(target.client, context_id: target.context_id, target_id: target.id)
|
220
251
|
target.page
|
221
252
|
end
|
222
253
|
end
|
@@ -3,9 +3,9 @@
|
|
3
3
|
require "uri"
|
4
4
|
require "forwardable"
|
5
5
|
|
6
|
+
# rubocop:disable Metrics/ClassLength
|
6
7
|
module Capybara
|
7
8
|
module Cuprite
|
8
|
-
# rubocop:disable Metrics/ClassLength
|
9
9
|
class Driver < Capybara::Driver::Base
|
10
10
|
DEFAULT_MAXIMIZE_SCREEN_SIZE = [1366, 768].freeze
|
11
11
|
EXTENSION = File.expand_path("javascripts/index.js", __dir__)
|
@@ -14,7 +14,8 @@ module Capybara
|
|
14
14
|
|
15
15
|
delegate %i[restart quit status_code timeout timeout= current_url title body
|
16
16
|
window_handles close_window switch_to_window within_window window_handle
|
17
|
-
back forward refresh wait_for_reload] => :browser
|
17
|
+
back forward refresh wait_for_reload viewport_size device_pixel_ratio] => :browser
|
18
|
+
delegate %i[send_keys] => :active_element
|
18
19
|
alias html body
|
19
20
|
alias current_window_handle window_handle
|
20
21
|
alias go_back back
|
@@ -32,10 +33,13 @@ module Capybara
|
|
32
33
|
|
33
34
|
@screen_size = @options.delete(:screen_size)
|
34
35
|
@screen_size ||= DEFAULT_MAXIMIZE_SCREEN_SIZE
|
36
|
+
@options[:save_path] ||= File.expand_path(Capybara.save_path) if Capybara.save_path
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
# It's set for debug() to make devtools tab open correctly.
|
39
|
+
@options[:browser_options] ||= {}
|
40
|
+
unless @options[:browser_options][:"remote-allow-origins"]
|
41
|
+
@options[:browser_options].merge!("remote-allow-origins": "*")
|
42
|
+
end
|
39
43
|
|
40
44
|
super()
|
41
45
|
end
|
@@ -65,6 +69,10 @@ module Capybara
|
|
65
69
|
evaluate_script("document.title")
|
66
70
|
end
|
67
71
|
|
72
|
+
def active_element
|
73
|
+
Node.new(self, browser.active_element)
|
74
|
+
end
|
75
|
+
|
68
76
|
def find_xpath(selector)
|
69
77
|
find(:xpath, selector)
|
70
78
|
end
|
@@ -110,7 +118,7 @@ module Capybara
|
|
110
118
|
def open_new_window
|
111
119
|
target = browser.default_context.create_target
|
112
120
|
target.maybe_sleep_if_new_window
|
113
|
-
target.page = Page.new(target.
|
121
|
+
target.page = Page.new(target.client, context_id: target.context_id, target_id: target.id)
|
114
122
|
target.page
|
115
123
|
end
|
116
124
|
|
@@ -206,16 +214,7 @@ module Capybara
|
|
206
214
|
end
|
207
215
|
|
208
216
|
def set_proxy(host, port, user = nil, password = nil, bypass = nil)
|
209
|
-
|
210
|
-
browser_options = browser_options.merge("proxy-server" => "#{host}:#{port}")
|
211
|
-
browser_options = browser_options.merge("proxy-bypass-list" => bypass) if bypass
|
212
|
-
@options[:browser_options] = browser_options
|
213
|
-
|
214
|
-
return unless user && password
|
215
|
-
|
216
|
-
browser.network.authorize(user: user, password: password, type: :proxy) do |request, _index, _total|
|
217
|
-
request.continue
|
218
|
-
end
|
217
|
+
@options.merge!(proxy: { host: host, port: port, user: user, password: password, bypass: bypass })
|
219
218
|
end
|
220
219
|
|
221
220
|
def headers
|
@@ -275,7 +274,12 @@ module Capybara
|
|
275
274
|
alias authorize basic_authorize
|
276
275
|
|
277
276
|
def debug_url
|
278
|
-
|
277
|
+
response = JSON.parse(Net::HTTP.get(URI(build_remote_debug_url(path: "/json"))))
|
278
|
+
|
279
|
+
devtools_frontend_path = response[0]&.[]("devtoolsFrontendUrl")
|
280
|
+
raise "Could not generate debug url for remote debugging session" unless devtools_frontend_path
|
281
|
+
|
282
|
+
build_remote_debug_url(path: devtools_frontend_path)
|
279
283
|
end
|
280
284
|
|
281
285
|
def debug(binding = nil)
|
@@ -373,6 +377,10 @@ module Capybara
|
|
373
377
|
|
374
378
|
private
|
375
379
|
|
380
|
+
def build_remote_debug_url(path:)
|
381
|
+
"http://#{browser.process.host}:#{browser.process.port}#{path}"
|
382
|
+
end
|
383
|
+
|
376
384
|
def default_domain
|
377
385
|
if @started
|
378
386
|
URI.parse(browser.current_url).host
|
@@ -423,6 +431,6 @@ module Capybara
|
|
423
431
|
options[:format].to_s == "pdf"
|
424
432
|
end
|
425
433
|
end
|
426
|
-
# rubocop:enable Metrics/ClassLength
|
427
434
|
end
|
428
435
|
end
|
436
|
+
# rubocop:enable Metrics/ClassLength
|
@@ -84,7 +84,6 @@ class Cuprite {
|
|
84
84
|
return true;
|
85
85
|
}
|
86
86
|
|
87
|
-
|
88
87
|
isDisabled(node) {
|
89
88
|
let xpath = "parent::optgroup[@disabled] | \
|
90
89
|
ancestor::select[@disabled] | \
|
@@ -151,7 +150,7 @@ class Cuprite {
|
|
151
150
|
// call the following functions in order, if one returns false (preventDefault),
|
152
151
|
// stop the call chain
|
153
152
|
[
|
154
|
-
() => this.keyupdowned(node, "keydown", keyCode),
|
153
|
+
() => this.keyupdowned(node, "keydown", char, keyCode),
|
155
154
|
() => this.keypressed(node, false, false, false, false, char.charCodeAt(0), char.charCodeAt(0)),
|
156
155
|
() => {
|
157
156
|
this.setValue(node, node.value + char)
|
@@ -159,7 +158,7 @@ class Cuprite {
|
|
159
158
|
}
|
160
159
|
].some(fn => fn())
|
161
160
|
|
162
|
-
this.keyupdowned(node, "keyup", keyCode);
|
161
|
+
this.keyupdowned(node, "keyup", char, keyCode);
|
163
162
|
}
|
164
163
|
}
|
165
164
|
|
@@ -180,19 +179,22 @@ class Cuprite {
|
|
180
179
|
}
|
181
180
|
|
182
181
|
input(node) {
|
183
|
-
let event =
|
184
|
-
event.initEvent("input", true, false);
|
182
|
+
let event = new InputEvent("input", { inputType: "insertText", bubbles: true, cancelable: false });
|
185
183
|
node.dispatchEvent(event);
|
186
184
|
}
|
187
185
|
|
188
186
|
/**
|
189
187
|
* @return {boolean} false when an event handler called preventDefault()
|
190
188
|
*/
|
191
|
-
keyupdowned(node, eventName, keyCode) {
|
192
|
-
let event =
|
193
|
-
|
194
|
-
|
195
|
-
|
189
|
+
keyupdowned(node, eventName, char, keyCode) {
|
190
|
+
let event = new KeyboardEvent(
|
191
|
+
eventName, {
|
192
|
+
bubbles: true,
|
193
|
+
cancelable: true,
|
194
|
+
key: char,
|
195
|
+
keyCode: keyCode
|
196
|
+
}
|
197
|
+
);
|
196
198
|
return !node.dispatchEvent(event);
|
197
199
|
}
|
198
200
|
|
@@ -200,15 +202,18 @@ class Cuprite {
|
|
200
202
|
* @return {boolean} false when an event handler called preventDefault()
|
201
203
|
*/
|
202
204
|
keypressed(node, altKey, ctrlKey, shiftKey, metaKey, keyCode, charCode) {
|
203
|
-
event =
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
205
|
+
let event = new KeyboardEvent(
|
206
|
+
"keypress", {
|
207
|
+
bubbles: true,
|
208
|
+
cancelable: true,
|
209
|
+
altKey: altKey,
|
210
|
+
ctrlKey: ctrlKey,
|
211
|
+
shiftKey: shiftKey,
|
212
|
+
metaKey: metaKey,
|
213
|
+
keyCode: keyCode,
|
214
|
+
charCode: charCode
|
215
|
+
}
|
216
|
+
);
|
212
217
|
return !node.dispatchEvent(event);
|
213
218
|
}
|
214
219
|
|
@@ -338,10 +343,24 @@ class Cuprite {
|
|
338
343
|
|
339
344
|
_isInViewport(node) {
|
340
345
|
let rect = node.getBoundingClientRect();
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
346
|
+
|
347
|
+
let inViewport = rect.top >= 0 &&
|
348
|
+
rect.left >= 0 &&
|
349
|
+
rect.bottom <= window.innerHeight &&
|
350
|
+
rect.right <= window.innerWidth;
|
351
|
+
|
352
|
+
if (inViewport) {
|
353
|
+
// check if obscured by another element
|
354
|
+
let x = rect.width/2;
|
355
|
+
let y = rect.height/2 ;
|
356
|
+
|
357
|
+
let px = rect.left + x,
|
358
|
+
py = rect.top + y,
|
359
|
+
e = document.elementFromPoint(px, py);
|
360
|
+
return node == e;
|
361
|
+
}
|
362
|
+
|
363
|
+
return false;
|
345
364
|
}
|
346
365
|
|
347
366
|
select(node, value) {
|
@@ -350,12 +369,13 @@ class Cuprite {
|
|
350
369
|
} else if (value == false && !node.parentNode.multiple) {
|
351
370
|
return false;
|
352
371
|
} else {
|
353
|
-
|
372
|
+
let parentNode = node.parentNode;
|
373
|
+
this.trigger(parentNode, "focus");
|
354
374
|
|
355
375
|
node.selected = value;
|
356
376
|
this.changed(node);
|
357
377
|
|
358
|
-
this.trigger(
|
378
|
+
this.trigger(parentNode, "blur");
|
359
379
|
return true;
|
360
380
|
}
|
361
381
|
}
|
@@ -159,12 +159,16 @@ module Capybara
|
|
159
159
|
command(:hover)
|
160
160
|
end
|
161
161
|
|
162
|
-
def drag_to(other)
|
163
|
-
|
162
|
+
def drag_to(other, **options)
|
163
|
+
options[:steps] ||= 1
|
164
|
+
|
165
|
+
command(:drag, other.node, options[:steps], options[:delay])
|
164
166
|
end
|
165
167
|
|
166
|
-
def drag_by(x, y)
|
167
|
-
|
168
|
+
def drag_by(x, y, **options)
|
169
|
+
options[:steps] ||= 1
|
170
|
+
|
171
|
+
command(:drag_by, x, y, options[:steps], options[:delay])
|
168
172
|
end
|
169
173
|
|
170
174
|
def trigger(event)
|
@@ -4,6 +4,12 @@ require "forwardable"
|
|
4
4
|
|
5
5
|
module Capybara
|
6
6
|
module Cuprite
|
7
|
+
class ClosedPage
|
8
|
+
def closed?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
7
13
|
class Page < Ferrum::Page
|
8
14
|
MODAL_WAIT = ENV.fetch("CUPRITE_MODAL_WAIT", 0.05).to_f
|
9
15
|
TRIGGER_CLICK_WAIT = ENV.fetch("CUPRITE_TRIGGER_CLICK_WAIT", 0.1).to_f
|
@@ -13,10 +19,11 @@ module Capybara
|
|
13
19
|
current_url current_title body execution_id execution_id!
|
14
20
|
evaluate evaluate_on evaluate_async execute] => :active_frame
|
15
21
|
|
16
|
-
def initialize(
|
22
|
+
def initialize(...)
|
17
23
|
@frame_stack = []
|
18
24
|
@accept_modal = []
|
19
25
|
@modal_messages = []
|
26
|
+
@modal_response = nil
|
20
27
|
super
|
21
28
|
end
|
22
29
|
|
@@ -69,17 +76,17 @@ module Capybara
|
|
69
76
|
|
70
77
|
def find_modal(options)
|
71
78
|
start = Ferrum::Utils::ElapsedTime.monotonic_time
|
72
|
-
timeout = options.fetch(:wait, browser.timeout)
|
73
79
|
expect_text = options[:text]
|
74
80
|
expect_regexp = expect_text.is_a?(Regexp) ? expect_text : Regexp.escape(expect_text.to_s)
|
75
81
|
not_found_msg = "Unable to find modal dialog"
|
76
82
|
not_found_msg += " with #{expect_text}" if expect_text
|
83
|
+
wait = options.fetch(:wait, timeout)
|
77
84
|
|
78
85
|
begin
|
79
86
|
modal_text = @modal_messages.shift
|
80
87
|
raise Capybara::ModalNotFound if modal_text.nil? || (expect_text && !modal_text.match(expect_regexp))
|
81
88
|
rescue Capybara::ModalNotFound => e
|
82
|
-
raise e, not_found_msg if Ferrum::Utils::ElapsedTime.timeout?(start,
|
89
|
+
raise e, not_found_msg if Ferrum::Utils::ElapsedTime.timeout?(start, wait)
|
83
90
|
|
84
91
|
sleep(MODAL_WAIT)
|
85
92
|
retry
|
@@ -128,37 +135,22 @@ module Capybara
|
|
128
135
|
active_frame.current_title
|
129
136
|
end
|
130
137
|
|
138
|
+
def closed?
|
139
|
+
false
|
140
|
+
end
|
141
|
+
|
131
142
|
private
|
132
143
|
|
133
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
134
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
135
|
-
# rubocop:disable Style/GuardClause
|
136
144
|
def prepare_page
|
137
145
|
super
|
138
146
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
else
|
147
|
-
request.continue and next
|
148
|
-
end
|
149
|
-
elsif @browser.url_whitelist && !@browser.url_whitelist.empty?
|
150
|
-
if @browser.url_whitelist.any? { |r| request.match?(r) }
|
151
|
-
request.continue and next
|
152
|
-
else
|
153
|
-
request.abort and next
|
154
|
-
end
|
155
|
-
elsif index + 1 < total
|
156
|
-
# There are other callbacks that may handle this request
|
157
|
-
next
|
158
|
-
else
|
159
|
-
# If there are no callbacks then just continue
|
160
|
-
request.continue
|
161
|
-
end
|
147
|
+
width, height = @options.window_size
|
148
|
+
resize(width: width, height: height)
|
149
|
+
|
150
|
+
if @options.url_blacklist.any?
|
151
|
+
network.blacklist = @options.url_blacklist
|
152
|
+
elsif @options.url_whitelist.any?
|
153
|
+
network.whitelist = @options.url_whitelist
|
162
154
|
end
|
163
155
|
|
164
156
|
on("Page.javascriptDialogOpening") do |params|
|
@@ -181,9 +173,6 @@ module Capybara
|
|
181
173
|
command("Page.handleJavaScriptDialog", **options)
|
182
174
|
end
|
183
175
|
end
|
184
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
185
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
186
|
-
# rubocop:enable Style/GuardClause
|
187
176
|
|
188
177
|
def find_position(node, **options)
|
189
178
|
node.find_position(**options)
|
data/lib/capybara/cuprite.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
ENV["FERRUM_DEBUG"] = "true" if ENV["CUPRITE_DEBUG"]
|
4
|
+
|
3
5
|
require "ferrum"
|
4
6
|
require "capybara"
|
5
7
|
require "capybara/cuprite/driver"
|
6
8
|
require "capybara/cuprite/browser"
|
7
9
|
require "capybara/cuprite/page"
|
10
|
+
require "capybara/cuprite/options"
|
8
11
|
require "capybara/cuprite/node"
|
9
12
|
require "capybara/cuprite/errors"
|
10
13
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cuprite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dmitry Vorotilin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capybara
|
@@ -30,140 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.15.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: byebug
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '11.1'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '11.1'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: chunky_png
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '1.4'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '1.4'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: image_size
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '3.0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '3.0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: launchy
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '2.5'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '2.5'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: pdf-reader
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '2.5'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '2.5'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: puma
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - "~>"
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '4.3'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - "~>"
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '4.3'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: rake
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - "~>"
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '13.0'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - "~>"
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '13.0'
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
|
-
name: rspec
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - "~>"
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: '3.10'
|
146
|
-
type: :development
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - "~>"
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: '3.10'
|
153
|
-
- !ruby/object:Gem::Dependency
|
154
|
-
name: sinatra
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
156
|
-
requirements:
|
157
|
-
- - "~>"
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
version: '2.1'
|
160
|
-
type: :development
|
161
|
-
prerelease: false
|
162
|
-
version_requirements: !ruby/object:Gem::Requirement
|
163
|
-
requirements:
|
164
|
-
- - "~>"
|
165
|
-
- !ruby/object:Gem::Version
|
166
|
-
version: '2.1'
|
40
|
+
version: 0.15.0
|
167
41
|
description: Cuprite is a driver for Capybara that allows you to run your tests on
|
168
42
|
a headless Chrome browser
|
169
43
|
email:
|
@@ -181,6 +55,7 @@ files:
|
|
181
55
|
- lib/capybara/cuprite/errors.rb
|
182
56
|
- lib/capybara/cuprite/javascripts/index.js
|
183
57
|
- lib/capybara/cuprite/node.rb
|
58
|
+
- lib/capybara/cuprite/options.rb
|
184
59
|
- lib/capybara/cuprite/page.rb
|
185
60
|
- lib/capybara/cuprite/version.rb
|
186
61
|
homepage: https://github.com/rubycdp/cuprite
|
@@ -189,7 +64,7 @@ licenses:
|
|
189
64
|
metadata:
|
190
65
|
homepage_uri: https://cuprite.rubycdp.com/
|
191
66
|
bug_tracker_uri: https://github.com/rubycdp/cuprite/issues
|
192
|
-
documentation_uri: https://github.com/rubycdp/cuprite/blob/
|
67
|
+
documentation_uri: https://github.com/rubycdp/cuprite/blob/main/README.md
|
193
68
|
source_code_uri: https://github.com/rubycdp/cuprite
|
194
69
|
rubygems_mfa_required: 'true'
|
195
70
|
post_install_message:
|
@@ -200,14 +75,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
200
75
|
requirements:
|
201
76
|
- - ">="
|
202
77
|
- !ruby/object:Gem::Version
|
203
|
-
version: 2.
|
78
|
+
version: 2.7.0
|
204
79
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
205
80
|
requirements:
|
206
81
|
- - ">="
|
207
82
|
- !ruby/object:Gem::Version
|
208
83
|
version: '0'
|
209
84
|
requirements: []
|
210
|
-
rubygems_version: 3.
|
85
|
+
rubygems_version: 3.5.11
|
211
86
|
signing_key:
|
212
87
|
specification_version: 4
|
213
88
|
summary: Headless Chrome driver for Capybara
|