mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Merge branch 'request_tracking' into server_per_session
* request_tracking: Wait for all server requests to finish on session reset
This commit is contained in:
commit
9342c66c4d
3 changed files with 55 additions and 0 deletions
|
@ -4,22 +4,47 @@ require 'rack'
|
||||||
|
|
||||||
module Capybara
|
module Capybara
|
||||||
class Server
|
class Server
|
||||||
|
class Counter
|
||||||
|
attr_reader :value
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@value = 0
|
||||||
|
@mutex = Mutex.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def increment
|
||||||
|
@mutex.synchronize { @value += 1 }
|
||||||
|
end
|
||||||
|
|
||||||
|
def decrement
|
||||||
|
@mutex.synchronize { @value -= 1 }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class Middleware
|
class Middleware
|
||||||
attr_accessor :error
|
attr_accessor :error
|
||||||
|
|
||||||
def initialize(app)
|
def initialize(app)
|
||||||
@app = app
|
@app = app
|
||||||
|
@counter = Counter.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def pending_requests?
|
||||||
|
@counter.value > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def call(env)
|
def call(env)
|
||||||
if env["PATH_INFO"] == "/__identify__"
|
if env["PATH_INFO"] == "/__identify__"
|
||||||
[200, {}, [@app.object_id.to_s]]
|
[200, {}, [@app.object_id.to_s]]
|
||||||
else
|
else
|
||||||
|
@counter.increment
|
||||||
begin
|
begin
|
||||||
@app.call(env)
|
@app.call(env)
|
||||||
rescue *Capybara.server_errors => e
|
rescue *Capybara.server_errors => e
|
||||||
@error = e unless @error
|
@error = e unless @error
|
||||||
raise e
|
raise e
|
||||||
|
ensure
|
||||||
|
@counter.decrement
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -62,6 +87,12 @@ module Capybara
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def wait_for_pending_requests
|
||||||
|
Timeout.timeout(60) { sleep(0.01) while @middleware.pending_requests? }
|
||||||
|
rescue Timeout::Error
|
||||||
|
raise "Requests did not finish in 60 seconds"
|
||||||
|
end
|
||||||
|
|
||||||
def boot
|
def boot
|
||||||
unless responsive?
|
unless responsive?
|
||||||
Capybara::Server.ports[@app.object_id] = @port
|
Capybara::Server.ports[@app.object_id] = @port
|
||||||
|
|
|
@ -109,6 +109,7 @@ module Capybara
|
||||||
assert_no_selector :xpath, "/html/body/*" if driver.browser_initialized?
|
assert_no_selector :xpath, "/html/body/*" if driver.browser_initialized?
|
||||||
@touched = false
|
@touched = false
|
||||||
end
|
end
|
||||||
|
@server.wait_for_pending_requests if @server
|
||||||
raise_server_error!
|
raise_server_error!
|
||||||
end
|
end
|
||||||
alias_method :cleanup!, :reset!
|
alias_method :cleanup!, :reset!
|
||||||
|
|
|
@ -113,4 +113,27 @@ RSpec.describe Capybara::Server do
|
||||||
expect(Net::HTTP).to receive(:start).and_raise(SystemCallError.allocate)
|
expect(Net::HTTP).to receive(:start).and_raise(SystemCallError.allocate)
|
||||||
expect(server.responsive?).to eq false
|
expect(server.responsive?).to eq false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "can detect and wait for pending requests" do
|
||||||
|
done = false
|
||||||
|
app = proc do |env|
|
||||||
|
sleep 0.2
|
||||||
|
done = true
|
||||||
|
[200, {}, ["Hello Server!"]]
|
||||||
|
end
|
||||||
|
server = Capybara::Server.new(app).boot
|
||||||
|
|
||||||
|
# Start request, but don't wait for it to finish
|
||||||
|
socket = TCPSocket.new(server.host, server.port)
|
||||||
|
socket.write "GET / HTTP/1.0\r\n\r\n"
|
||||||
|
socket.close
|
||||||
|
sleep 0.1
|
||||||
|
|
||||||
|
expect(done).to be false
|
||||||
|
|
||||||
|
server.wait_for_pending_requests
|
||||||
|
|
||||||
|
# Ensure server was allowed to finish
|
||||||
|
expect(done).to be true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue