cuprite 0.12 → 0.15.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,198 +2,192 @@
2
2
 
3
3
  require "forwardable"
4
4
 
5
- module Capybara::Cuprite
6
- class Page < Ferrum::Page
7
- MODAL_WAIT = ENV.fetch("CUPRITE_MODAL_WAIT", 0.05).to_f
8
- TRIGGER_CLICK_WAIT = ENV.fetch("CUPRITE_TRIGGER_CLICK_WAIT", 0.1).to_f
9
-
10
- extend Forwardable
11
- delegate %i[at_css at_xpath css xpath
12
- current_url current_title body execution_id
13
- evaluate evaluate_on evaluate_async execute] => :active_frame
14
-
15
- def initialize(*args)
16
- @frame_stack = []
17
- @accept_modal = []
18
- @modal_messages = []
19
- super
5
+ module Capybara
6
+ module Cuprite
7
+ class ClosedPage
8
+ def closed?
9
+ true
10
+ end
20
11
  end
21
12
 
22
- def set(node, value)
23
- object_id = command("DOM.resolveNode", nodeId: node.node_id).dig("object", "objectId")
24
- evaluate("_cuprite.set(arguments[0], arguments[1])", { "objectId" => object_id }, value)
25
- end
13
+ class Page < Ferrum::Page
14
+ MODAL_WAIT = ENV.fetch("CUPRITE_MODAL_WAIT", 0.05).to_f
15
+ TRIGGER_CLICK_WAIT = ENV.fetch("CUPRITE_TRIGGER_CLICK_WAIT", 0.1).to_f
26
16
 
27
- def select(node, value)
28
- evaluate_on(node: node, expression: "_cuprite.select(this, #{value})")
29
- end
17
+ extend Forwardable
18
+ delegate %i[at_css at_xpath css xpath
19
+ current_url current_title body execution_id execution_id!
20
+ evaluate evaluate_on evaluate_async execute] => :active_frame
30
21
 
31
- def trigger(node, event)
32
- options = {}
33
- options.merge!(wait: TRIGGER_CLICK_WAIT) if event.to_s == "click" && TRIGGER_CLICK_WAIT > 0
34
- evaluate_on(node: node, expression: %(_cuprite.trigger(this, "#{event}")), **options)
35
- end
22
+ def initialize(...)
23
+ @frame_stack = []
24
+ @accept_modal = []
25
+ @modal_messages = []
26
+ @modal_response = nil
27
+ super
28
+ end
36
29
 
37
- def hover(node)
38
- evaluate_on(node: node, expression: "_cuprite.scrollIntoViewport(this)")
39
- x, y = find_position(node)
40
- command("Input.dispatchMouseEvent", type: "mouseMoved", x: x, y: y)
41
- end
30
+ def set(node, value)
31
+ object_id = command("DOM.resolveNode", nodeId: node.node_id).dig("object", "objectId")
32
+ evaluate("_cuprite.set(arguments[0], arguments[1])", { "objectId" => object_id }, value)
33
+ end
42
34
 
43
- def send_keys(node, keys)
44
- if !evaluate_on(node: node, expression: %(_cuprite.containsSelection(this)))
45
- before_click(node, "click")
46
- node.click(mode: :left, keys: keys)
35
+ def select(node, value)
36
+ evaluate_on(node: node, expression: "_cuprite.select(this, #{value})")
47
37
  end
48
38
 
49
- keyboard.type(keys)
50
- end
39
+ def trigger(node, event)
40
+ options = {}
41
+ options.merge!(wait: TRIGGER_CLICK_WAIT) if event.to_s == "click" && TRIGGER_CLICK_WAIT.positive?
42
+ evaluate_on(node: node, expression: %(_cuprite.trigger(this, "#{event}")), **options)
43
+ end
51
44
 
52
- def accept_confirm
53
- @accept_modal << true
54
- end
45
+ def hover(node)
46
+ evaluate_on(node: node, expression: "_cuprite.scrollIntoViewport(this)")
47
+ x, y = find_position(node)
48
+ command("Input.dispatchMouseEvent", type: "mouseMoved", x: x, y: y)
49
+ end
55
50
 
56
- def dismiss_confirm
57
- @accept_modal << false
58
- end
51
+ def send_keys(node, keys)
52
+ unless evaluate_on(node: node, expression: %(_cuprite.containsSelection(this)))
53
+ before_click(node, "click")
54
+ node.click(mode: :left, keys: keys)
55
+ end
59
56
 
60
- def accept_prompt(modal_response)
61
- @accept_modal << true
62
- @modal_response = modal_response
63
- end
57
+ keyboard.type(keys)
58
+ end
64
59
 
65
- def dismiss_prompt
66
- @accept_modal << false
67
- end
60
+ def accept_confirm
61
+ @accept_modal << true
62
+ end
68
63
 
69
- def find_modal(options)
70
- start = Ferrum.monotonic_time
71
- timeout = options.fetch(:wait, browser.timeout)
72
- expect_text = options[:text]
73
- expect_regexp = expect_text.is_a?(Regexp) ? expect_text : Regexp.escape(expect_text.to_s)
74
- not_found_msg = "Unable to find modal dialog"
75
- not_found_msg += " with #{expect_text}" if expect_text
64
+ def dismiss_confirm
65
+ @accept_modal << false
66
+ end
76
67
 
77
- begin
78
- modal_text = @modal_messages.shift
79
- raise Capybara::ModalNotFound if modal_text.nil? || (expect_text && !modal_text.match(expect_regexp))
80
- rescue Capybara::ModalNotFound => e
81
- raise e, not_found_msg if Ferrum.timeout?(start, timeout)
82
- sleep(MODAL_WAIT)
83
- retry
68
+ def accept_prompt(modal_response)
69
+ @accept_modal << true
70
+ @modal_response = modal_response
84
71
  end
85
72
 
86
- modal_text
87
- end
73
+ def dismiss_prompt
74
+ @accept_modal << false
75
+ end
88
76
 
89
- def reset_modals
90
- @accept_modal = []
91
- @modal_response = nil
92
- @modal_messages = []
93
- end
77
+ def find_modal(options)
78
+ start = Ferrum::Utils::ElapsedTime.monotonic_time
79
+ expect_text = options[:text]
80
+ expect_regexp = expect_text.is_a?(Regexp) ? expect_text : Regexp.escape(expect_text.to_s)
81
+ not_found_msg = "Unable to find modal dialog"
82
+ not_found_msg += " with #{expect_text}" if expect_text
83
+ wait = options.fetch(:wait, timeout)
84
+
85
+ begin
86
+ modal_text = @modal_messages.shift
87
+ raise Capybara::ModalNotFound if modal_text.nil? || (expect_text && !modal_text.match(expect_regexp))
88
+ rescue Capybara::ModalNotFound => e
89
+ raise e, not_found_msg if Ferrum::Utils::ElapsedTime.timeout?(start, wait)
90
+
91
+ sleep(MODAL_WAIT)
92
+ retry
93
+ end
94
94
 
95
- def before_click(node, name, keys = [], offset = {})
96
- evaluate_on(node: node, expression: "_cuprite.scrollIntoViewport(this)")
95
+ modal_text
96
+ end
97
97
 
98
- # If offset is given it may go outside of the element and likely error
99
- # will be raised that we detected another element at this position.
100
- return true if offset[:x] || offset[:y]
98
+ def reset_modals
99
+ @accept_modal = []
100
+ @modal_response = nil
101
+ @modal_messages = []
102
+ end
101
103
 
102
- x, y = find_position(node, **offset)
103
- evaluate_on(node: node, expression: "_cuprite.mouseEventTest(this, '#{name}', #{x}, #{y})")
104
- true
105
- rescue Ferrum::JavaScriptError => e
106
- raise MouseEventFailed.new(e.message) if e.class_name == "MouseEventFailed"
107
- end
104
+ def before_click(node, name, _keys = [], offset = {})
105
+ evaluate_on(node: node, expression: "_cuprite.scrollIntoViewport(this)")
108
106
 
109
- def switch_to_frame(handle)
110
- case handle
111
- when :parent
112
- @frame_stack.pop
113
- when :top
114
- @frame_stack = []
115
- else
116
- @frame_stack << handle
117
- inject_extensions
107
+ # If offset is given it may go outside of the element and likely error
108
+ # will be raised that we detected another element at this position.
109
+ return true if offset[:x] || offset[:y]
110
+
111
+ x, y = find_position(node, **offset)
112
+ evaluate_on(node: node, expression: "_cuprite.mouseEventTest(this, '#{name}', #{x}, #{y})")
113
+ true
114
+ rescue Ferrum::JavaScriptError => e
115
+ raise MouseEventFailed, e.message if e.class_name == "MouseEventFailed"
118
116
  end
119
- end
120
117
 
121
- def frame_name
122
- evaluate("window.name")
123
- end
118
+ def switch_to_frame(handle)
119
+ case handle
120
+ when :parent
121
+ @frame_stack.pop
122
+ when :top
123
+ @frame_stack = []
124
+ else
125
+ @frame_stack << handle
126
+ inject_extensions
127
+ end
128
+ end
124
129
 
125
- def title
126
- active_frame.current_title
127
- end
130
+ def frame_name
131
+ evaluate("window.name")
132
+ end
128
133
 
129
- private
134
+ def title
135
+ active_frame.current_title
136
+ end
130
137
 
131
- def prepare_page
132
- super
138
+ def closed?
139
+ false
140
+ end
133
141
 
134
- network.intercept if !Array(@browser.url_whitelist).empty? ||
135
- !Array(@browser.url_blacklist).empty?
142
+ private
136
143
 
137
- on(:request) do |request, index, total|
138
- if @browser.url_blacklist && !@browser.url_blacklist.empty?
139
- if @browser.url_blacklist.any? { |r| request.match?(r) }
140
- request.abort and next
141
- else
142
- request.continue and next
143
- end
144
- elsif @browser.url_whitelist && !@browser.url_whitelist.empty?
145
- if @browser.url_whitelist.any? { |r| request.match?(r) }
146
- request.continue and next
147
- else
148
- request.abort and next
149
- end
150
- elsif index + 1 < total
151
- # There are other callbacks that may handle this request
152
- next
153
- else
154
- # If there are no callbacks then just continue
155
- request.continue
144
+ def prepare_page
145
+ super
146
+
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
156
154
  end
157
- end
158
155
 
159
- on("Page.javascriptDialogOpening") do |params|
160
- accept_modal = @accept_modal.last
161
- if accept_modal == true || accept_modal == false
162
- @accept_modal.pop
163
- @modal_messages << params["message"]
164
- options = { accept: accept_modal }
165
- response = @modal_response || params["defaultPrompt"]
166
- options.merge!(promptText: response) if response
167
- command("Page.handleJavaScriptDialog", **options)
168
- else
169
- with_text = params["message"] ? "with text `#{params["message"]}` " : ""
170
- warn "Modal window #{with_text}has been opened, but you didn't wrap "\
171
- "your code into (`accept_prompt` | `dismiss_prompt` | "\
172
- "`accept_confirm` | `dismiss_confirm` | `accept_alert`), "\
173
- "accepting by default"
174
- options = { accept: true }
175
- response = params["defaultPrompt"]
156
+ on("Page.javascriptDialogOpening") do |params|
157
+ accept_modal = @accept_modal.last
158
+ if [true, false].include?(accept_modal)
159
+ @accept_modal.pop
160
+ @modal_messages << params["message"]
161
+ options = { accept: accept_modal }
162
+ response = @modal_response || params["defaultPrompt"]
163
+ else
164
+ with_text = params["message"] ? "with text `#{params['message']}` " : ""
165
+ warn "Modal window #{with_text}has been opened, but you didn't wrap " \
166
+ "your code into (`accept_prompt` | `dismiss_prompt` | " \
167
+ "`accept_confirm` | `dismiss_confirm` | `accept_alert`), " \
168
+ "accepting by default"
169
+ options = { accept: true }
170
+ response = params["defaultPrompt"]
171
+ end
176
172
  options.merge!(promptText: response) if response
177
173
  command("Page.handleJavaScriptDialog", **options)
178
174
  end
179
175
  end
180
- end
181
176
 
182
- def find_position(node, **options)
183
- x, y = node.find_position(**options)
184
- rescue Ferrum::BrowserError => e
185
- if e.message == "Could not compute content quads."
186
- raise MouseEventFailed.new("MouseEventFailed: click, none, 0, 0")
187
- else
177
+ def find_position(node, **options)
178
+ node.find_position(**options)
179
+ rescue Ferrum::BrowserError => e
180
+ raise MouseEventFailed, "MouseEventFailed: click, none, 0, 0" if e.message == "Could not compute content quads."
181
+
188
182
  raise
189
183
  end
190
- end
191
184
 
192
- def active_frame
193
- if @frame_stack.empty?
194
- main_frame
195
- else
196
- @frames[@frame_stack.last]
185
+ def active_frame
186
+ if @frame_stack.empty?
187
+ main_frame
188
+ else
189
+ @frames[@frame_stack.last]
190
+ end
197
191
  end
198
192
  end
199
193
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Capybara
4
4
  module Cuprite
5
- VERSION = "0.12"
5
+ VERSION = "0.15.1"
6
6
  end
7
7
  end
@@ -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,155 +1,23 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cuprite
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.12'
4
+ version: 0.15.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Vorotilin
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-24 00:00:00.000000000 Z
11
+ date: 2024-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capybara
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '2.1'
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '4'
23
- type: :runtime
24
- prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: '2.1'
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: '4'
33
- - !ruby/object:Gem::Dependency
34
- name: ferrum
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: 0.10.0
40
- type: :runtime
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: 0.10.0
47
- - !ruby/object:Gem::Dependency
48
- name: image_size
49
- requirement: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
52
- - !ruby/object:Gem::Version
53
- version: '2.0'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: '2.0'
61
- - !ruby/object:Gem::Dependency
62
- name: pdf-reader
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '2.1'
68
- type: :development
69
- prerelease: false
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - "~>"
73
- - !ruby/object:Gem::Version
74
- version: '2.1'
75
- - !ruby/object:Gem::Dependency
76
- name: rake
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '12.3'
82
- type: :development
83
- prerelease: false
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: '12.3'
89
- - !ruby/object:Gem::Dependency
90
- name: rspec
91
- requirement: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - "~>"
94
- - !ruby/object:Gem::Version
95
- version: '3.7'
96
- type: :development
97
- prerelease: false
98
- version_requirements: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "~>"
101
- - !ruby/object:Gem::Version
102
- version: '3.7'
103
- - !ruby/object:Gem::Dependency
104
- name: sinatra
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - "~>"
108
- - !ruby/object:Gem::Version
109
- version: '2.0'
110
- type: :development
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - "~>"
115
- - !ruby/object:Gem::Version
116
- version: '2.0'
117
- - !ruby/object:Gem::Dependency
118
- name: launchy
119
- requirement: !ruby/object:Gem::Requirement
120
- requirements:
121
- - - "~>"
122
- - !ruby/object:Gem::Version
123
- version: '2.4'
124
- type: :development
125
- prerelease: false
126
- version_requirements: !ruby/object:Gem::Requirement
127
- requirements:
128
- - - "~>"
129
- - !ruby/object:Gem::Version
130
- version: '2.4'
131
- - !ruby/object:Gem::Dependency
132
- name: byebug
133
- requirement: !ruby/object:Gem::Requirement
134
- requirements:
135
- - - "~>"
136
- - !ruby/object:Gem::Version
137
- version: '10.0'
138
- type: :development
139
- prerelease: false
140
- version_requirements: !ruby/object:Gem::Requirement
141
- requirements:
142
- - - "~>"
143
- - !ruby/object:Gem::Version
144
- version: '10.0'
145
- - !ruby/object:Gem::Dependency
146
- name: puma
147
15
  requirement: !ruby/object:Gem::Requirement
148
16
  requirements:
149
17
  - - "~>"
150
18
  - !ruby/object:Gem::Version
151
19
  version: '3.0'
152
- type: :development
20
+ type: :runtime
153
21
  prerelease: false
154
22
  version_requirements: !ruby/object:Gem::Requirement
155
23
  requirements:
@@ -157,19 +25,19 @@ dependencies:
157
25
  - !ruby/object:Gem::Version
158
26
  version: '3.0'
159
27
  - !ruby/object:Gem::Dependency
160
- name: chunky_png
28
+ name: ferrum
161
29
  requirement: !ruby/object:Gem::Requirement
162
30
  requirements:
163
31
  - - "~>"
164
32
  - !ruby/object:Gem::Version
165
- version: '1.3'
166
- type: :development
33
+ version: 0.15.0
34
+ type: :runtime
167
35
  prerelease: false
168
36
  version_requirements: !ruby/object:Gem::Requirement
169
37
  requirements:
170
38
  - - "~>"
171
39
  - !ruby/object:Gem::Version
172
- version: '1.3'
40
+ version: 0.15.0
173
41
  description: Cuprite is a driver for Capybara that allows you to run your tests on
174
42
  a headless Chrome browser
175
43
  email:
@@ -187,13 +55,19 @@ files:
187
55
  - lib/capybara/cuprite/errors.rb
188
56
  - lib/capybara/cuprite/javascripts/index.js
189
57
  - lib/capybara/cuprite/node.rb
58
+ - lib/capybara/cuprite/options.rb
190
59
  - lib/capybara/cuprite/page.rb
191
60
  - lib/capybara/cuprite/version.rb
192
61
  homepage: https://github.com/rubycdp/cuprite
193
62
  licenses:
194
63
  - MIT
195
- metadata: {}
196
- post_install_message:
64
+ metadata:
65
+ homepage_uri: https://cuprite.rubycdp.com/
66
+ bug_tracker_uri: https://github.com/rubycdp/cuprite/issues
67
+ documentation_uri: https://github.com/rubycdp/cuprite/blob/main/README.md
68
+ source_code_uri: https://github.com/rubycdp/cuprite
69
+ rubygems_mfa_required: 'true'
70
+ post_install_message:
197
71
  rdoc_options: []
198
72
  require_paths:
199
73
  - lib
@@ -201,15 +75,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
201
75
  requirements:
202
76
  - - ">="
203
77
  - !ruby/object:Gem::Version
204
- version: 2.3.0
78
+ version: 2.7.0
205
79
  required_rubygems_version: !ruby/object:Gem::Requirement
206
80
  requirements:
207
81
  - - ">="
208
82
  - !ruby/object:Gem::Version
209
83
  version: '0'
210
84
  requirements: []
211
- rubygems_version: 3.1.2
212
- signing_key:
85
+ rubygems_version: 3.5.11
86
+ signing_key:
213
87
  specification_version: 4
214
88
  summary: Headless Chrome driver for Capybara
215
89
  test_files: []