capybara-webmock 0.4.4 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a1511010285eeb520105986a627bf40f2957fcaa
4
- data.tar.gz: a12bff84fc592bfb31774cd2c3eeb9d691d074f9
3
+ metadata.gz: 81553b5b1145d09248402a0c1b895df288b5e51c
4
+ data.tar.gz: 64dc84c9c2b55c7eb70f447be825fa58f6e17f43
5
5
  SHA512:
6
- metadata.gz: 6861262f85e84d138a83dca1c8152b601506cd702af8c58ca6cebf0b75b8c695953f53ae25338c43f253192f908bc72b2c52c31d7155f539cfed6eb400ae9799
7
- data.tar.gz: af780a9538de5a69a5a1686d4b7b8c144f17d0939b6511dfc3912611d81734c43e143207724600d174c621fa70bd42eb6ed826383d44492169531f2346ae6fb1
6
+ metadata.gz: 399fa5e03d96661d9b1370b8d0be2709a6d9ca923532fceee1ed683df95f78452a4115c95a94d2685c198614f8b6a2e710a759043163f5333cac0c4040de45be
7
+ data.tar.gz: d2558a7df70f91d5dbd6db30afa2c7fece4c0d544d2686cc4782700560257348051a0eac3f3ee882943b7d791e4881272d3fb1c3b669ea3395b024e57b9ed833
@@ -0,0 +1,9 @@
1
+ version: 2
2
+ jobs:
3
+ build:
4
+ docker:
5
+ - image: circleci/ruby:2.5.1
6
+ steps:
7
+ - checkout
8
+ - run: bundle install
9
+ - run: rake
data/README.md CHANGED
@@ -18,10 +18,10 @@ Use of this gem can significantly speed up the test suite. No more waiting on
18
18
  irrelevant external requests.
19
19
 
20
20
  `localhost`, `127.0.0.1`, `*.lvh.me`, and `lvh.me` are the only whitelisted
21
- domains. Custom domain support is a planned feature.
21
+ domains.
22
22
 
23
- This gem currently supports Ruby on Rails applications
24
- using the Selenium Firefox and Chrome drivers.
23
+ This gem currently supports Ruby on Rails applications using the Selenium
24
+ Firefox and Chrome drivers.
25
25
 
26
26
  ### Installation
27
27
 
@@ -37,7 +37,7 @@ And then execute:
37
37
  $ bundle
38
38
  ```
39
39
 
40
- Or install it yourself as:
40
+ Or install it via the command line:
41
41
 
42
42
  ```
43
43
  $ gem install capybara-webmock
@@ -57,8 +57,10 @@ Then in your RSpec configuration:
57
57
  # spec/spec_helper.rb
58
58
 
59
59
  RSpec.configure do |config|
60
- config.before(:suite) do
61
- Capybara::Webmock.start
60
+ config.before(:each) do |example|
61
+ if example.metadata[:type] == :feature
62
+ Capybara::Webmock.start
63
+ end
62
64
  end
63
65
 
64
66
  config.after(:suite) do
@@ -67,18 +69,6 @@ RSpec.configure do |config|
67
69
  end
68
70
  ```
69
71
 
70
- Or, your Cucumber configuration:
71
-
72
- ```ruby
73
- # features/support/env.rb
74
-
75
- Capybara::Webmock.start
76
-
77
- at_exit do
78
- Capybara::Webmock.stop
79
- end
80
- ```
81
-
82
72
  Then use the `capybara_webmock` JavaScript driver:
83
73
 
84
74
  ```ruby
@@ -109,17 +99,48 @@ with the following configuration:
109
99
  Capybara::Webmock.port_number = 8080
110
100
  ```
111
101
 
102
+ During each test, you can inspect the list of proxied requests:
103
+
104
+ ```ruby
105
+ it 'makes a request to /somewhere when the user visits the page' do
106
+ visit "/some-page"
107
+ expect(Capybara::Webmock.proxied_requests.any?{|req| req.path == "/somewhere" }).to be
108
+ end
109
+ ```
110
+
112
111
  ### Development
113
112
 
114
- After checking out the repo, run `bin/setup` to install dependencies. Then, run
115
- `rake spec` to run the tests. You can also run `bin/console` for an interactive
116
- prompt that will allow you to experiment.
113
+ After pulling down the repo, install dependencies:
114
+
115
+ ```
116
+ $ bin/setup
117
+ ```
118
+
119
+ Then, run the tests:
120
+
121
+ ```
122
+ $ rake spec
123
+ ```
124
+
125
+ For an interactive prompt that will allow you to experiment, run:
126
+
127
+ ```
128
+ $ bin/console
129
+ ```
117
130
 
118
- To install this gem onto your local machine, run `bundle exec rake install`. To
119
- release a new version, update the version number in `version.rb`, and then run
120
- `bundle exec rake release`, which will create a git tag for the version, push
121
- git commits and tags, and push the `.gem` file to
122
- [rubygems.org](https://rubygems.org).
131
+ To install your development gem onto your local machine, run:
132
+
133
+ ```
134
+ $ bundle exec rake install
135
+ ```
136
+
137
+ To release a new version, update the version number in `version.rb`, then
138
+ update the git tag, push commits and tags, and publish the gem to
139
+ [rubygems.org](https://rubygems.org) with:
140
+
141
+ ```
142
+ $ bundle exec rake release
143
+ ```
123
144
 
124
145
  ### Contributing
125
146
 
@@ -1,26 +1,59 @@
1
+ require 'open3'
2
+ require 'fileutils'
3
+ require 'socket'
1
4
  require 'capybara'
2
5
  require 'selenium-webdriver'
3
6
  require 'capybara/webmock/version'
4
7
  require 'capybara/webmock/proxy'
8
+ require 'capybara/webmock/proxied_request'
5
9
 
6
10
  module Capybara
7
11
  module Webmock
8
12
  class << self
9
-
10
- attr_accessor :port_number
13
+ attr_accessor :port_number, :pid_file, :kill_timeout, :start_timeout
11
14
 
12
15
  def start
13
- log_file = File.join('log', 'test.log')
14
- gem_path = File.dirname(__FILE__)
15
- proxy_file = File.join(gem_path, 'webmock', 'config.ru')
16
- IO.popen("PROXY_PORT_NUMBER=#{port_number} rackup #{proxy_file} >> #{log_file} 2>&1")
16
+ if @pid.nil?
17
+ kill_old_process
18
+ gem_path = File.dirname(__FILE__)
19
+ proxy_file = File.join(gem_path, 'webmock', 'config.ru')
20
+ stdin, stdout, wait_thr = Open3.popen2e({ "PROXY_PORT_NUMBER" => port_number.to_s }, "rackup", proxy_file)
21
+ stdin.close
22
+ @stdout = stdout
23
+ @pid = wait_thr[:pid]
24
+ write_pid_file
25
+ wait_for_proxy_start
26
+ end
27
+
28
+ reset
17
29
  end
18
30
 
19
- def stop
20
- if File.exist?(Capybara::Webmock::Proxy::PID_FILE)
21
- rack_pid = File.read(Capybara::Webmock::Proxy::PID_FILE).to_i
22
- Process.kill('HUP', rack_pid)
31
+ def reset
32
+ get_output_nonblocking
33
+ @output_buf = ""
34
+ end
35
+
36
+ def proxied_requests
37
+ @output_buf += get_output_nonblocking
38
+
39
+ matches = @output_buf.sub(/\n[^\n]+\z/, '').split("\n").map do |line|
40
+ match = /\A(.+) -> (.+)\Z/.match(line)
41
+ next nil unless match
42
+ match.captures
23
43
  end
44
+
45
+ matches.compact.map{ |raw_referrer, raw_uri| ProxiedRequest.new(raw_referrer, raw_uri) }
46
+ end
47
+
48
+ def stop
49
+ return if @pid.nil?
50
+
51
+ @stdout.close
52
+ kill_process(@pid)
53
+ remove_pid_file
54
+
55
+ @pid = nil
56
+ @stdout = nil
24
57
  end
25
58
 
26
59
  def firefox_profile
@@ -35,26 +68,103 @@ module Capybara
35
68
  end
36
69
 
37
70
  def chrome_options
38
- ::Selenium::WebDriver::Chrome::Options.new.tap do |options|
39
- options.add_argument("--proxy-server=127.0.0.1:#{port_number}")
40
- end
71
+ { args: "proxy-server=127.0.0.1:#{port_number}" }
41
72
  end
42
73
 
43
74
  def phantomjs_options
44
75
  ["--proxy=127.0.0.1:#{port_number}"]
45
76
  end
77
+
78
+ private
79
+
80
+ def wait_for_proxy_start
81
+ connected = false
82
+ (1..start_timeout).each do
83
+ begin
84
+ Socket.tcp("127.0.0.1", port_number, connect_timeout: 1) {}
85
+ connected = true
86
+ break
87
+ rescue => e
88
+ sleep 1
89
+ end
90
+ end
91
+
92
+ unless connected
93
+ raise "Unable to connect to capybara-webmock proxy on #{port_number}"
94
+ end
95
+ end
96
+
97
+ def get_output_nonblocking
98
+ buf = ""
99
+
100
+ while true
101
+ begin
102
+ output = @stdout.read_nonblock(1024)
103
+ break if output == ""
104
+ buf += output
105
+ rescue IO::WaitReadable
106
+ break
107
+ end
108
+ end
109
+
110
+ buf
111
+ end
112
+
113
+ def kill_old_process
114
+ return unless File.exists?(pid_file)
115
+ old_pid = File.read(pid_file).to_i
116
+ kill_process(old_pid) if old_pid > 1
117
+ remove_pid_file
118
+ end
119
+
120
+ def kill_process(pid)
121
+ Process.kill('HUP', pid) if process_alive?(pid)
122
+
123
+ (1..kill_timeout).each do
124
+ sleep(1) if process_alive?(pid)
125
+ end
126
+
127
+ Process.kill('KILL', pid) if process_alive?(pid)
128
+
129
+ (1..kill_timeout).each do
130
+ sleep(1) if process_alive?(pid)
131
+ end
132
+
133
+ if process_alive?(pid)
134
+ raise "Unable to kill capybara-webmock process with PID #{pid}"
135
+ end
136
+ end
137
+
138
+ def process_alive?(pid)
139
+ !!Process.kill(0, pid) rescue false
140
+ end
141
+
142
+ def write_pid_file
143
+ raise "Pid file #{pid_file} already exists" if File.exists?(pid_file)
144
+ FileUtils.mkdir_p(File.dirname(pid_file))
145
+ File.write(pid_file, @pid.to_s)
146
+ end
147
+
148
+ def remove_pid_file
149
+ File.delete(pid_file) if File.exists?(pid_file)
150
+ end
46
151
  end
47
152
  end
48
153
  end
49
154
 
50
155
  Capybara::Webmock.port_number ||= 9292
156
+ Capybara::Webmock.pid_file ||= File.join('tmp', 'pids', 'capybara_webmock_proxy.pid')
157
+ Capybara::Webmock.kill_timeout ||= 5
158
+ Capybara::Webmock.start_timeout ||= 30
51
159
 
52
160
  Capybara.register_driver :capybara_webmock do |app|
53
161
  Capybara::Selenium::Driver.new(app, browser: :firefox, profile: Capybara::Webmock.firefox_profile)
54
162
  end
55
163
 
56
164
  Capybara.register_driver :capybara_webmock_chrome do |app|
57
- Capybara::Selenium::Driver.new(app, browser: :chrome, options: Capybara::Webmock.chrome_options)
165
+ Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: {
166
+ chromeOptions: Capybara::Webmock.chrome_options
167
+ })
58
168
  end
59
169
 
60
170
  Capybara.register_driver :capybara_webmock_poltergeist do |app|
@@ -1,12 +1,5 @@
1
1
  require 'rack'
2
2
  require 'capybara/webmock/proxy'
3
3
 
4
- at_exit { Capybara::Webmock::Proxy.remove_pid }
5
-
6
- trap('SIGHUP') {
7
- Capybara::Webmock::Proxy.remove_pid
8
- exit!
9
- }
10
-
11
4
  app = Capybara::Webmock::Proxy.new(Process.pid)
12
5
  Rack::Handler::WEBrick.run(app, Port: ENV.fetch('PROXY_PORT_NUMBER', 9292))
@@ -0,0 +1,25 @@
1
+ require 'uri'
2
+
3
+ module Capybara
4
+ module Webmock
5
+ class ProxiedRequest
6
+ attr_reader :referrer, :uri
7
+
8
+ def initialize(raw_referrer, raw_uri)
9
+ @referrer = raw_referrer == "-" ? nil : URI.parse(raw_referrer)
10
+ @uri = URI.parse(raw_uri)
11
+ end
12
+
13
+ def fragment; @uri.fragment; end
14
+ def host; @uri.host; end
15
+ def hostname; @uri.hostname; end
16
+ def password; @uri.password; end
17
+ def path; @uri.path; end
18
+ def port; @uri.port; end
19
+ def query; @uri.query; end
20
+ def scheme; @uri.scheme; end
21
+ def user; @uri.user; end
22
+ def userinfo; @uri.userinfo; end
23
+ end
24
+ end
25
+ end
@@ -2,12 +2,7 @@ require 'rack/proxy'
2
2
  require 'capybara/webmock'
3
3
 
4
4
  class Capybara::Webmock::Proxy < Rack::Proxy
5
- PID_FILE = File.join('tmp', 'pids', 'capybara_webmock_proxy.pid')
6
-
7
- def initialize(pid)
8
- write_pid(pid)
9
- ensure_log_exists
10
- end
5
+ ALLOWED_HOSTS = allowed_hosts = ['127.0.0.1', 'localhost', /(.*\.|\A)lvh.me/]
11
6
 
12
7
  def call(env)
13
8
  @streaming = true
@@ -16,49 +11,30 @@ class Capybara::Webmock::Proxy < Rack::Proxy
16
11
 
17
12
  def perform_request(env)
18
13
  request = Rack::Request.new(env)
19
- allowed_urls = ['127.0.0.1', 'localhost', %r{(.*\.|\A)lvh.me}]
20
14
 
21
- if allowed_url?(allowed_urls, request.host)
15
+ if allowed_host?(request.host)
22
16
  super(env)
23
17
  else
24
- ['200', {'Content-Type' => 'text/html'}, ['']]
18
+ headers = {
19
+ 'Content-Type' => 'text/html',
20
+ 'Access-Control-Allow-Origin' => '*',
21
+ 'Access-Control-Allow-Methods' => '*',
22
+ 'Access-Control-Allow-Headers' => '*'
23
+ }
24
+ ['200', headers, ['']]
25
25
  end
26
26
  end
27
27
 
28
- def self.remove_pid
29
- File.delete(PID_FILE) if File.exist?(PID_FILE)
30
- end
31
-
32
- def rewrite_response(triplet)
33
- status, headers, body = triplet
34
- headers.delete "transfer-encoding"
35
- triplet
36
- end
37
-
38
28
  private
39
29
 
40
- def allowed_url?(urls, host)
41
- case urls
42
- when Array
43
- urls.any? { |url| allowed_url?(url, host) }
44
- when Regexp
45
- urls =~ host
46
- when String
47
- urls == host
30
+ def allowed_host?(host)
31
+ ALLOWED_HOSTS.any? do |allowed_host|
32
+ case allowed_host
33
+ when Regexp
34
+ allowed_host =~ host
35
+ when String
36
+ allowed_host == host
37
+ end
48
38
  end
49
39
  end
50
-
51
- def write_pid(pid)
52
- tmp_dir = 'tmp'
53
- pid_dir = File.join(tmp_dir, 'pids')
54
- Dir.mkdir(tmp_dir) unless Dir.exist?(tmp_dir)
55
- Dir.mkdir(pid_dir) unless Dir.exist?(pid_dir)
56
- File.write(PID_FILE, pid)
57
- end
58
-
59
- def ensure_log_exists
60
- log_file = File.join('log', 'test.log')
61
- Dir.mkdir('log') unless Dir.exist?('log')
62
- File.open(log_file, 'a') { |f| f.write "" }
63
- end
64
40
  end
@@ -1,5 +1,5 @@
1
1
  module Capybara
2
2
  module Webmock
3
- VERSION = '0.4.4'
3
+ VERSION = '0.5.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara-webmock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jake Worth
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-06-27 00:00:00.000000000 Z
12
+ date: 2018-09-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capybara
@@ -150,6 +150,7 @@ executables: []
150
150
  extensions: []
151
151
  extra_rdoc_files: []
152
152
  files:
153
+ - ".circleci/config.yml"
153
154
  - ".gitignore"
154
155
  - ".rspec"
155
156
  - CODE_OF_CONDUCT.md
@@ -162,6 +163,7 @@ files:
162
163
  - capybara-webmock.gemspec
163
164
  - lib/capybara/webmock.rb
164
165
  - lib/capybara/webmock/config.ru
166
+ - lib/capybara/webmock/proxied_request.rb
165
167
  - lib/capybara/webmock/proxy.rb
166
168
  - lib/capybara/webmock/version.rb
167
169
  homepage: https://github.com/hashrocket/capybara-webmock