capybara-mechanize 1.11.0 → 1.12.0
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 +5 -5
- data/README.mdown +12 -0
- data/lib/capybara/mechanize/browser.rb +37 -37
- data/lib/capybara/mechanize/cucumber.rb +3 -1
- data/lib/capybara/mechanize/driver.rb +4 -3
- data/lib/capybara/mechanize/form.rb +11 -20
- data/lib/capybara/mechanize/node.rb +8 -10
- data/lib/capybara/mechanize/version.rb +3 -1
- data/lib/capybara/mechanize.rb +5 -6
- data/lib/capybara/spec/extended_test_app.rb +19 -16
- data/spec/driver/mechanize_driver_spec.rb +72 -71
- data/spec/driver/remote_mechanize_driver_spec.rb +17 -15
- data/spec/session/mechanize_spec.rb +59 -45
- data/spec/session/remote_mechanize_spec.rb +57 -55
- data/spec/spec_helper.rb +4 -4
- data/spec/support/disable_external_tests.rb +4 -3
- data/spec/support/extended_test_app_setup.rb +2 -0
- data/spec/support/remote_test_url.rb +3 -1
- metadata +71 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 964088e52d1773ab930c2e5954ab42aa618526a06fd1c3f80e4ae33bb72c0630
|
4
|
+
data.tar.gz: '0854756c4a3f907052509229cb682099d18af60adeb7e9c76c5b2375c7e8d946'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c691f96c62e55c408c2b6b235eb6804b1adf4446358f08c0e53e4092f838537e28c235fcd9b0a887828247313ea3b57bf944fa1b872d53a6fc86b3ec4c8e7ae
|
7
|
+
data.tar.gz: 5d7ecc072aa6f57b3536224e2cb35f1f7915e3758e67cdfaf872ae9ba49f0d07d15bf394b635305f89c0a5b1756233eefe6947e8efac5520f409f7789aeb83b5
|
data/README.mdown
CHANGED
@@ -35,7 +35,19 @@ Capybara.register_driver :mechanize do |app|
|
|
35
35
|
driver
|
36
36
|
end
|
37
37
|
```
|
38
|
+
### Usage without rack app
|
38
39
|
|
40
|
+
You can configure it to use for external servers. Until this issue https://github.com/jeroenvandijk/capybara-mechanize/issues/66 is resolved, you can configure with
|
41
|
+
```
|
42
|
+
Capybara.register_driver :mechanize do |app|
|
43
|
+
Capybara::Mechanize::Driver.new(proc {})
|
44
|
+
end
|
45
|
+
```
|
46
|
+
and use like this
|
47
|
+
```
|
48
|
+
session = Capybara::Session.new :mechanize
|
49
|
+
session.visit 'https://github.com'
|
50
|
+
```
|
39
51
|
### Usage with Cucumber and tags
|
40
52
|
|
41
53
|
A @mechanize tag is added to your hooks when you add the following line to your env.rb
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'capybara/rack_test/driver'
|
2
4
|
require 'mechanize'
|
3
5
|
require 'capybara/mechanize/node'
|
@@ -39,7 +41,7 @@ class Capybara::Mechanize::Browser < Capybara::RackTest::Browser
|
|
39
41
|
# Then we determine if the call is remote or local.
|
40
42
|
# Remote: Handle it with our process_remote_request method.
|
41
43
|
# Local: Register the local request and call super to let RackTest get it.
|
42
|
-
[
|
44
|
+
%i[get post put delete].each do |method|
|
43
45
|
define_method(method) do |path, params = {}, env = {}, &block|
|
44
46
|
path = @last_path if path.nil? || path.empty?
|
45
47
|
|
@@ -81,7 +83,7 @@ class Capybara::Mechanize::Browser < Capybara::RackTest::Browser
|
|
81
83
|
end
|
82
84
|
|
83
85
|
def find(format, selector)
|
84
|
-
if format
|
86
|
+
if format == :css
|
85
87
|
dom.css(selector, Capybara::RackTest::CSSHandlers.new)
|
86
88
|
else
|
87
89
|
dom.xpath(selector)
|
@@ -110,39 +112,37 @@ class Capybara::Mechanize::Browser < Capybara::RackTest::Browser
|
|
110
112
|
end
|
111
113
|
|
112
114
|
def process_remote_request(method, url, attributes, headers)
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
@agent.send(method, url, attributes, headers)
|
125
|
-
end
|
126
|
-
elsif method == :get
|
127
|
-
if attributes.is_a? Mechanize::Form
|
128
|
-
submit_mechanize_form(url, attributes, headers)
|
129
|
-
else
|
130
|
-
referer = headers['HTTP_REFERER']
|
131
|
-
@agent.send(method, url, attributes, referer, headers)
|
132
|
-
end
|
115
|
+
return unless remote?(url)
|
116
|
+
|
117
|
+
uri = URI.parse(url)
|
118
|
+
@last_remote_uri = uri
|
119
|
+
url = uri.to_s
|
120
|
+
|
121
|
+
reset_cache!
|
122
|
+
begin
|
123
|
+
if method == :post
|
124
|
+
if attributes.is_a? Mechanize::Form
|
125
|
+
submit_mechanize_form(url, attributes, headers)
|
133
126
|
else
|
134
127
|
@agent.send(method, url, attributes, headers)
|
135
128
|
end
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
129
|
+
elsif method == :get
|
130
|
+
if attributes.is_a? Mechanize::Form
|
131
|
+
submit_mechanize_form(url, attributes, headers)
|
132
|
+
else
|
133
|
+
referer = headers['HTTP_REFERER']
|
134
|
+
@agent.send(method, url, attributes, referer, headers)
|
142
135
|
end
|
136
|
+
else
|
137
|
+
@agent.send(method, url, attributes, headers)
|
143
138
|
end
|
144
|
-
@
|
139
|
+
@errored_remote_response = nil
|
140
|
+
rescue Mechanize::ResponseCodeError => e
|
141
|
+
@errored_remote_response = e.page
|
142
|
+
|
143
|
+
raise "Received the following error for a #{method.to_s.upcase} request to #{url}: '#{e.message}'" if Capybara.raise_server_errors
|
145
144
|
end
|
145
|
+
@last_request_remote = true
|
146
146
|
end
|
147
147
|
|
148
148
|
def submit_mechanize_form(url, form, headers)
|
@@ -154,12 +154,12 @@ class Capybara::Mechanize::Browser < Capybara::RackTest::Browser
|
|
154
154
|
if errored_remote_response
|
155
155
|
ResponseProxy.new(errored_remote_response)
|
156
156
|
elsif @agent.current_page
|
157
|
-
ResponseProxy.new(@agent.current_page)
|
157
|
+
ResponseProxy.new(@agent.current_page, current_fragment: @current_fragment)
|
158
158
|
end
|
159
159
|
end
|
160
160
|
|
161
161
|
def default_user_agent
|
162
|
-
|
162
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.853.0 Safari/535.2'
|
163
163
|
end
|
164
164
|
|
165
165
|
class ResponseProxy
|
@@ -169,18 +169,21 @@ class Capybara::Mechanize::Browser < Capybara::RackTest::Browser
|
|
169
169
|
|
170
170
|
attr_reader :page
|
171
171
|
|
172
|
-
def initialize(page)
|
172
|
+
def initialize(page, current_fragment: nil)
|
173
173
|
@page = page
|
174
|
+
@current_fragment = current_fragment
|
174
175
|
end
|
175
176
|
|
176
177
|
def current_url
|
177
|
-
page.uri.
|
178
|
+
uri = page.uri.dup
|
179
|
+
uri.fragment = @current_fragment if @current_fragment
|
180
|
+
uri.to_s
|
178
181
|
end
|
179
182
|
|
180
183
|
def headers
|
181
184
|
# Hax the content-type contains utf8, so Capybara specs are failing, need to ask mailinglist
|
182
185
|
headers = page.response
|
183
|
-
headers[
|
186
|
+
headers['content-type']&.gsub!(';charset=utf-8', '')
|
184
187
|
headers
|
185
188
|
end
|
186
189
|
|
@@ -195,8 +198,5 @@ class Capybara::Mechanize::Browser < Capybara::RackTest::Browser
|
|
195
198
|
def redirect?
|
196
199
|
status >= 300 && status < 400
|
197
200
|
end
|
198
|
-
|
199
201
|
end
|
200
|
-
|
201
202
|
end
|
202
|
-
|
@@ -1,9 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'capybara/mechanize/browser'
|
2
4
|
|
3
5
|
class Capybara::Mechanize::Driver < Capybara::RackTest::Driver
|
4
|
-
|
5
6
|
def initialize(app, **options)
|
6
|
-
raise ArgumentError,
|
7
|
+
raise ArgumentError, 'mechanize requires a rack application, but none was given' unless app
|
7
8
|
|
8
9
|
super
|
9
10
|
end
|
@@ -12,7 +13,7 @@ class Capybara::Mechanize::Driver < Capybara::RackTest::Driver
|
|
12
13
|
browser.remote?(url)
|
13
14
|
end
|
14
15
|
|
15
|
-
def configure
|
16
|
+
def configure
|
16
17
|
yield(browser.agent) if block_given?
|
17
18
|
end
|
18
19
|
|
@@ -1,25 +1,20 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
class Capybara::Mechanize::Form < Capybara::RackTest::Form
|
3
4
|
def params(button)
|
4
|
-
|
5
|
-
return super
|
6
|
-
end
|
5
|
+
return super unless use_mechanize?
|
7
6
|
|
8
7
|
node = {}
|
9
8
|
# Create a fake form
|
10
9
|
class << node
|
11
|
-
def search(*
|
10
|
+
def search(*_args); []; end
|
12
11
|
end
|
13
12
|
|
14
13
|
node['method'] = button && button['formmethod']
|
15
14
|
|
16
15
|
node['method'] ||= (respond_to?(:request_method, true) ? request_method : method).to_s.upcase
|
17
16
|
|
18
|
-
|
19
|
-
node['enctype'] = 'multipart/form-data'
|
20
|
-
else
|
21
|
-
node['enctype'] = 'application/x-www-form-urlencoded'
|
22
|
-
end
|
17
|
+
node['enctype'] = multipart? ? 'multipart/form-data' : 'application/x-www-form-urlencoded'
|
23
18
|
|
24
19
|
@m_form = Mechanize::Form.new(node, nil, form_referer)
|
25
20
|
|
@@ -31,20 +26,16 @@ class Capybara::Mechanize::Form < Capybara::RackTest::Form
|
|
31
26
|
private
|
32
27
|
|
33
28
|
def merge_param!(params, key, value)
|
34
|
-
|
35
|
-
return super
|
36
|
-
end
|
29
|
+
return super unless use_mechanize?
|
37
30
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
return params
|
42
|
-
end
|
31
|
+
# Adding a nil value here will result in the form element existing with the empty string as its value.
|
32
|
+
# Instead don't add the form element at all.
|
33
|
+
return params if value.is_a? NilUploadedFile
|
43
34
|
|
44
35
|
if value.is_a? Rack::Test::UploadedFile
|
45
36
|
@m_form.enctype = 'multipart/form-data'
|
46
37
|
|
47
|
-
ul = Mechanize::Form::FileUpload.new({'name' => key.to_s}, value.original_filename)
|
38
|
+
ul = Mechanize::Form::FileUpload.new({ 'name' => key.to_s }, value.original_filename)
|
48
39
|
ul.mime_type = value.content_type
|
49
40
|
ul.file_data = (value.rewind; value.read)
|
50
41
|
|
@@ -53,7 +44,7 @@ class Capybara::Mechanize::Form < Capybara::RackTest::Form
|
|
53
44
|
return params
|
54
45
|
end
|
55
46
|
|
56
|
-
@m_form.fields << Mechanize::Form::Field.new({'name' => key.to_s}, value)
|
47
|
+
@m_form.fields << Mechanize::Form::Field.new({ 'name' => key.to_s }, value)
|
57
48
|
|
58
49
|
params
|
59
50
|
end
|
@@ -1,18 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Capybara::Mechanize::Node < Capybara::RackTest::Node
|
2
|
-
def click(keys = [],
|
3
|
-
raise ArgumentError,
|
4
|
+
def click(keys = [], **options)
|
5
|
+
raise ArgumentError, 'The mechanize driver does not support click options' unless keys.empty? && options.empty?
|
4
6
|
|
5
7
|
submits = respond_to?(:submits?) ? submits? :
|
6
|
-
((tag_name == 'input' and %w
|
7
|
-
((tag_name == 'button') and type.nil? or type ==
|
8
|
+
((tag_name == 'input' and %w[submit image].include?(type)) or
|
9
|
+
((tag_name == 'button') and type.nil? or type == 'submit'))
|
8
10
|
|
9
11
|
if tag_name == 'a' or tag_name == 'label' or
|
10
|
-
(tag_name == 'input' and %w
|
11
|
-
|
12
|
-
super
|
13
|
-
else
|
14
|
-
super()
|
15
|
-
end
|
12
|
+
(tag_name == 'input' and %w[checkbox radio].include?(type))
|
13
|
+
Capybara::VERSION > '3.0.0' ? super : super()
|
16
14
|
elsif submits
|
17
15
|
associated_form = form
|
18
16
|
Capybara::Mechanize::Form.new(driver, form).submit(self) if associated_form
|
data/lib/capybara/mechanize.rb
CHANGED
@@ -1,19 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'capybara'
|
2
4
|
|
3
5
|
module Capybara::Mechanize
|
4
6
|
class << self
|
5
|
-
|
6
7
|
# Host that should be considered local (includes default_host)
|
7
8
|
def local_hosts
|
8
9
|
@local_hosts ||= begin
|
9
|
-
default_host = URI.parse(Capybara.default_host ||
|
10
|
+
default_host = URI.parse(Capybara.default_host || '').host || Capybara.default_host
|
10
11
|
[default_host].compact
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
14
|
-
|
15
|
-
@local_hosts = hosts
|
16
|
-
end
|
15
|
+
attr_writer :local_hosts
|
17
16
|
end
|
18
17
|
end
|
19
18
|
|
@@ -21,4 +20,4 @@ require 'capybara/mechanize/driver'
|
|
21
20
|
|
22
21
|
Capybara.register_driver :mechanize do |app|
|
23
22
|
Capybara::Mechanize::Driver.new(app)
|
24
|
-
end
|
23
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'capybara/spec/test_app'
|
2
4
|
|
3
5
|
class ExtendedTestApp < TestApp
|
@@ -9,19 +11,19 @@ class ExtendedTestApp < TestApp
|
|
9
11
|
end
|
10
12
|
|
11
13
|
get '/form_with_relative_action_to_host' do
|
12
|
-
%
|
14
|
+
%(<form action="/request_info/host" method="post">
|
13
15
|
<input type="submit" value="submit" />
|
14
|
-
</form>
|
16
|
+
</form>)
|
15
17
|
end
|
16
18
|
|
17
19
|
get '/request_info/form_with_no_action' do
|
18
|
-
%
|
20
|
+
%(<form method="post">
|
19
21
|
<input type="submit" value="submit" />
|
20
|
-
</form>
|
22
|
+
</form>)
|
21
23
|
end
|
22
24
|
|
23
25
|
get '/relative_link_to_host' do
|
24
|
-
%
|
26
|
+
%(<a href="/request_info/host">host</a>)
|
25
27
|
end
|
26
28
|
|
27
29
|
get '/request_info/user_agent' do
|
@@ -37,15 +39,15 @@ class ExtendedTestApp < TestApp
|
|
37
39
|
end
|
38
40
|
|
39
41
|
get '/subsite/relative_link_to_host' do
|
40
|
-
%
|
42
|
+
%(<a href="/subsite/request_info2/host">host</a>)
|
41
43
|
end
|
42
44
|
|
43
45
|
get '/subsite/local_link_to_host' do
|
44
|
-
%
|
46
|
+
%(<a href="request_info2/host">host</a>)
|
45
47
|
end
|
46
48
|
|
47
49
|
get '/subsite/request_info2/*' do
|
48
|
-
|
50
|
+
'subsite: ' + current_request_info
|
49
51
|
end
|
50
52
|
|
51
53
|
get '/redirect_with_http_param' do
|
@@ -53,25 +55,26 @@ class ExtendedTestApp < TestApp
|
|
53
55
|
end
|
54
56
|
|
55
57
|
get '/redirect_target' do
|
56
|
-
%
|
58
|
+
%(correct redirect)
|
57
59
|
end
|
58
60
|
|
59
61
|
get %r{/form_posts_to/(.*)} do
|
60
|
-
%
|
62
|
+
%(
|
61
63
|
<form action="#{params[:captures].first}" method="post">
|
62
64
|
<input type="submit" value="submit" />
|
63
65
|
</form>
|
64
|
-
|
66
|
+
)
|
65
67
|
end
|
66
68
|
|
67
69
|
post '/get_referer' do
|
68
|
-
request.referer.nil? ?
|
70
|
+
request.referer.nil? ? 'No referer' : "Got referer: #{request.referer}"
|
69
71
|
end
|
70
72
|
|
73
|
+
@form_post_count = 0
|
74
|
+
|
71
75
|
private
|
72
76
|
|
73
|
-
|
74
|
-
|
75
|
-
|
77
|
+
def current_request_info
|
78
|
+
"Current host is #{request.url}, method #{request.request_method.downcase}"
|
79
|
+
end
|
76
80
|
end
|
77
|
-
|