puffing-billy 2.1.0 → 2.4.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 +4 -4
- data/.travis.yml +29 -16
- data/CHANGELOG.md +23 -0
- data/README.md +142 -113
- data/Rakefile +9 -0
- data/examples/tumblr_api_https.html +22 -0
- data/lib/billy/browsers/capybara.rb +48 -8
- data/lib/billy/browsers/watir.rb +1 -0
- data/lib/billy/config.rb +6 -3
- data/lib/billy/handlers/proxy_handler.rb +15 -1
- data/lib/billy/handlers/request_handler.rb +4 -0
- data/lib/billy/ssl/certificate_helpers.rb +1 -1
- data/lib/billy/version.rb +1 -1
- data/puffing-billy.gemspec +4 -5
- data/spec/lib/billy/browsers/capybara_spec.rb +28 -0
- data/spec/lib/billy/handlers/proxy_handler_spec.rb +28 -0
- data/spec/lib/billy/handlers/request_handler_spec.rb +22 -0
- data/spec/lib/proxy_spec.rb +25 -2
- data/spec/spec_helper.rb +10 -4
- metadata +29 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98ce893c9461f4f8c8eedd69eee46870634f789dd03a2007370bb7b03361bc26
|
4
|
+
data.tar.gz: 35f7939ff8eb3cbccd4bf4e91ccefbddd1b4b999fddfbc86ec0ff82885ae0dad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73d5bc111493abd8a2bf9157f9bc3b717f0d4bc2a9276a757280d6e6ad7b3e5a1acd90a30234e00bdd9245380f6d9c00aa9bb86c3ec6bd7eed46643af1b85451
|
7
|
+
data.tar.gz: a32ac78dec161016266bf1ac2d2cdedcb68247c03cea681f096dc1dd4eb73dd4d166f27173a9f8b0040df39fd168d97010960a074b8b23c49183bee6a737bd50
|
data/.travis.yml
CHANGED
@@ -1,23 +1,36 @@
|
|
1
1
|
language: ruby
|
2
|
-
|
3
|
-
before_install:
|
4
|
-
- gem install bundler -v '< 2'
|
5
|
-
- export PHANTOMJS_VERSION='2.1.1'
|
6
|
-
- export PHANTOMJS_URL='https://github.com/Medium/phantomjs'
|
7
|
-
- export PHANTOMJS_URL+="/releases/download/v${PHANTOMJS_VERSION}"
|
8
|
-
- export PHANTOMJS_URL+="/phantomjs-${PHANTOMJS_VERSION}-linux-x86_64.tar.bz2"
|
9
|
-
- >
|
10
|
-
wget -q ${PHANTOMJS_URL} &&
|
11
|
-
tar xfv phantomjs-${PHANTOMJS_VERSION}-linux-x86_64.tar.bz2 \
|
12
|
-
--wildcards */bin/phantomjs --strip-components=2
|
13
|
-
- export PATH="`pwd`:${PATH}"
|
14
|
-
before_script:
|
15
|
-
- phantomjs --version
|
16
|
-
- bundle --version
|
2
|
+
|
17
3
|
rvm:
|
18
4
|
- 2.3
|
19
5
|
- 2.4
|
20
6
|
- 2.5
|
21
7
|
- 2.6
|
22
|
-
|
8
|
+
|
9
|
+
cache:
|
10
|
+
bundler: true
|
11
|
+
directories:
|
12
|
+
- $HOME/.webdrivers
|
13
|
+
|
14
|
+
addons:
|
15
|
+
chrome: stable
|
16
|
+
apt:
|
17
|
+
update: true
|
18
|
+
|
19
|
+
sudo: false
|
20
|
+
dist: xenial
|
21
|
+
|
22
|
+
rvm:
|
23
|
+
- 2.3
|
24
|
+
- 2.4
|
25
|
+
- 2.5
|
26
|
+
- 2.6
|
27
|
+
|
28
|
+
matrix:
|
29
|
+
fast_finish: true
|
30
|
+
|
31
|
+
bundler_args: --jobs 3 --retry 3
|
32
|
+
|
33
|
+
before_install:
|
34
|
+
- gem update --system
|
35
|
+
- gem install bundler
|
23
36
|
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
v2.4.0, 2020-08-26
|
2
|
+
-------------------
|
3
|
+
* Make verify_peer configurable and default it to false [#294](https://github.com/oesmith/puffing-billy/pull/294)
|
4
|
+
* Include pid in names of temporary files [#290](https://github.com/oesmith/puffing-billy/pull/290)
|
5
|
+
|
6
|
+
v2.3.1, 2020-03-19
|
7
|
+
-------------------
|
8
|
+
* Update min 'faraday' gem version required [#285](https://github.com/oesmith/puffing-billy/pull/285)
|
9
|
+
|
10
|
+
v2.3.0, 2019-12-26
|
11
|
+
-------------------
|
12
|
+
* Add `cache_whitelist` config option [#279](https://github.com/oesmith/puffing-billy/pull/279)
|
13
|
+
* Ignore certificate errors in Chrome [#280](https://github.com/oesmith/puffing-billy/pull/280)
|
14
|
+
|
15
|
+
v2.2.0, 2019-10-26
|
16
|
+
-------------------
|
17
|
+
* Before handle request method [#273](https://github.com/oesmith/puffing-billy/pull/273)
|
18
|
+
* Add Selenium headless driver [#272](https://github.com/oesmith/puffing-billy/pull/272)
|
19
|
+
|
20
|
+
v2.1.1, 2019-06-15
|
21
|
+
-------------------
|
22
|
+
* Add driver registration for chrome headless [#267](https://github.com/oesmith/puffing-billy/pull/267)
|
23
|
+
|
1
24
|
v2.1.0, 2019-03-17
|
2
25
|
-------------------
|
3
26
|
* Allow stubbing all request methods [#263](https://github.com/oesmith/puffing-billy/pull/263)
|
data/README.md
CHANGED
@@ -14,14 +14,14 @@ Billy spawns an EventMachine-based proxy server, which it uses to intercept
|
|
14
14
|
requests sent by your browser. It has a simple API for configuring which
|
15
15
|
requests need stubbing and what they should return.
|
16
16
|
|
17
|
-
Billy lets you test against known, repeatable data.
|
17
|
+
Billy lets you test against known, repeatable data. It also allows you to
|
18
18
|
test for failure cases. Does your twitter (or facebook/google/etc)
|
19
|
-
integration degrade gracefully when the API starts returning 500s?
|
19
|
+
integration degrade gracefully when the API starts returning 500s? Well now
|
20
20
|
you can test it!
|
21
21
|
|
22
22
|
```ruby
|
23
23
|
it 'should stub google' do
|
24
|
-
proxy.stub('http://www.google.com/').and_return(:
|
24
|
+
proxy.stub('http://www.google.com/').and_return(text: "I'm not Google!")
|
25
25
|
visit 'http://www.google.com/'
|
26
26
|
expect(page).to have_content("I'm not Google!")
|
27
27
|
end
|
@@ -32,21 +32,25 @@ You can also record HTTP interactions and replay them later. See
|
|
32
32
|
|
33
33
|
## Installation
|
34
34
|
|
35
|
-
Add this line to your application's Gemfile
|
35
|
+
Add this line to your application's `Gemfile`:
|
36
36
|
|
37
|
-
|
37
|
+
```ruby
|
38
|
+
gem 'puffing-billy', group: :test
|
39
|
+
```
|
38
40
|
|
39
41
|
And then execute:
|
40
42
|
|
41
|
-
|
43
|
+
```sh
|
44
|
+
$ bundle
|
45
|
+
```
|
42
46
|
|
43
47
|
Or install it yourself as:
|
44
48
|
|
45
|
-
|
46
|
-
|
47
|
-
|
49
|
+
```sh
|
50
|
+
$ gem install puffing-billy
|
51
|
+
```
|
48
52
|
|
49
|
-
|
53
|
+
## Setup for Capybara
|
50
54
|
|
51
55
|
In your `rails_helper.rb`:
|
52
56
|
|
@@ -55,7 +59,9 @@ require 'billy/capybara/rspec'
|
|
55
59
|
|
56
60
|
# select a driver for your chosen browser environment
|
57
61
|
Capybara.javascript_driver = :selenium_billy # Uses Firefox
|
62
|
+
# Capybara.javascript_driver = :selenium_headless_billy # Uses Firefox in headless mode
|
58
63
|
# Capybara.javascript_driver = :selenium_chrome_billy
|
64
|
+
# Capybara.javascript_driver = :selenium_chrome_headless_billy
|
59
65
|
# Capybara.javascript_driver = :apparition_billy
|
60
66
|
# Capybara.javascript_driver = :webkit_billy
|
61
67
|
# Capybara.javascript_driver = :poltergeist_billy
|
@@ -66,7 +72,7 @@ Capybara.javascript_driver = :selenium_billy # Uses Firefox
|
|
66
72
|
headless specs when using puffing-billy for other local rack apps.
|
67
73
|
See [this phantomjs issue](https://github.com/ariya/phantomjs/issues/11342) for any updates.
|
68
74
|
|
69
|
-
|
75
|
+
## Setup for Watir
|
70
76
|
|
71
77
|
In your `rails_helper.rb`:
|
72
78
|
|
@@ -79,87 +85,7 @@ require 'billy/watir/rspec'
|
|
79
85
|
# @browser = Billy::Browsers::Watir.new = :phantomjs
|
80
86
|
```
|
81
87
|
|
82
|
-
|
83
|
-
|
84
|
-
```ruby
|
85
|
-
# Stub and return text, json, jsonp (or anything else)
|
86
|
-
proxy.stub('http://example.com/text/').and_return(:text => 'Foobar')
|
87
|
-
proxy.stub('http://example.com/json/').and_return(:json => { :foo => 'bar' })
|
88
|
-
proxy.stub('http://example.com/jsonp/').and_return(:jsonp => { :foo => 'bar' })
|
89
|
-
proxy.stub('http://example.com/headers/').and_return({
|
90
|
-
:headers => { 'Access-Control-Allow-Origin' => '*' },
|
91
|
-
:json => { :foo => 'bar' }
|
92
|
-
})
|
93
|
-
proxy.stub('http://example.com/wtf/').and_return(:body => 'WTF!?', :content_type => 'text/wtf')
|
94
|
-
|
95
|
-
# Stub redirections and other return codes
|
96
|
-
proxy.stub('http://example.com/redirect/').and_return(:redirect_to => 'http://example.com/other')
|
97
|
-
proxy.stub('http://example.com/missing/').and_return(:code => 404, :body => 'Not found')
|
98
|
-
|
99
|
-
# Even stub HTTPS!
|
100
|
-
proxy.stub('https://example.com:443/secure/').and_return(:text => 'secrets!!1!')
|
101
|
-
|
102
|
-
# Pass a Proc (or Proc-style object) to create dynamic responses.
|
103
|
-
#
|
104
|
-
# The proc will be called with the following arguments:
|
105
|
-
# params: Query string parameters hash, CGI::escape-style
|
106
|
-
# headers: Headers hash
|
107
|
-
# body: Request body string
|
108
|
-
# url: The actual URL which was requested
|
109
|
-
# method: The HTTP verb which was requested
|
110
|
-
proxy.stub('https://example.com/proc/').and_return(Proc.new { |params, headers, body, url, method|
|
111
|
-
{
|
112
|
-
:code => 200,
|
113
|
-
:text => "Hello, #{params['name'][0]}"
|
114
|
-
}
|
115
|
-
})
|
116
|
-
|
117
|
-
# You can also use Puffing Billy to intercept requests and responses. Just pass
|
118
|
-
# a Proc and use the pass_request method. You can manipulate the request
|
119
|
-
# (headers, URL, HTTP method, etc) and also the response from the upstream
|
120
|
-
# server. The scope of the delivered callable is the user scope where
|
121
|
-
# it was defined. Setting method to 'all' will intercept requests regardless of
|
122
|
-
# the method.
|
123
|
-
proxy.stub('http://example.com/', method => 'all').and_return(Proc.new { |*args|
|
124
|
-
response = Billy.pass_request(*args)
|
125
|
-
response[:headers]['Content-Type'] = 'text/plain'
|
126
|
-
response[:body] = 'Hello World!'
|
127
|
-
response[:code] = 200
|
128
|
-
response
|
129
|
-
})
|
130
|
-
|
131
|
-
# Stub out a POST. Don't forget to allow a CORS request and set the method to 'post'
|
132
|
-
proxy.stub('http://example.com/api', :method => 'post').and_return(
|
133
|
-
:headers => { 'Access-Control-Allow-Origin' => '*' },
|
134
|
-
:code => 201
|
135
|
-
)
|
136
|
-
|
137
|
-
# Stub out an OPTIONS request. Set the headers to the values you require.
|
138
|
-
proxy.stub('http://example.com/api', :method => :options).and_return(
|
139
|
-
:headers => {
|
140
|
-
'Access-Control-Allow-Methods' => 'GET, PATCH, POST, PUT, OPTIONS',
|
141
|
-
'Access-Control-Allow-Headers' => 'X-Requested-With, X-Prototype-Version, Content-Type',
|
142
|
-
'Access-Control-Allow-Origin' => '*'
|
143
|
-
},
|
144
|
-
:code => 200
|
145
|
-
)
|
146
|
-
```
|
147
|
-
|
148
|
-
Stubs are reset between tests. Any requests that are not stubbed will be
|
149
|
-
proxied to the remote server.
|
150
|
-
|
151
|
-
If for any reason you'd need to reset stubs manually you can do it in two ways:
|
152
|
-
|
153
|
-
```ruby
|
154
|
-
# reset a single stub
|
155
|
-
example_stub = proxy.stub('http://example.com/text/').and_return(:text => 'Foobar')
|
156
|
-
proxy.unstub example_stub
|
157
|
-
|
158
|
-
# reset all stubs
|
159
|
-
proxy.reset
|
160
|
-
```
|
161
|
-
|
162
|
-
## Cucumber Usage
|
88
|
+
## Setup for Cucumber
|
163
89
|
|
164
90
|
An example feature:
|
165
91
|
|
@@ -171,7 +97,7 @@ Feature: Stubbing via billy
|
|
171
97
|
And a stub for google
|
172
98
|
```
|
173
99
|
|
174
|
-
### Capybara
|
100
|
+
### Setup for Cucumber + Capybara
|
175
101
|
|
176
102
|
In your `features/support/env.rb`:
|
177
103
|
|
@@ -191,7 +117,7 @@ Before('@billy') do
|
|
191
117
|
end
|
192
118
|
|
193
119
|
And /^a stub for google$/ do
|
194
|
-
proxy.stub('http://www.google.com/').and_return(:
|
120
|
+
proxy.stub('http://www.google.com/').and_return(text: "I'm not Google!")
|
195
121
|
visit 'http://www.google.com/'
|
196
122
|
expect(page).to have_content("I'm not Google!")
|
197
123
|
end
|
@@ -202,7 +128,7 @@ It's good practice to reset the driver after each scenario, so having an
|
|
202
128
|
stubs are reset after each step, so any usage of a stub should be in the
|
203
129
|
same step that it was created in.
|
204
130
|
|
205
|
-
### Watir
|
131
|
+
### Setup for Cucumber + Watir
|
206
132
|
|
207
133
|
In your `features/support/env.rb`:
|
208
134
|
|
@@ -222,7 +148,7 @@ Before('@billy') do
|
|
222
148
|
end
|
223
149
|
|
224
150
|
And /^a stub for google$/ do
|
225
|
-
proxy.stub('http://www.google.com/').and_return(:
|
151
|
+
proxy.stub('http://www.google.com/').and_return(text: "I'm not Google!")
|
226
152
|
@browser.goto 'http://www.google.com/'
|
227
153
|
expect(@browser.text).to eq("I'm not Google!")
|
228
154
|
end
|
@@ -234,6 +160,86 @@ Please see [this link](https://gist.github.com/sauy7/1b081266dd453a1b737b) for
|
|
234
160
|
details and report back to [Issue #49](https://github.com/oesmith/puffing-billy/issues/49)
|
235
161
|
if you get it fully working.
|
236
162
|
|
163
|
+
## Examples
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
# Stub and return text, json, jsonp (or anything else)
|
167
|
+
proxy.stub('http://example.com/text/').and_return(text: 'Foobar')
|
168
|
+
proxy.stub('http://example.com/json/').and_return(json: { foo: 'bar' })
|
169
|
+
proxy.stub('http://example.com/jsonp/').and_return(jsonp: { foo: 'bar' })
|
170
|
+
proxy.stub('http://example.com/headers/').and_return(
|
171
|
+
headers: { 'Access-Control-Allow-Origin' => '*' },
|
172
|
+
json: { foo: 'bar' }
|
173
|
+
)
|
174
|
+
proxy.stub('http://example.com/wtf/').and_return(body: 'WTF!?', content_type: 'text/wtf')
|
175
|
+
|
176
|
+
# Stub redirections and other return codes
|
177
|
+
proxy.stub('http://example.com/redirect/').and_return(redirect_to: 'http://example.com/other')
|
178
|
+
proxy.stub('http://example.com/missing/').and_return(code: 404, body: 'Not found')
|
179
|
+
|
180
|
+
# Even stub HTTPS!
|
181
|
+
proxy.stub('https://example.com:443/secure/').and_return(text: 'secrets!!1!')
|
182
|
+
|
183
|
+
# Pass a Proc (or Proc-style object) to create dynamic responses.
|
184
|
+
#
|
185
|
+
# The proc will be called with the following arguments:
|
186
|
+
# params: Query string parameters hash, CGI::escape-style
|
187
|
+
# headers: Headers hash
|
188
|
+
# body: Request body string
|
189
|
+
# url: The actual URL which was requested
|
190
|
+
# method: The HTTP verb which was requested
|
191
|
+
proxy.stub('https://example.com/proc/').and_return(Proc.new { |params, headers, body, url, method|
|
192
|
+
{
|
193
|
+
code: 200,
|
194
|
+
text: "Hello, #{params['name'][0]}"
|
195
|
+
}
|
196
|
+
})
|
197
|
+
|
198
|
+
# You can also use Puffing Billy to intercept requests and responses. Just pass
|
199
|
+
# a Proc and use the pass_request method. You can manipulate the request
|
200
|
+
# (headers, URL, HTTP method, etc) and also the response from the upstream
|
201
|
+
# server. The scope of the delivered callable is the user scope where
|
202
|
+
# it was defined. Setting method to 'all' will intercept requests regardless of
|
203
|
+
# the method.
|
204
|
+
proxy.stub('http://example.com/', method: 'all').and_return(Proc.new { |*args|
|
205
|
+
response = Billy.pass_request(*args)
|
206
|
+
response[:headers]['Content-Type'] = 'text/plain'
|
207
|
+
response[:body] = 'Hello World!'
|
208
|
+
response[:code] = 200
|
209
|
+
response
|
210
|
+
})
|
211
|
+
|
212
|
+
# Stub out a POST. Don't forget to allow a CORS request and set the method to 'post'
|
213
|
+
proxy.stub('http://example.com/api', method: 'post').and_return(
|
214
|
+
headers: { 'Access-Control-Allow-Origin' => '*' },
|
215
|
+
code: 201
|
216
|
+
)
|
217
|
+
|
218
|
+
# Stub out an OPTIONS request. Set the headers to the values you require.
|
219
|
+
proxy.stub('http://example.com/api', method: 'options').and_return(
|
220
|
+
headers: {
|
221
|
+
'Access-Control-Allow-Methods' => 'GET, PATCH, POST, PUT, OPTIONS',
|
222
|
+
'Access-Control-Allow-Headers' => 'X-Requested-With, X-Prototype-Version, Content-Type',
|
223
|
+
'Access-Control-Allow-Origin' => '*'
|
224
|
+
},
|
225
|
+
code: 200
|
226
|
+
)
|
227
|
+
```
|
228
|
+
|
229
|
+
Stubs are reset between tests. Any requests that are not stubbed will be
|
230
|
+
proxied to the remote server.
|
231
|
+
|
232
|
+
If for any reason you'd need to reset stubs manually you can do it in two ways:
|
233
|
+
|
234
|
+
```ruby
|
235
|
+
# reset a single stub
|
236
|
+
example_stub = proxy.stub('http://example.com/text/').and_return(text: 'Foobar')
|
237
|
+
proxy.unstub example_stub
|
238
|
+
|
239
|
+
# reset all stubs
|
240
|
+
proxy.reset
|
241
|
+
```
|
242
|
+
|
237
243
|
## Caching
|
238
244
|
|
239
245
|
Requests routed through the external proxy are cached.
|
@@ -246,7 +252,8 @@ In your `rails_helper.rb`:
|
|
246
252
|
|
247
253
|
```ruby
|
248
254
|
Billy.configure do |c|
|
249
|
-
c.whitelist = ['test.host', 'localhost', '127.0.0.1']
|
255
|
+
c.whitelist = ['test.host', 'localhost', '127.0.0.1'] # To replace the default whitelist, OR
|
256
|
+
c.whitelist << 'mynewhost.local' # to append a host without overriding the defaults.
|
250
257
|
end
|
251
258
|
```
|
252
259
|
|
@@ -260,6 +267,8 @@ server = Capybara.current_session.server
|
|
260
267
|
Billy.config.whitelist = ["#{server.host}:#{server.port}"]
|
261
268
|
```
|
262
269
|
|
270
|
+
If you would like to cache whitelisted URLs, you can define them in `c.cache_whitelist`. This is useful for scenarios where you may want to set `c.non_whitelisted_requests_disabled` to `true` to only allow whitelisted URLs to be accessed, but still allow specific URLs to be treated as if they were non-whitelisted.
|
271
|
+
|
263
272
|
If you want to use puffing-billy like you would [VCR](https://github.com/vcr/vcr)
|
264
273
|
you can turn on cache persistence. This way you don't have to manually mock out
|
265
274
|
everything as requests are automatically recorded and played back. With cache
|
@@ -289,6 +298,7 @@ Billy.configure do |c|
|
|
289
298
|
c.proxy_port = 12345 # defaults to random
|
290
299
|
c.proxied_request_host = nil
|
291
300
|
c.proxied_request_port = 80
|
301
|
+
c.cache_whitelist = []
|
292
302
|
c.record_requests = true # defaults to false
|
293
303
|
c.cache_request_body_methods = ['post', 'patch', 'put'] # defaults to ['post']
|
294
304
|
end
|
@@ -434,9 +444,6 @@ internally on this request, or your test ended before it could complete successf
|
|
434
444
|
|
435
445
|
`c.after_cache_handles_request` is used to configure a callback that can operate on the response after it has been retrieved from the cache but before it is returned. The callback receives the request and response as arguments, with a request object like: `{ method: method, url: url, headers: headers, body: body }`. An example usage would be manipulating the Access-Control-Allow-Origin header so that your test server doesn't always have to run on the same port in order to accept cached responses to CORS requests:
|
436
446
|
|
437
|
-
`c.use_ignore_params` is used to choose whether to use the ignore_params blacklist or the allow_params whitelist. Set to `true` to use `c.ignore_params`,
|
438
|
-
`false` to use `c.allow_params`
|
439
|
-
|
440
447
|
```
|
441
448
|
Billy.configure do |c|
|
442
449
|
...
|
@@ -454,6 +461,18 @@ Billy.configure do |c|
|
|
454
461
|
end
|
455
462
|
```
|
456
463
|
|
464
|
+
`c.use_ignore_params` is used to choose whether to use the ignore_params blacklist or the allow_params whitelist. Set to `true` to use `c.ignore_params`,
|
465
|
+
`false` to use `c.allow_params`
|
466
|
+
|
467
|
+
`c.before_handle_request` is used to modify `method`, `url`, `headers`, `body` before handle request by `stubs`, `cache` or `proxy`. Method accept 4 argumens and must return array of this arguments:
|
468
|
+
|
469
|
+
```
|
470
|
+
c.before_handle_request = proc { |method, url, headers, body|
|
471
|
+
filtered_body = JSON.dump(filter_secret_data(JSON.load(body)))
|
472
|
+
[method, url, headers, filtered_body]
|
473
|
+
}
|
474
|
+
```
|
475
|
+
|
457
476
|
`c.cache_simulates_network_delays` is used to add some delay before cache returns response. When set to `true`, cached requests will wait from configured delay time before responding. This allows to catch various race conditions in asynchronous front-end requests. The default is `false`.
|
458
477
|
|
459
478
|
`c.cache_simulates_network_delay_time` is used to configure time (in seconds) to wait until responding from cache. The default is `0.1`.
|
@@ -524,20 +543,23 @@ end
|
|
524
543
|
If you want the cache for each test to be independent, i.e. have it's own directory where the cache files are stored, you can do so.
|
525
544
|
|
526
545
|
### in Cucumber
|
527
|
-
|
546
|
+
|
547
|
+
use a `Before` tag:
|
528
548
|
```rb
|
529
549
|
Before('@javascript') do |scenario, block|
|
530
550
|
Billy.configure do |c|
|
531
551
|
feature_name = scenario.feature.name.underscore
|
532
552
|
scenario_name = scenario.name.underscore
|
533
553
|
c.cache_path = "features/support/fixtures/req_cache/#{feature_name}/#{scenario_name}/"
|
534
|
-
|
554
|
+
FileUtils.mkdir_p(Billy.config.cache_path) unless File.exist?(Billy.config.cache_path)
|
535
555
|
end
|
536
556
|
end
|
537
557
|
```
|
538
558
|
|
539
559
|
### in Rspec
|
540
|
-
|
560
|
+
|
561
|
+
use a `before(:each)` block:
|
562
|
+
|
541
563
|
```rb
|
542
564
|
RSpec.configure do |config|
|
543
565
|
base_cache_path = Billy.config.cache_path
|
@@ -558,7 +580,6 @@ RSpec.configure do |config|
|
|
558
580
|
end
|
559
581
|
```
|
560
582
|
|
561
|
-
|
562
583
|
## Stub requests recording
|
563
584
|
|
564
585
|
If you want to record requests to stubbed URIs, set the following configuration option:
|
@@ -602,6 +623,7 @@ and tell it to ignore SSL certificate warnings. See
|
|
602
623
|
to see how Billy's default drivers are configured.
|
603
624
|
|
604
625
|
## Working with VCR and Webmock
|
626
|
+
|
605
627
|
If you use VCR and Webmock elsewhere in your specs, you may need to disable them
|
606
628
|
for your specs utilizing Puffing Billy. To do so, you can configure your `rails_helper.rb`
|
607
629
|
as shown below:
|
@@ -631,7 +653,7 @@ Note that this approach may cause unexpected behavior if your backend sends the
|
|
631
653
|
|
632
654
|
### Raising errors from stubs
|
633
655
|
|
634
|
-
By default
|
656
|
+
By default Puffing Billy suppresses errors from stub-blocks.
|
635
657
|
To make it raise errors instead, add this test initializers:
|
636
658
|
|
637
659
|
```ruby
|
@@ -718,17 +740,24 @@ the system store. So after a run of your the suite only one certificate will be
|
|
718
740
|
left over. If this is not enough you can handling the cleanup again with a
|
719
741
|
custom on-after hook.
|
720
742
|
|
721
|
-
|
743
|
+
### TLS hostname validation
|
722
744
|
|
723
|
-
|
724
|
-
|
725
|
-
|
745
|
+
em-http-request was modified to emit a warning if being used without the TLS
|
746
|
+
``verify_peer`` option. Puffing Billy defaults to specifying ``verify_peer: false``
|
747
|
+
but you can now modify configuration to do peer verification. So if you've
|
748
|
+
gone to the trouble of setting up your own certificate authority and self-signed
|
749
|
+
certs you can enable it like so:
|
726
750
|
|
727
|
-
|
751
|
+
```ruby
|
752
|
+
Billy.configure do |c|
|
753
|
+
c.verify_peer = true
|
754
|
+
end
|
755
|
+
```
|
728
756
|
|
729
|
-
|
757
|
+
## Resources
|
730
758
|
|
731
|
-
|
759
|
+
* [Bring Ruby VCR to Javascript testing with Capybara and puffing-billy](https://dzone.com/articles/bring-ruby-vcr-javascript)
|
760
|
+
* [Clean-up unused cache files periodically with this config](https://github.com/oesmith/puffing-billy/pull/26#issuecomment-29905030)
|
732
761
|
|
733
762
|
## Contributing
|
734
763
|
|
@@ -740,5 +769,5 @@ custom on-after hook.
|
|
740
769
|
|
741
770
|
## TODO
|
742
771
|
|
743
|
-
1. Integration for test frameworks other than
|
772
|
+
1. Integration for test frameworks other than RSpec.
|
744
773
|
2. Show errors from the EventMachine reactor loop in the test output.
|
data/Rakefile
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<body>
|
3
|
+
<h1>Latest news</h1>
|
4
|
+
<div id="news"></div>
|
5
|
+
|
6
|
+
<script type='text/javascript' src='http://code.jquery.com/jquery-1.8.2.min.js'></script>
|
7
|
+
<script type='text/javascript'>
|
8
|
+
$(function () {
|
9
|
+
var url = 'https://blog.howmanyleft.co.uk/api/read/json?callback=?&type=text&num=3&filter=text';
|
10
|
+
$.getJSON(url, function (data) {
|
11
|
+
$.each(data.posts, function (idx, post) {
|
12
|
+
var title = post['regular-title'];
|
13
|
+
var href = post['url-with-slug'];
|
14
|
+
var body = post['regular-body'];
|
15
|
+
$('#news').append(
|
16
|
+
'<h3><a href="' + href + '">' + title + '</a></h3>' +
|
17
|
+
'<p>' + body + '</p>');
|
18
|
+
});
|
19
|
+
});
|
20
|
+
})
|
21
|
+
</script>
|
22
|
+
</body>
|
@@ -47,21 +47,50 @@ module Billy
|
|
47
47
|
|
48
48
|
def self.register_selenium_driver
|
49
49
|
::Capybara.register_driver :selenium_billy do |app|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
50
|
+
options = build_selenium_options_for_firefox
|
51
|
+
capabilities = Selenium::WebDriver::Remote::Capabilities.firefox(accept_insecure_certs: true)
|
52
|
+
|
53
|
+
::Capybara::Selenium::Driver.new(app, options: options, desired_capabilities: capabilities)
|
54
|
+
end
|
55
|
+
|
56
|
+
::Capybara.register_driver :selenium_headless_billy do |app|
|
57
|
+
options = build_selenium_options_for_firefox.tap do |opts|
|
58
|
+
opts.add_argument '-headless'
|
59
|
+
end
|
60
|
+
capabilities = Selenium::WebDriver::Remote::Capabilities.firefox(accept_insecure_certs: true)
|
61
|
+
|
62
|
+
::Capybara::Selenium::Driver.new(app, options: options, desired_capabilities: capabilities)
|
56
63
|
end
|
57
64
|
|
58
65
|
::Capybara.register_driver :selenium_chrome_billy do |app|
|
59
66
|
options = Selenium::WebDriver::Chrome::Options.new
|
67
|
+
options.add_argument('--ignore-certificate-errors')
|
60
68
|
options.add_argument("--proxy-server=#{Billy.proxy.host}:#{Billy.proxy.port}")
|
61
69
|
|
62
70
|
::Capybara::Selenium::Driver.new(
|
63
|
-
app,
|
64
|
-
|
71
|
+
app,
|
72
|
+
browser: :chrome,
|
73
|
+
options: options,
|
74
|
+
clear_local_storage: true,
|
75
|
+
clear_session_storage: true
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
::Capybara.register_driver :selenium_chrome_headless_billy do |app|
|
80
|
+
options = Selenium::WebDriver::Chrome::Options.new
|
81
|
+
options.headless!
|
82
|
+
options.add_argument('--enable-features=NetworkService,NetworkServiceInProcess')
|
83
|
+
options.add_argument('--ignore-certificate-errors')
|
84
|
+
options.add_argument("--proxy-server=#{Billy.proxy.host}:#{Billy.proxy.port}")
|
85
|
+
options.add_argument('--disable-gpu') if Gem.win_platform?
|
86
|
+
options.add_argument('--no-sandbox') if ENV['CI']
|
87
|
+
|
88
|
+
::Capybara::Selenium::Driver.new(
|
89
|
+
app,
|
90
|
+
browser: :chrome,
|
91
|
+
options: options,
|
92
|
+
clear_local_storage: true,
|
93
|
+
clear_session_storage: true
|
65
94
|
)
|
66
95
|
end
|
67
96
|
end
|
@@ -73,6 +102,17 @@ module Billy
|
|
73
102
|
end
|
74
103
|
end
|
75
104
|
end
|
105
|
+
|
106
|
+
def self.build_selenium_options_for_firefox
|
107
|
+
profile = Selenium::WebDriver::Firefox::Profile.new.tap do |prof|
|
108
|
+
prof.assume_untrusted_certificate_issuer = false
|
109
|
+
prof.proxy = Selenium::WebDriver::Proxy.new(
|
110
|
+
http: "#{Billy.proxy.host}:#{Billy.proxy.port}",
|
111
|
+
ssl: "#{Billy.proxy.host}:#{Billy.proxy.port}")
|
112
|
+
end
|
113
|
+
|
114
|
+
Selenium::WebDriver::Firefox::Options.new(profile: profile)
|
115
|
+
end
|
76
116
|
end
|
77
117
|
end
|
78
118
|
end
|
data/lib/billy/browsers/watir.rb
CHANGED
data/lib/billy/config.rb
CHANGED
@@ -6,12 +6,12 @@ module Billy
|
|
6
6
|
DEFAULT_WHITELIST = ['127.0.0.1', 'localhost']
|
7
7
|
RANDOM_AVAILABLE_PORT = 0 # https://github.com/eventmachine/eventmachine/wiki/FAQ#wiki-can-i-start-a-server-on-a-random-available-port
|
8
8
|
|
9
|
-
attr_accessor :logger, :cache, :cache_request_headers, :whitelist, :path_blacklist, :ignore_params, :allow_params,
|
9
|
+
attr_accessor :logger, :cache, :cache_request_headers, :whitelist, :cache_whitelist, :path_blacklist, :ignore_params, :allow_params,
|
10
10
|
:persist_cache, :ignore_cache_port, :non_successful_cache_disabled, :non_successful_error_level,
|
11
|
-
:non_whitelisted_requests_disabled, :cache_path, :certs_path, :proxy_host, :proxy_port, :proxied_request_inactivity_timeout,
|
11
|
+
:non_whitelisted_requests_disabled, :cache_path, :certs_path, :verify_peer, :proxy_host, :proxy_port, :proxied_request_inactivity_timeout,
|
12
12
|
:proxied_request_connect_timeout, :dynamic_jsonp, :dynamic_jsonp_keys, :dynamic_jsonp_callback_name, :merge_cached_responses_whitelist,
|
13
13
|
:strip_query_params, :proxied_request_host, :proxied_request_port, :cache_request_body_methods, :after_cache_handles_request,
|
14
|
-
:cache_simulates_network_delays, :cache_simulates_network_delay_time, :record_requests, :record_stub_requests, :use_ignore_params
|
14
|
+
:cache_simulates_network_delays, :cache_simulates_network_delay_time, :record_requests, :record_stub_requests, :use_ignore_params, :before_handle_request
|
15
15
|
|
16
16
|
def initialize
|
17
17
|
@logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
|
@@ -21,6 +21,7 @@ module Billy
|
|
21
21
|
def reset
|
22
22
|
@cache = true
|
23
23
|
@cache_request_headers = false
|
24
|
+
@cache_whitelist = []
|
24
25
|
@whitelist = DEFAULT_WHITELIST
|
25
26
|
@path_blacklist = []
|
26
27
|
@merge_cached_responses_whitelist = []
|
@@ -36,6 +37,7 @@ module Billy
|
|
36
37
|
@non_whitelisted_requests_disabled = false
|
37
38
|
@cache_path = File.join(Dir.tmpdir, 'puffing-billy')
|
38
39
|
@certs_path = File.join(Dir.tmpdir, 'puffing-billy', 'certs')
|
40
|
+
@verify_peer = false
|
39
41
|
@proxy_host = 'localhost'
|
40
42
|
@proxy_port = RANDOM_AVAILABLE_PORT
|
41
43
|
@proxied_request_inactivity_timeout = 10 # defaults from https://github.com/igrigorik/em-http-request/wiki/Redirects-and-Timeouts
|
@@ -50,6 +52,7 @@ module Billy
|
|
50
52
|
@record_requests = false
|
51
53
|
@record_stub_requests = false
|
52
54
|
@use_ignore_params = true
|
55
|
+
@before_handle_request = nil
|
53
56
|
end
|
54
57
|
end
|
55
58
|
|
@@ -16,6 +16,10 @@ module Billy
|
|
16
16
|
opts = { inactivity_timeout: Billy.config.proxied_request_inactivity_timeout,
|
17
17
|
connect_timeout: Billy.config.proxied_request_connect_timeout }
|
18
18
|
|
19
|
+
if url =~ /^https/
|
20
|
+
opts.merge!({tls: {verify_peer: Billy.config.verify_peer}})
|
21
|
+
end
|
22
|
+
|
19
23
|
if Billy.config.proxied_request_host && !bypass_internal_proxy?(url)
|
20
24
|
opts.merge!({ proxy: { host: Billy.config.proxied_request_host,
|
21
25
|
port: Billy.config.proxied_request_port }} )
|
@@ -110,7 +114,7 @@ module Billy
|
|
110
114
|
|
111
115
|
url = Addressable::URI.parse(url)
|
112
116
|
# Cache the responses if they aren't whitelisted host[:port]s but always cache blacklisted paths on any hosts
|
113
|
-
cacheable_status?(status) && (!whitelisted_url?(url) || blacklisted_path?(url.path))
|
117
|
+
cacheable_status?(status) && (!whitelisted_url?(url) || blacklisted_path?(url.path) || cache_whitelisted_url?(url))
|
114
118
|
end
|
115
119
|
|
116
120
|
def whitelisted_url?(url)
|
@@ -123,6 +127,16 @@ module Billy
|
|
123
127
|
end
|
124
128
|
end
|
125
129
|
|
130
|
+
def cache_whitelisted_url?(url)
|
131
|
+
Billy.config.cache_whitelist.any? do |value|
|
132
|
+
if value.is_a?(Regexp)
|
133
|
+
url.to_s =~ value || url.omit(:port).to_s =~ value
|
134
|
+
else
|
135
|
+
value =~ /^#{url.host}(?::#{url.port})?$/
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
126
140
|
def blacklisted_path?(path)
|
127
141
|
!Billy.config.path_blacklist.index { |bl| bl.is_a?(Regexp) ? path =~ bl : path.include?(bl) }.nil?
|
128
142
|
end
|
@@ -17,6 +17,10 @@ module Billy
|
|
17
17
|
def handle_request(method, url, headers, body)
|
18
18
|
request = request_log.record(method, url, headers, body)
|
19
19
|
|
20
|
+
if Billy.config.before_handle_request
|
21
|
+
method, url, headers, body = Billy.config.before_handle_request.call(method, url, headers, body)
|
22
|
+
end
|
23
|
+
|
20
24
|
# Process the handlers by order of importance
|
21
25
|
[:stubs, :cache, :proxy].each do |key|
|
22
26
|
if (response = handlers[key].handle_request(method, url, headers, body))
|
@@ -27,7 +27,7 @@ module Billy
|
|
27
27
|
# and ensure the location is safely created. Pass
|
28
28
|
# back the resulting path.
|
29
29
|
def write_file(name, contents)
|
30
|
-
path = File.join(Billy.config.certs_path, name)
|
30
|
+
path = File.join(Billy.config.certs_path, "#{Process.pid}-#{name}")
|
31
31
|
FileUtils.mkdir_p(File.dirname(path))
|
32
32
|
File.write(path, contents)
|
33
33
|
path
|
data/lib/billy/version.rb
CHANGED
data/puffing-billy.gemspec
CHANGED
@@ -17,19 +17,18 @@ Gem::Specification.new do |gem|
|
|
17
17
|
|
18
18
|
gem.add_development_dependency 'rspec'
|
19
19
|
gem.add_development_dependency 'thin'
|
20
|
-
gem.add_development_dependency 'faraday'
|
21
|
-
gem.add_development_dependency 'poltergeist'
|
20
|
+
gem.add_development_dependency 'faraday', '>= 0.9.0'
|
22
21
|
gem.add_development_dependency 'apparition'
|
23
|
-
# selenium-webdriver 3.8 drops support for PhantomJS
|
24
|
-
gem.add_development_dependency 'selenium-webdriver', '<= 3.7.0'
|
25
22
|
gem.add_development_dependency 'capybara'
|
26
|
-
gem.add_development_dependency '
|
23
|
+
gem.add_development_dependency 'selenium-webdriver'
|
27
24
|
gem.add_development_dependency 'rack'
|
25
|
+
gem.add_development_dependency 'rake'
|
28
26
|
gem.add_development_dependency 'guard'
|
29
27
|
gem.add_development_dependency 'rb-inotify'
|
30
28
|
gem.add_development_dependency 'pry'
|
31
29
|
gem.add_development_dependency 'cucumber'
|
32
30
|
gem.add_development_dependency 'watir', '~> 6.10.0'
|
31
|
+
gem.add_development_dependency 'webdrivers'
|
33
32
|
gem.add_runtime_dependency 'addressable', '~> 2.5'
|
34
33
|
gem.add_runtime_dependency 'eventmachine', '~> 1.2'
|
35
34
|
gem.add_runtime_dependency 'em-synchrony'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Capybara drivers', type: :feature, js: true do
|
4
|
+
it 'allows HTTPS calls' do
|
5
|
+
proxy.stub('https://blog.howmanyleft.co.uk:443/api/read/json').and_return(
|
6
|
+
jsonp: {
|
7
|
+
posts: [
|
8
|
+
{
|
9
|
+
'regular-title' => 'News Item 1',
|
10
|
+
'url-with-slug' => 'http://example.com/news/1',
|
11
|
+
'regular-body' => 'News item 1 content here'
|
12
|
+
},
|
13
|
+
{
|
14
|
+
'regular-title' => 'News Item 2',
|
15
|
+
'url-with-slug' => 'http://example.com/news/2',
|
16
|
+
'regular-body' => 'News item 2 content here'
|
17
|
+
}
|
18
|
+
]
|
19
|
+
})
|
20
|
+
|
21
|
+
visit '/tumblr_api_https.html'
|
22
|
+
|
23
|
+
expect(page).to have_link('News Item 1', href: 'http://example.com/news/1')
|
24
|
+
expect(page).to have_content('News item 1 content here')
|
25
|
+
expect(page).to have_link('News Item 2', href: 'http://example.com/news/2')
|
26
|
+
expect(page).to have_content('News item 2 content here')
|
27
|
+
end
|
28
|
+
end
|
@@ -175,6 +175,34 @@ describe Billy::ProxyHandler do
|
|
175
175
|
request[:body])
|
176
176
|
end
|
177
177
|
|
178
|
+
it 'does NOT cache the response if the host is whitelisted but not cache_whitelisted' do
|
179
|
+
uri = Addressable::URI.parse(request[:url])
|
180
|
+
|
181
|
+
expect(subject).to receive(:allowed_response_code?).and_return(true)
|
182
|
+
expect(Billy.config).to receive(:whitelist).and_return([uri.host])
|
183
|
+
expect(Billy.config).to receive(:cache_whitelist).and_return([])
|
184
|
+
|
185
|
+
expect(Billy::Cache.instance).not_to receive(:store)
|
186
|
+
subject.handle_request(request[:method],
|
187
|
+
request[:url],
|
188
|
+
request[:headers],
|
189
|
+
request[:body])
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'caches the response if the host is whitelisted AND cache_whitelisted' do
|
193
|
+
uri = Addressable::URI.parse(request[:url])
|
194
|
+
|
195
|
+
expect(subject).to receive(:allowed_response_code?).and_return(true)
|
196
|
+
expect(Billy.config).to receive(:whitelist).and_return([uri.host])
|
197
|
+
expect(Billy.config).to receive(:cache_whitelist).and_return([uri.host])
|
198
|
+
|
199
|
+
expect(Billy::Cache.instance).to receive(:store)
|
200
|
+
subject.handle_request(request[:method],
|
201
|
+
request[:url],
|
202
|
+
request[:headers],
|
203
|
+
request[:body])
|
204
|
+
end
|
205
|
+
|
178
206
|
it 'uses the timeouts defined in configuration' do
|
179
207
|
allow(Billy.config).to receive(:proxied_request_inactivity_timeout).and_return(42)
|
180
208
|
allow(Billy.config).to receive(:proxied_request_connect_timeout).and_return(24)
|
@@ -128,6 +128,28 @@ describe Billy::RequestHandler do
|
|
128
128
|
allow(stub_handler).to receive(:handle_request).and_raise("Any Stub Error")
|
129
129
|
expect(subject.handle_request(*args)).to eql(error: "Any Stub Error")
|
130
130
|
end
|
131
|
+
|
132
|
+
context 'before_handle_request activated' do
|
133
|
+
before do
|
134
|
+
handle_request = proc { |method, url, headers, body|
|
135
|
+
[method, url, headers, "#{body}_modified"]
|
136
|
+
}
|
137
|
+
allow(Billy::config).to receive(:before_handle_request).and_return(handle_request)
|
138
|
+
end
|
139
|
+
|
140
|
+
after do
|
141
|
+
allow(Billy::config).to receive(:before_handle_request).and_call_original
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'modify request before handling' do
|
145
|
+
new_args = %w(get url headers body_modified)
|
146
|
+
expect(stub_handler).to receive(:handle_request).with(*new_args)
|
147
|
+
expect(cache_handler).to receive(:handle_request).with(*new_args).and_return('bar')
|
148
|
+
expect(proxy_handler).to_not receive(:handle_request)
|
149
|
+
expect(subject.handle_request(*args)).to eql 'bar'
|
150
|
+
expect(subject.requests).to eql([{status: :complete, handler: :cache, method: 'get', url: 'url', headers: 'headers', body: 'body'}])
|
151
|
+
end
|
152
|
+
end
|
131
153
|
end
|
132
154
|
|
133
155
|
describe '#stubs' do
|
data/spec/lib/proxy_spec.rb
CHANGED
@@ -118,6 +118,29 @@ shared_examples_for 'a cache' do
|
|
118
118
|
end
|
119
119
|
end
|
120
120
|
|
121
|
+
context 'cache_whitelist GET requests' do
|
122
|
+
before do
|
123
|
+
Billy.config.whitelist = [http.host]
|
124
|
+
Billy.config.cache_whitelist = [http.host]
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should be cached' do
|
128
|
+
assert_cached_url
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'with ports' do
|
132
|
+
before do
|
133
|
+
rack_app_url = URI(http.url_prefix)
|
134
|
+
Billy.config.whitelist = ["#{rack_app_url.host}:#{rack_app_url.port + 1}"]
|
135
|
+
Billy.config.cache_whitelist = Billy.config.whitelist
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should be cached' do
|
139
|
+
assert_cached_url
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
121
144
|
context 'ignore_params GET requests' do
|
122
145
|
before do
|
123
146
|
Billy.config.ignore_params = ['/analytics']
|
@@ -232,7 +255,7 @@ shared_examples_for 'a cache' do
|
|
232
255
|
|
233
256
|
it 'should raise error when disabled' do
|
234
257
|
# TODO: Suppress stderr output: https://gist.github.com/adamstegman/926858
|
235
|
-
expect { http.get('/foo') }.to raise_error(Faraday::
|
258
|
+
expect { http.get('/foo') }.to raise_error(Faraday::ConnectionFailed, 'end of file reached')
|
236
259
|
end
|
237
260
|
end
|
238
261
|
|
@@ -261,7 +284,7 @@ shared_examples_for 'a cache' do
|
|
261
284
|
end
|
262
285
|
|
263
286
|
it 'should raise error for non-successful responses when :error' do
|
264
|
-
expect { http_error.get('/foo') }.to raise_error(Faraday::
|
287
|
+
expect { http_error.get('/foo') }.to raise_error(Faraday::ConnectionFailed)
|
265
288
|
end
|
266
289
|
end
|
267
290
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -6,11 +6,17 @@ require 'billy/watir/rspec'
|
|
6
6
|
require 'rack'
|
7
7
|
require 'logger'
|
8
8
|
require 'fileutils'
|
9
|
+
require 'webdrivers'
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
$stdout.puts `#{::Selenium::WebDriver::Chrome::Service.driver_path.call} --version` if ENV['CI']
|
12
|
+
|
13
|
+
browser = Billy::Browsers::Watir.new :chrome
|
14
|
+
|
15
|
+
Capybara.configure do |config|
|
16
|
+
config.app = Rack::Directory.new(File.expand_path('../../examples', __FILE__))
|
17
|
+
config.server = :webrick
|
18
|
+
config.javascript_driver = :selenium_chrome_headless_billy
|
19
|
+
end
|
14
20
|
|
15
21
|
Billy.configure do |config|
|
16
22
|
config.logger = Logger.new(File.expand_path('../../log/test.log', __FILE__))
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puffing-billy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Olly Smith
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -44,16 +44,16 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 0.9.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 0.9.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: apparition
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: capybara
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -82,20 +82,6 @@ dependencies:
|
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: selenium-webdriver
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "<="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 3.7.0
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "<="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 3.7.0
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: capybara
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
87
|
- - ">="
|
@@ -109,21 +95,21 @@ dependencies:
|
|
109
95
|
- !ruby/object:Gem::Version
|
110
96
|
version: '0'
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
98
|
+
name: rack
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
114
100
|
requirements:
|
115
|
-
- - "
|
101
|
+
- - ">="
|
116
102
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
103
|
+
version: '0'
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
107
|
requirements:
|
122
|
-
- - "
|
108
|
+
- - ">="
|
123
109
|
- !ruby/object:Gem::Version
|
124
|
-
version: '
|
110
|
+
version: '0'
|
125
111
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
112
|
+
name: rake
|
127
113
|
requirement: !ruby/object:Gem::Requirement
|
128
114
|
requirements:
|
129
115
|
- - ">="
|
@@ -206,6 +192,20 @@ dependencies:
|
|
206
192
|
- - "~>"
|
207
193
|
- !ruby/object:Gem::Version
|
208
194
|
version: 6.10.0
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: webdrivers
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
209
209
|
- !ruby/object:Gem::Dependency
|
210
210
|
name: addressable
|
211
211
|
requirement: !ruby/object:Gem::Requirement
|
@@ -336,6 +336,7 @@ files:
|
|
336
336
|
- examples/post_api.html
|
337
337
|
- examples/preflight_request.html
|
338
338
|
- examples/tumblr_api.html
|
339
|
+
- examples/tumblr_api_https.html
|
339
340
|
- lib/billy.rb
|
340
341
|
- lib/billy/browsers/capybara.rb
|
341
342
|
- lib/billy/browsers/watir.rb
|
@@ -375,6 +376,7 @@ files:
|
|
375
376
|
- spec/features/examples/post_api_spec.rb
|
376
377
|
- spec/features/examples/preflight_request_spec.rb
|
377
378
|
- spec/features/examples/tumblr_api_spec.rb
|
379
|
+
- spec/lib/billy/browsers/capybara_spec.rb
|
378
380
|
- spec/lib/billy/cache_spec.rb
|
379
381
|
- spec/lib/billy/handlers/cache_handler_spec.rb
|
380
382
|
- spec/lib/billy/handlers/handler_spec.rb
|
@@ -421,6 +423,7 @@ test_files:
|
|
421
423
|
- spec/features/examples/post_api_spec.rb
|
422
424
|
- spec/features/examples/preflight_request_spec.rb
|
423
425
|
- spec/features/examples/tumblr_api_spec.rb
|
426
|
+
- spec/lib/billy/browsers/capybara_spec.rb
|
424
427
|
- spec/lib/billy/cache_spec.rb
|
425
428
|
- spec/lib/billy/handlers/cache_handler_spec.rb
|
426
429
|
- spec/lib/billy/handlers/handler_spec.rb
|