puffing-billy 2.1.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|