Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Teamcapybara Capybara Server Middleware

From Leeroopedia
Revision as of 11:53, 16 February 2026 by Admin (talk | contribs) (Auto-imported from implementations/Teamcapybara_Capybara_Server_Middleware.md)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Overview

Capybara::Server::Middleware is a Rack middleware that wraps the application under test, tracking in-flight HTTP requests and capturing server errors for test isolation. It allows Capybara to wait for pending requests to complete before making test assertions and to detect server-side errors that occur during test execution. The middleware includes a nested Counter class that provides thread-safe request counting.

Source File

Property Value
File lib/capybara/server/middleware.rb
Lines 71
Language Ruby
Module Capybara::Server::Middleware
Nested Class Capybara::Server::Middleware::Counter

Class: Capybara::Server::Middleware

Attributes

Attribute Access Description
error reader The most recent server error captured during request processing; nil if no error has occurred

initialize(app, server_errors, extra_middleware = [])

Creates a new middleware instance wrapping the given Rack application. Accepts a list of exception classes to capture as server errors and an optional array of extra middleware classes to layer on top of the application.

The extra middleware classes are composed using inject, each wrapping the previous application in the chain:

def initialize(app, server_errors, extra_middleware = [])
  @app = app
  @extended_app = extra_middleware.inject(@app) do |ex_app, klass|
    klass.new(ex_app)
  end
  @counter = Counter.new
  @server_errors = server_errors
end

pending_requests

Returns a duplicate array of URI strings for all currently in-flight requests. The array is duplicated to prevent external mutation of the internal state.

def pending_requests
  @counter.value
end

pending_requests?

Returns true if there are any in-flight requests currently being processed by the server.

def pending_requests?
  @counter.positive?
end

clear_error

Resets the captured server error to nil. Typically called between test executions to ensure errors from one test do not affect subsequent tests.

def clear_error
  @error = nil
end

call(env)

The Rack middleware entry point. Handles two cases:

  1. Identity endpoint -- If the request path is /__identify__, responds immediately with the application's object_id as the body. This is used by Capybara to verify that the middleware is wrapping the correct application instance.
  2. Normal requests -- Increments the pending request counter with the request URI, delegates to the extended application, captures any errors matching @server_errors, and decrements the counter in the ensure block regardless of success or failure.
def call(env)
  if env['PATH_INFO'] == '/__identify__'
    [200, {}, [@app.object_id.to_s]]
  else
    request_uri = env['REQUEST_URI']
    @counter.increment(request_uri)
    begin
      @extended_app.call(env)
    rescue *@server_errors => e
      @error ||= e
      raise e
    ensure
      @counter.decrement(request_uri)
    end
  end
end

The error is captured with @error ||= e, meaning only the first error is retained. Subsequent errors are still re-raised but do not overwrite the stored error. The error is also re-raised after capture so that the server's error handling still functions normally.

Nested Class: Counter

The Counter class provides a thread-safe mechanism for tracking in-flight requests by URI. It uses a Mutex to synchronize all operations on the internal array.

Internal State

Variable Type Description
@value Array List of URI strings for currently active requests
@mutex Mutex Synchronization primitive protecting @value

initialize

Creates a new counter with an empty array and a new mutex.

def initialize
  @value = []
  @mutex = Mutex.new
end

increment(uri)

Adds a URI string to the active requests list within a synchronized block.

def increment(uri)
  @mutex.synchronize { @value.push(uri) }
end

decrement(uri)

Removes a single occurrence of the given URI from the active requests list within a synchronized block. Uses delete_at with index to remove only one instance (not all matching entries), defaulting to index -1 if the URI is not found.

def decrement(uri)
  @mutex.synchronize { @value.delete_at(@value.index(uri) || -1) }
end

positive?

Returns true if there are any active requests in the list.

def positive?
  @mutex.synchronize { @value.length.positive? }
end

value

Returns a duplicate of the internal array, providing a snapshot of active request URIs without exposing the internal state to external modification.

def value
  @mutex.synchronize { @value.dup }
end

Key Design Decisions

  • Array-based counter -- The counter stores actual URI strings rather than a simple integer, enabling debugging and diagnostics by revealing which specific requests are still pending.
  • Thread-safe operations -- All counter operations are synchronized with a Mutex because the Rack server may handle multiple concurrent requests from different threads.
  • First-error-wins semantics -- Only the first server error is stored (@error ||= e), but all errors are re-raised. This ensures the original error is available for test assertions while not suppressing subsequent error handling.
  • Identity endpoint -- The /__identify__ path provides a lightweight mechanism for Capybara to verify server identity by matching object_id values, enabling multi-server test configurations.
  • Extra middleware composition -- The extra_middleware parameter allows users to inject additional Rack middleware (such as logging or authentication) into the test server stack without modifying the application.

See Also

  • Capybara::Server -- The server class that uses this middleware to wrap the application under test
  • Capybara::Server::Checker -- Verifies server availability during startup

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment