Class: Capybara::Lightpanda::Network
- Inherits:
-
Object
- Object
- Capybara::Lightpanda::Network
- Defined in:
- lib/capybara/lightpanda/network.rb
Constant Summary collapse
- TRAFFIC_LIMIT =
Tracking is always on (create_page enables it), so the buffer needs the same unbounded-growth cap as Browser’s console ring buffer —one very long session would otherwise grow @traffic indefinitely.
1_000
Instance Attribute Summary collapse
-
#browser ⇒ Object
readonly
Returns the value of attribute browser.
-
#last_navigation_response ⇒ Object
readonly
Status/headers of the last top-level document navigation; nil before the first navigation completes.
Instance Method Summary collapse
- #add_headers(headers) ⇒ Object
- #clear ⇒ Object
- #clear_headers ⇒ Object
-
#disable ⇒ Object
Caveat: disabling the domain also stops the navigation-response capture, so Browser#status_code / #response_headers freeze at their last values until the next #enable.
-
#enable ⇒ Object
The domain toggle is connection-scoped (browser.command), while setExtraHTTPHeaders is session-scoped (browser.page_command) — see #headers=.
-
#extra_headers ⇒ Object
Headers applied via headers= / add_headers.
-
#headers=(headers) ⇒ Object
Setting extra headers also lazily enables the Network domain.
-
#idle?(connections = 0) ⇒ Boolean
True when no more than ‘connections` requests are in-flight.
-
#initialize(browser) ⇒ Network
constructor
A new instance of Network.
-
#pending_connections ⇒ Object
Count of in-flight requests (those with no response yet recorded).
-
#reset ⇒ Object
Wipe local state without sending Network.disable.
- #traffic ⇒ Object
- #wait_for_idle(timeout: 5, connections: 0) ⇒ Object
-
#wait_for_idle!(timeout: 5, connections: 0) ⇒ Object
Raising variant of #wait_for_idle (ferrum parity).
Constructor Details
#initialize(browser) ⇒ Network
Returns a new instance of Network.
18 19 20 21 22 23 24 25 26 |
# File 'lib/capybara/lightpanda/network.rb', line 18 def initialize(browser) @browser = browser @traffic = [] @traffic_mutex = Mutex.new @enabled = false @request_handler = @response_handler = nil @last_navigation_response = nil @document_request_id = nil end |
Instance Attribute Details
#browser ⇒ Object (readonly)
Returns the value of attribute browser.
11 12 13 |
# File 'lib/capybara/lightpanda/network.rb', line 11 def browser @browser end |
#last_navigation_response ⇒ Object (readonly)
Status/headers of the last top-level document navigation; nil before the first navigation completes. Backs Browser#status_code / #response_headers. Captured by #subscribe’s handlers.
16 17 18 |
# File 'lib/capybara/lightpanda/network.rb', line 16 def @last_navigation_response end |
Instance Method Details
#add_headers(headers) ⇒ Object
102 103 104 105 106 |
# File 'lib/capybara/lightpanda/network.rb', line 102 def add_headers(headers) enable @extra_headers = (@extra_headers || {}).merge(headers) browser.page_command("Network.setExtraHTTPHeaders", headers: @extra_headers) end |
#clear ⇒ Object
71 72 73 |
# File 'lib/capybara/lightpanda/network.rb', line 71 def clear @traffic_mutex.synchronize { @traffic.clear } end |
#clear_headers ⇒ Object
108 109 110 111 112 |
# File 'lib/capybara/lightpanda/network.rb', line 108 def clear_headers enable @extra_headers = {} browser.page_command("Network.setExtraHTTPHeaders", headers: {}) end |
#disable ⇒ Object
Caveat: disabling the domain also stops the navigation-response capture, so Browser#status_code / #response_headers freeze at their last values until the next #enable.
54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/capybara/lightpanda/network.rb', line 54 def disable return unless @enabled # Tell the browser to stop emitting BEFORE unsubscribing locally: # otherwise an in-flight Network.responseReceived can race past the # already-removed handler and leave a `response: nil` entry in # @traffic for the matching request — which then trips # wait_for_idle's pending count on a future call. browser.command("Network.disable") unsubscribe @enabled = false end |
#enable ⇒ Object
The domain toggle is connection-scoped (browser.command), while setExtraHTTPHeaders is session-scoped (browser.page_command) — see #headers=. Browser#create_page calls this, so tracking (traffic AND the navigation-response capture) is on for every page.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/capybara/lightpanda/network.rb', line 32 def enable return if @enabled # Subscribe BEFORE flipping the wire toggle (mirror image of # #disable's ordering): events can't be emitted while the domain is # off, so this order can never miss one. If the command fails # (Lightpanda can block commands mid-navigation), roll the handlers # back — orphaned duplicates would double-count every request and # wedge pending_connections above zero for the session. subscribe begin browser.command("Network.enable") rescue StandardError unsubscribe raise end @enabled = true end |
#extra_headers ⇒ Object
Headers applied via headers= / add_headers. Backs Driver#headers.
91 |
# File 'lib/capybara/lightpanda/network.rb', line 91 def extra_headers = @extra_headers || {} |
#headers=(headers) ⇒ Object
Setting extra headers also lazily enables the Network domain. Without this, headers were silently ignored until the caller separately ran ‘network.enable` (or `wait_for_network_idle`). Cuprite/Ferrum parity.
96 97 98 99 100 |
# File 'lib/capybara/lightpanda/network.rb', line 96 def headers=(headers) enable @extra_headers = headers browser.page_command("Network.setExtraHTTPHeaders", headers: headers) end |
#idle?(connections = 0) ⇒ Boolean
True when no more than ‘connections` requests are in-flight.
121 122 123 |
# File 'lib/capybara/lightpanda/network.rb', line 121 def idle?(connections = 0) pending_connections <= connections end |
#pending_connections ⇒ Object
Count of in-flight requests (those with no response yet recorded). Cheap predicate-friendly accessor (ferrum parity).
116 117 118 |
# File 'lib/capybara/lightpanda/network.rb', line 116 def pending_connections @traffic_mutex.synchronize { @traffic.count { |t| t[:response].nil? } } end |
#reset ⇒ Object
Wipe local state without sending Network.disable. Called by Browser#reset after Target.disposeBrowserContext, which destroys the subscriptions and the Network domain along with the context —leaving @enabled true would silently no-op the next #enable. Also unsubscribes locally so we don’t rely on the caller having cleared the Subscriber first.
81 82 83 84 85 86 87 88 |
# File 'lib/capybara/lightpanda/network.rb', line 81 def reset unsubscribe clear @enabled = false @extra_headers = nil # the fresh context never received setExtraHTTPHeaders @last_navigation_response = nil @document_request_id = nil end |
#traffic ⇒ Object
67 68 69 |
# File 'lib/capybara/lightpanda/network.rb', line 67 def traffic @traffic_mutex.synchronize { @traffic.dup } end |
#wait_for_idle(timeout: 5, connections: 0) ⇒ Object
125 126 127 128 129 |
# File 'lib/capybara/lightpanda/network.rb', line 125 def wait_for_idle(timeout: 5, connections: 0) wait_for_idle!(timeout: timeout, connections: connections) rescue TimeoutError false end |
#wait_for_idle!(timeout: 5, connections: 0) ⇒ Object
Raising variant of #wait_for_idle (ferrum parity). Returns true on success, raises TimeoutError on timeout so callers that treat the idle wait as a precondition don’t have to remember to check a bool.
134 135 136 137 138 139 140 141 142 |
# File 'lib/capybara/lightpanda/network.rb', line 134 def wait_for_idle!(timeout: 5, connections: 0) # rubocop:disable Naming/PredicateMethod Utils::Wait.until( timeout: timeout, interval: 0.1, message: "Network did not become idle within #{timeout}s " \ "(pending=#{pending_connections}, allowed=#{connections})" ) { idle?(connections) } true end |