cuprite 0.19 → 0.20
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 +43 -41
- data/lib/capybara/cuprite/browser/deprecations.rb +26 -0
- data/lib/capybara/cuprite/browser/extensions.rb +59 -0
- data/lib/capybara/cuprite/browser.rb +18 -232
- data/lib/capybara/cuprite/deprecation.rb +13 -0
- data/lib/capybara/cuprite/driver/deprecations.rb +198 -0
- data/lib/capybara/cuprite/driver/extensions.rb +13 -0
- data/lib/capybara/cuprite/driver.rb +66 -201
- data/lib/capybara/cuprite/finder.rb +22 -0
- data/lib/capybara/cuprite/javascripts/drag.js +96 -101
- data/lib/capybara/cuprite/javascripts/index.js +507 -508
- data/lib/capybara/cuprite/node/deprecations.rb +43 -0
- data/lib/capybara/cuprite/node/extensions.rb +27 -0
- data/lib/capybara/cuprite/node.rb +130 -116
- data/lib/capybara/cuprite/options.rb +1 -1
- data/lib/capybara/cuprite/page/frames.rb +47 -0
- data/lib/capybara/cuprite/page/modals.rb +118 -0
- data/lib/capybara/cuprite/page.rb +6 -209
- data/lib/capybara/cuprite/version.rb +1 -1
- metadata +15 -6
- data/lib/capybara/cuprite/cookie.rb +0 -47
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "uri"
|
|
4
|
+
require "capybara/cuprite/deprecation"
|
|
5
|
+
|
|
6
|
+
module Capybara
|
|
7
|
+
module Cuprite
|
|
8
|
+
class Driver < Capybara::Driver::Base
|
|
9
|
+
module Deprecations
|
|
10
|
+
def self.deprecate(name, replacement)
|
|
11
|
+
define_method(name) do |*args, **kwargs, &block|
|
|
12
|
+
Cuprite.deprecation_warning("#{self.class}##{name}", "use ##{replacement}")
|
|
13
|
+
public_send(replacement, *args, **kwargs, &block)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
private_class_method :deprecate
|
|
17
|
+
|
|
18
|
+
deprecate :body, :html
|
|
19
|
+
deprecate :window_handle, :current_window_handle
|
|
20
|
+
deprecate :back, :go_back
|
|
21
|
+
deprecate :forward, :go_forward
|
|
22
|
+
deprecate :render, :save_screenshot
|
|
23
|
+
|
|
24
|
+
def render_base64(format = :png, options = {})
|
|
25
|
+
Cuprite.deprecation_warning("#{self.class}#render_base64", "use page.driver.browser.screenshot or .pdf")
|
|
26
|
+
browser.screenshot(format: format, encoding: :base64, **options)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def zoom_factor=(value)
|
|
30
|
+
Cuprite.deprecation_warning("#{self.class}#zoom_factor=", "pass scale: to save_screenshot")
|
|
31
|
+
@zoom_factor = value.to_f
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def paper_size=(value)
|
|
35
|
+
Cuprite.deprecation_warning("#{self.class}#paper_size=",
|
|
36
|
+
"pass paper_width: and paper_height: to save_screenshot")
|
|
37
|
+
@paper_size = value
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def resize(width, height)
|
|
41
|
+
Cuprite.deprecation_warning("#{self.class}##{__callee__}", "use page.current_window.resize_to")
|
|
42
|
+
resize_window_to(current_window_handle, width, height)
|
|
43
|
+
end
|
|
44
|
+
alias resize_window resize
|
|
45
|
+
|
|
46
|
+
def click(x, y)
|
|
47
|
+
Cuprite.deprecation_warning("#{self.class}#click", "use page.driver.browser.mouse.click")
|
|
48
|
+
browser.mouse.click(x: x, y: y)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def scroll_to(left, top)
|
|
52
|
+
Cuprite.deprecation_warning("#{self.class}#scroll_to", "use page.scroll_to")
|
|
53
|
+
browser.mouse.scroll_to(left, top)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def set_proxy(host, port, user = nil, password = nil, bypass = nil)
|
|
57
|
+
Cuprite.deprecation_warning("#{self.class}#set_proxy", "pass the :proxy option to the driver")
|
|
58
|
+
@options.merge!(proxy: { host: host, port: port, user: user, password: password, bypass: bypass })
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def restart
|
|
62
|
+
Cuprite.deprecation_warning("#{self.class}#restart", "use page.driver.browser.restart")
|
|
63
|
+
browser.restart
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def wait_for_reload(timeout = 1)
|
|
67
|
+
Cuprite.deprecation_warning("#{self.class}#wait_for_reload", "use page.driver.browser.wait_for_reload")
|
|
68
|
+
browser.wait_for_reload(timeout)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def timeout
|
|
72
|
+
Cuprite.deprecation_warning("#{self.class}#timeout", "use page.driver.browser.timeout")
|
|
73
|
+
browser.timeout
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def timeout=(value)
|
|
77
|
+
Cuprite.deprecation_warning("#{self.class}#timeout=", "use page.driver.browser.timeout=")
|
|
78
|
+
browser.timeout = value
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def device_pixel_ratio
|
|
82
|
+
Cuprite.deprecation_warning("#{self.class}#device_pixel_ratio", "use page.driver.browser.device_pixel_ratio")
|
|
83
|
+
browser.device_pixel_ratio
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def viewport_size
|
|
87
|
+
Cuprite.deprecation_warning("#{self.class}#viewport_size", "use page.driver.browser.viewport_size")
|
|
88
|
+
browser.viewport_size
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def authorize(user, password)
|
|
92
|
+
Cuprite.deprecation_warning("#{self.class}##{__callee__}", "use page.driver.browser.network.authorize")
|
|
93
|
+
browser.network.authorize(user: user, password: password) do |request, _index, _total|
|
|
94
|
+
request.continue
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
alias basic_authorize authorize
|
|
98
|
+
|
|
99
|
+
def headers
|
|
100
|
+
Cuprite.deprecation_warning("#{self.class}#headers", "use page.driver.browser.headers.get")
|
|
101
|
+
browser.headers.get
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def headers=(headers)
|
|
105
|
+
Cuprite.deprecation_warning("#{self.class}#headers=", "use page.driver.browser.headers.set")
|
|
106
|
+
browser.headers.set(headers)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def add_headers(headers)
|
|
110
|
+
Cuprite.deprecation_warning("#{self.class}#add_headers", "use page.driver.browser.headers.add")
|
|
111
|
+
browser.headers.add(headers)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def add_header(name, value, permanent: true)
|
|
115
|
+
Cuprite.deprecation_warning("#{self.class}#add_header", "use page.driver.browser.headers.add")
|
|
116
|
+
browser.headers.add({ name => value }, permanent: permanent)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def cookies
|
|
120
|
+
Cuprite.deprecation_warning("#{self.class}#cookies", "use page.driver.browser.cookies.all")
|
|
121
|
+
browser.cookies.all
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def set_cookie(name, value, options = {})
|
|
125
|
+
Cuprite.deprecation_warning("#{self.class}#set_cookie", "use page.driver.browser.cookies.set")
|
|
126
|
+
options = options.dup
|
|
127
|
+
options[:name] ||= name
|
|
128
|
+
options[:value] ||= value
|
|
129
|
+
options[:domain] ||= default_domain
|
|
130
|
+
browser.cookies.set(**options)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def remove_cookie(name, **options)
|
|
134
|
+
Cuprite.deprecation_warning("#{self.class}#remove_cookie", "use page.driver.browser.cookies.remove")
|
|
135
|
+
options[:domain] = default_domain if options.empty?
|
|
136
|
+
options = options.merge(name: name)
|
|
137
|
+
browser.cookies.remove(**options)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def clear_cookies
|
|
141
|
+
Cuprite.deprecation_warning("#{self.class}#clear_cookies", "use page.driver.browser.cookies.clear")
|
|
142
|
+
browser.cookies.clear
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def network_traffic(type = nil)
|
|
146
|
+
Cuprite.deprecation_warning("#{self.class}#network_traffic", "use page.driver.browser.network.traffic")
|
|
147
|
+
traffic = browser.network.traffic
|
|
148
|
+
|
|
149
|
+
case type.to_s
|
|
150
|
+
when "all"
|
|
151
|
+
traffic
|
|
152
|
+
when "blocked"
|
|
153
|
+
traffic.select(&:blocked?)
|
|
154
|
+
else
|
|
155
|
+
# when request isn't blocked
|
|
156
|
+
traffic.reject(&:blocked?)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def clear_network_traffic
|
|
161
|
+
Cuprite.deprecation_warning("#{self.class}#clear_network_traffic",
|
|
162
|
+
"use page.driver.browser.network.clear(:traffic)")
|
|
163
|
+
browser.network.clear(:traffic)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def wait_for_network_idle(**options)
|
|
167
|
+
Cuprite.deprecation_warning("#{self.class}#wait_for_network_idle",
|
|
168
|
+
"use page.driver.browser.network.wait_for_idle")
|
|
169
|
+
browser.network.wait_for_idle(**options)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def clear_memory_cache
|
|
173
|
+
Cuprite.deprecation_warning("#{self.class}#clear_memory_cache",
|
|
174
|
+
"use page.driver.browser.network.clear(:cache)")
|
|
175
|
+
browser.network.clear(:cache)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
private
|
|
179
|
+
|
|
180
|
+
def default_domain
|
|
181
|
+
if @started
|
|
182
|
+
URI.parse(browser.current_url).host
|
|
183
|
+
else
|
|
184
|
+
URI.parse(default_cookie_host).host || "127.0.0.1"
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def default_cookie_host
|
|
189
|
+
if respond_to?(:session_options)
|
|
190
|
+
session_options.app_host
|
|
191
|
+
else
|
|
192
|
+
Capybara.app_host
|
|
193
|
+
end || ""
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
@@ -1,27 +1,42 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "uri"
|
|
4
3
|
require "forwardable"
|
|
4
|
+
require "capybara/cuprite/finder"
|
|
5
|
+
require "capybara/cuprite/driver/deprecations"
|
|
6
|
+
require "capybara/cuprite/driver/extensions"
|
|
5
7
|
|
|
6
|
-
# rubocop:disable-next Metrics/ClassLength
|
|
7
8
|
module Capybara
|
|
8
9
|
module Cuprite
|
|
9
10
|
class Driver < Capybara::Driver::Base
|
|
10
11
|
DEFAULT_MAXIMIZE_SCREEN_SIZE = [1366, 768].freeze
|
|
11
12
|
EXTENSION = File.expand_path("javascripts/index.js", __dir__)
|
|
13
|
+
CALLBACK_JS = <<~JS
|
|
14
|
+
function(...args) {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
try {
|
|
17
|
+
(function() {
|
|
18
|
+
SCRIPT
|
|
19
|
+
}).apply(this, [...args, resolve]);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
reject(error);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
JS
|
|
12
26
|
|
|
13
27
|
extend Forwardable
|
|
28
|
+
include Deprecations
|
|
29
|
+
include Extensions
|
|
14
30
|
|
|
15
|
-
delegate %i[
|
|
16
|
-
window_handles close_window switch_to_window
|
|
17
|
-
|
|
31
|
+
delegate %i[quit current_url title
|
|
32
|
+
window_handles current_window_handle close_window switch_to_window
|
|
33
|
+
refresh] => :browser
|
|
18
34
|
delegate %i[send_keys] => :active_element
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
alias go_forward forward
|
|
35
|
+
def_delegator :browser, :body, :html
|
|
36
|
+
def_delegator :browser, :back, :go_back
|
|
37
|
+
def_delegator :browser, :forward, :go_forward
|
|
23
38
|
|
|
24
|
-
attr_reader :app, :options
|
|
39
|
+
attr_reader :app, :options
|
|
25
40
|
|
|
26
41
|
def initialize(app, options = {})
|
|
27
42
|
@app = app
|
|
@@ -52,20 +67,21 @@ module Capybara
|
|
|
52
67
|
end
|
|
53
68
|
|
|
54
69
|
def browser
|
|
55
|
-
@browser ||= Browser.new(@options)
|
|
70
|
+
@browser ||= Browser.new({ base_url: capybara_base_url }.compact.merge(@options))
|
|
56
71
|
end
|
|
57
72
|
|
|
58
73
|
def visit(url)
|
|
59
74
|
@started = true
|
|
60
|
-
browser.
|
|
75
|
+
browser.base_url = url if url.match?(%r{\Ahttps?://})
|
|
76
|
+
browser.goto(url)
|
|
61
77
|
end
|
|
62
78
|
|
|
63
|
-
def
|
|
64
|
-
|
|
79
|
+
def status_code
|
|
80
|
+
browser.network.status
|
|
65
81
|
end
|
|
66
82
|
|
|
67
|
-
def
|
|
68
|
-
|
|
83
|
+
def frame_url
|
|
84
|
+
evaluate_script("window.location.href")
|
|
69
85
|
end
|
|
70
86
|
|
|
71
87
|
def frame_title
|
|
@@ -73,7 +89,7 @@ module Capybara
|
|
|
73
89
|
end
|
|
74
90
|
|
|
75
91
|
def active_element
|
|
76
|
-
Node.new(self, browser.
|
|
92
|
+
Node.new(self, browser.evaluate("document.activeElement"))
|
|
77
93
|
end
|
|
78
94
|
|
|
79
95
|
def find_xpath(selector)
|
|
@@ -84,21 +100,13 @@ module Capybara
|
|
|
84
100
|
find(:css, selector)
|
|
85
101
|
end
|
|
86
102
|
|
|
87
|
-
def find(method, selector)
|
|
88
|
-
browser.find(method, selector).map { |native| Node.new(self, native) }
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def click(x, y)
|
|
92
|
-
browser.mouse.click(x: x, y: y)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
103
|
def evaluate_script(script, *args)
|
|
96
104
|
result = browser.evaluate(script, *native_args(args))
|
|
97
105
|
unwrap_script_result(result)
|
|
98
106
|
end
|
|
99
107
|
|
|
100
108
|
def evaluate_async_script(script, *args)
|
|
101
|
-
result = browser.
|
|
109
|
+
result = browser.evaluate(CALLBACK_JS.sub("SCRIPT") { script }, *native_args(args), timeout: session_wait_time)
|
|
102
110
|
unwrap_script_result(result)
|
|
103
111
|
end
|
|
104
112
|
|
|
@@ -110,23 +118,20 @@ module Capybara
|
|
|
110
118
|
def switch_to_frame(locator)
|
|
111
119
|
handle = case locator
|
|
112
120
|
when Capybara::Node::Element
|
|
113
|
-
locator.native.description["frameId"]
|
|
121
|
+
locator.native.node.description["frameId"]
|
|
114
122
|
when Capybara::Cuprite::Node
|
|
115
|
-
locator.description["frameId"]
|
|
123
|
+
locator.node.description["frameId"]
|
|
116
124
|
when :parent, :top
|
|
117
125
|
locator
|
|
118
126
|
end
|
|
119
127
|
|
|
120
128
|
raise ArgumentError, "Unable to switch to frame from #{locator.class}" unless handle
|
|
121
129
|
|
|
122
|
-
browser.switch_to_frame(handle)
|
|
130
|
+
browser.page.switch_to_frame(handle)
|
|
123
131
|
end
|
|
124
132
|
|
|
125
133
|
def open_new_window
|
|
126
|
-
|
|
127
|
-
target.maybe_sleep_if_new_window
|
|
128
|
-
target.page = Page.new(target.client, context_id: target.context_id, target_id: target.id)
|
|
129
|
-
target.page
|
|
134
|
+
browser.open_new_window
|
|
130
135
|
end
|
|
131
136
|
|
|
132
137
|
def no_such_window_error
|
|
@@ -140,6 +145,8 @@ module Capybara
|
|
|
140
145
|
browser.url_whitelist = @options[:url_whitelist]
|
|
141
146
|
browser.raise_on_unhandled_modal = @options.fetch(:raise_on_unhandled_modal, false)
|
|
142
147
|
browser.reset
|
|
148
|
+
base_url = @options[:base_url] || capybara_base_url
|
|
149
|
+
browser.base_url = base_url if base_url
|
|
143
150
|
ensure
|
|
144
151
|
@started = false
|
|
145
152
|
end
|
|
@@ -147,7 +154,7 @@ module Capybara
|
|
|
147
154
|
def save_screenshot(path, options = {})
|
|
148
155
|
options[:scale] = @zoom_factor if @zoom_factor
|
|
149
156
|
|
|
150
|
-
if
|
|
157
|
+
if File.extname(path) == ".pdf"
|
|
151
158
|
options[:paperWidth] = @paper_size[:width].to_f if @paper_size
|
|
152
159
|
options[:paperHeight] = @paper_size[:height].to_f if @paper_size
|
|
153
160
|
browser.pdf(path: path, **options)
|
|
@@ -155,32 +162,10 @@ module Capybara
|
|
|
155
162
|
browser.screenshot(path: path, **options)
|
|
156
163
|
end
|
|
157
164
|
end
|
|
158
|
-
alias render save_screenshot
|
|
159
|
-
|
|
160
|
-
def render_base64(format = :png, options = {})
|
|
161
|
-
if pdf?(nil, options)
|
|
162
|
-
options[:paperWidth] = @paper_size[:width].to_f if @paper_size
|
|
163
|
-
options[:paperHeight] = @paper_size[:height].to_f if @paper_size
|
|
164
|
-
browser.pdf(encoding: :base64, **options)
|
|
165
|
-
else
|
|
166
|
-
browser.screenshot(format: format, encoding: :base64, **options)
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
def zoom_factor=(value)
|
|
171
|
-
@zoom_factor = value.to_f
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
attr_writer :paper_size
|
|
175
|
-
|
|
176
|
-
def resize(width, height)
|
|
177
|
-
browser.resize(width: width, height: height)
|
|
178
|
-
end
|
|
179
|
-
alias resize_window resize
|
|
180
165
|
|
|
181
166
|
def resize_window_to(handle, width, height)
|
|
182
167
|
within_window(handle) do
|
|
183
|
-
resize(width, height)
|
|
168
|
+
browser.resize(width: width, height: height)
|
|
184
169
|
end
|
|
185
170
|
end
|
|
186
171
|
|
|
@@ -200,129 +185,10 @@ module Capybara
|
|
|
200
185
|
end
|
|
201
186
|
end
|
|
202
187
|
|
|
203
|
-
def scroll_to(left, top)
|
|
204
|
-
browser.mouse.scroll_to(left, top)
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
def network_traffic(type = nil)
|
|
208
|
-
traffic = browser.network.traffic
|
|
209
|
-
|
|
210
|
-
case type.to_s
|
|
211
|
-
when "all"
|
|
212
|
-
traffic
|
|
213
|
-
when "blocked"
|
|
214
|
-
traffic.select(&:blocked?)
|
|
215
|
-
else
|
|
216
|
-
# when request isn't blocked
|
|
217
|
-
traffic.reject(&:blocked?)
|
|
218
|
-
end
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
def clear_network_traffic
|
|
222
|
-
browser.network.clear(:traffic)
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
def set_proxy(host, port, user = nil, password = nil, bypass = nil)
|
|
226
|
-
@options.merge!(proxy: { host: host, port: port, user: user, password: password, bypass: bypass })
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
def headers
|
|
230
|
-
browser.headers.get
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
def headers=(headers)
|
|
234
|
-
browser.headers.set(headers)
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
def add_headers(headers)
|
|
238
|
-
browser.headers.add(headers)
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
def add_header(name, value, permanent: true)
|
|
242
|
-
browser.headers.add({ name => value }, permanent: permanent)
|
|
243
|
-
end
|
|
244
|
-
|
|
245
188
|
def response_headers
|
|
246
189
|
browser.network.response&.headers
|
|
247
190
|
end
|
|
248
191
|
|
|
249
|
-
def cookies
|
|
250
|
-
browser.cookies.all
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
def set_cookie(name, value, options = {})
|
|
254
|
-
options = options.dup
|
|
255
|
-
options[:name] ||= name
|
|
256
|
-
options[:value] ||= value
|
|
257
|
-
options[:domain] ||= default_domain
|
|
258
|
-
browser.cookies.set(**options)
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
def remove_cookie(name, **options)
|
|
262
|
-
options[:domain] = default_domain if options.empty?
|
|
263
|
-
options = options.merge(name: name)
|
|
264
|
-
browser.cookies.remove(**options)
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
def clear_cookies
|
|
268
|
-
browser.cookies.clear
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
def wait_for_network_idle(**options)
|
|
272
|
-
browser.network.wait_for_idle(**options)
|
|
273
|
-
end
|
|
274
|
-
|
|
275
|
-
def clear_memory_cache
|
|
276
|
-
browser.network.clear(:cache)
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
def basic_authorize(user, password)
|
|
280
|
-
browser.network.authorize(user: user, password: password) do |request, _index, _total|
|
|
281
|
-
request.continue
|
|
282
|
-
end
|
|
283
|
-
end
|
|
284
|
-
alias authorize basic_authorize
|
|
285
|
-
|
|
286
|
-
def debug(...)
|
|
287
|
-
browser.debug(...)
|
|
288
|
-
end
|
|
289
|
-
|
|
290
|
-
def pause
|
|
291
|
-
# STDIN is not necessarily connected to a keyboard. It might even be closed.
|
|
292
|
-
# So we need a method other than keypress to continue.
|
|
293
|
-
|
|
294
|
-
# In jRuby - STDIN returns immediately from select
|
|
295
|
-
# see https://github.com/jruby/jruby/issues/1783
|
|
296
|
-
read, write = IO.pipe
|
|
297
|
-
thread = Thread.new do
|
|
298
|
-
IO.copy_stream($stdin, write)
|
|
299
|
-
write.close
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
warn "Cuprite execution paused. Press enter (or run 'kill -CONT #{Process.pid}') to continue."
|
|
303
|
-
|
|
304
|
-
signal = false
|
|
305
|
-
old_trap = trap("SIGCONT") do
|
|
306
|
-
signal = true
|
|
307
|
-
warn "\nSignal SIGCONT received"
|
|
308
|
-
end
|
|
309
|
-
keyboard = read.wait_readable(1) until keyboard || signal # wait for data on STDIN or signal SIGCONT received
|
|
310
|
-
|
|
311
|
-
unless signal
|
|
312
|
-
begin
|
|
313
|
-
input = read.read_nonblock(80) # clear out the read buffer
|
|
314
|
-
puts unless input&.end_with?("\n")
|
|
315
|
-
rescue EOFError, IO::WaitReadable
|
|
316
|
-
# Ignore problems reading from STDIN.
|
|
317
|
-
end
|
|
318
|
-
end
|
|
319
|
-
ensure
|
|
320
|
-
thread.kill
|
|
321
|
-
read.close
|
|
322
|
-
trap("SIGCONT", old_trap) # Restore the previous signal handler, if there was one.
|
|
323
|
-
warn "Continuing"
|
|
324
|
-
end
|
|
325
|
-
|
|
326
192
|
def wait?
|
|
327
193
|
true
|
|
328
194
|
end
|
|
@@ -338,37 +204,49 @@ module Capybara
|
|
|
338
204
|
def accept_modal(type, options = {})
|
|
339
205
|
case type
|
|
340
206
|
when :alert, :confirm
|
|
341
|
-
browser.accept_confirm
|
|
207
|
+
browser.page.accept_confirm
|
|
342
208
|
when :prompt
|
|
343
|
-
browser.accept_prompt(options[:with])
|
|
209
|
+
browser.page.accept_prompt(options[:with])
|
|
344
210
|
end
|
|
345
211
|
|
|
346
212
|
yield if block_given?
|
|
347
213
|
|
|
348
|
-
browser.find_modal(options)
|
|
214
|
+
browser.page.find_modal(options)
|
|
349
215
|
end
|
|
350
216
|
|
|
351
217
|
def dismiss_modal(type, options = {})
|
|
352
218
|
case type
|
|
353
219
|
when :confirm
|
|
354
|
-
browser.dismiss_confirm
|
|
220
|
+
browser.page.dismiss_confirm
|
|
355
221
|
when :prompt
|
|
356
|
-
browser.dismiss_prompt
|
|
222
|
+
browser.page.dismiss_prompt
|
|
357
223
|
end
|
|
358
224
|
|
|
359
225
|
yield if block_given?
|
|
360
226
|
|
|
361
|
-
browser.find_modal(options)
|
|
227
|
+
browser.page.find_modal(options)
|
|
362
228
|
end
|
|
363
229
|
|
|
364
230
|
private
|
|
365
231
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
232
|
+
attr_reader :screen_size
|
|
233
|
+
|
|
234
|
+
def find(method, selector)
|
|
235
|
+
Finder.find(browser, method, selector).map { |native| Node.new(self, native) }
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def within_window(handle)
|
|
239
|
+
original = browser.current_window_handle
|
|
240
|
+
raise Ferrum::NoSuchPageError unless browser.window_handles.include?(handle)
|
|
241
|
+
|
|
242
|
+
browser.switch_to_window(handle)
|
|
243
|
+
yield
|
|
244
|
+
ensure
|
|
245
|
+
browser.switch_to_window(original)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def capybara_base_url
|
|
249
|
+
session_options.app_host || session&.server&.base_url
|
|
372
250
|
end
|
|
373
251
|
|
|
374
252
|
def native_args(args)
|
|
@@ -387,14 +265,6 @@ module Capybara
|
|
|
387
265
|
end
|
|
388
266
|
end
|
|
389
267
|
|
|
390
|
-
def default_cookie_host
|
|
391
|
-
if respond_to?(:session_options)
|
|
392
|
-
session_options.app_host
|
|
393
|
-
else
|
|
394
|
-
Capybara.app_host
|
|
395
|
-
end || ""
|
|
396
|
-
end
|
|
397
|
-
|
|
398
268
|
def unwrap_script_result(arg)
|
|
399
269
|
case arg
|
|
400
270
|
when Array
|
|
@@ -407,11 +277,6 @@ module Capybara
|
|
|
407
277
|
arg
|
|
408
278
|
end
|
|
409
279
|
end
|
|
410
|
-
|
|
411
|
-
def pdf?(path, options)
|
|
412
|
-
(path && File.extname(path).delete(".") == "pdf") ||
|
|
413
|
-
options[:format].to_s == "pdf"
|
|
414
|
-
end
|
|
415
280
|
end
|
|
416
281
|
end
|
|
417
282
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Capybara
|
|
4
|
+
module Cuprite
|
|
5
|
+
module Finder
|
|
6
|
+
module_function
|
|
7
|
+
|
|
8
|
+
def find(browser, method, selector, within = nil)
|
|
9
|
+
# Capybara appends its text-match hint as `(expr)[...]`, but with `exact_text: true` the hint
|
|
10
|
+
# is empty and the result `(expr)[]` is invalid XPath. An empty predicate is never valid, so
|
|
11
|
+
# dropping it can't change a valid selector. Remove once teamcapybara/capybara#2860 is released.
|
|
12
|
+
selector = selector.delete_suffix("[]") if method == :xpath
|
|
13
|
+
nodes = browser.evaluate("_cuprite.find(...arguments)", *[method, selector, within].compact)
|
|
14
|
+
nodes.select(&:node?)
|
|
15
|
+
rescue Ferrum::JavaScriptError => e
|
|
16
|
+
raise InvalidSelector.new(e.response, method, selector) if e.class_name == "InvalidSelector"
|
|
17
|
+
|
|
18
|
+
raise
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|