From d1dd69972487a6d1cad498df30611b8c6ffce7b2 Mon Sep 17 00:00:00 2001 From: Dmitry Vorotilin Date: Mon, 9 Nov 2026 09:57:12 +0300 Subject: [PATCH] fix(events): pass only the object to one-argument lambdas and symbol procs in page.on page.on(:request, &:continue) called continue(index, total), which raised and was dropped, so the request stayed paused. Callbacks for :request, :response, :auth and :dialog that can't take the extra index and total now get only the object. --- CHANGELOG.md | 3 +++ lib/ferrum/interceptable.rb | 14 +++++++++++--- lib/ferrum/page.rb | 2 +- sig/ferrum/interceptable.rbs | 4 ++++ spec/page_spec.rb | 24 ++++++++++++++++++++++++ 5 files changed, 43 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 029778c8..bbd2a4bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,9 @@ `go_to` instead ### Fixed +- `page.on(:request, &:continue)` never continued the request, it called `continue(index, total)` and the error was + dropped. Symbol procs and lambdas taking one argument get only the object now, for `:request`, `:response`, `:auth` + and `:dialog` - `AuthRequest#abort` raised `BrowserError` and left the page hanging, it cancels the auth challenge now - `InterceptedRequest#navigation_request?` and `AuthRequest#navigation_request?` always returned `nil`, they are true for document requests now diff --git a/lib/ferrum/interceptable.rb b/lib/ferrum/interceptable.rb index 9c4581c7..9c3906f1 100644 --- a/lib/ferrum/interceptable.rb +++ b/lib/ferrum/interceptable.rb @@ -41,17 +41,17 @@ def on(name, &block) request = Network::InterceptedRequest.new(client, params) exchange = network.find_or_build_exchange(request.network_id) exchange.intercepted_request = request - block.call(request, index, total) + yield_event(block, request, index, total) end when :response client.on("Network.loadingFinished") do |params, index, total| exchange = network.select(params["requestId"]).last - block.call(exchange, index, total) if exchange + yield_event(block, exchange, index, total) if exchange end when :auth client.on("Fetch.authRequired") do |params, index, total| request = Network::AuthRequest.new(self, params) - block.call(request, index, total) + yield_event(block, request, index, total) end else client.on(name, &block) @@ -89,5 +89,13 @@ def off(name, id) def subscribed?(event) client.subscribed?(event) end + + private + + def yield_event(block, object, index, total) + return block.call(object) if block.lambda? && (block.arity == 1 || block.parameters == [%i[req], %i[rest]]) + + block.call(object, index, total) + end end end diff --git a/lib/ferrum/page.rb b/lib/ferrum/page.rb index 24347eee..faa6d39b 100644 --- a/lib/ferrum/page.rb +++ b/lib/ferrum/page.rb @@ -576,7 +576,7 @@ def on(name, &block) client.on("Page.javascriptDialogOpening") do |params, index, total| dialog = Dialog.new(self, params) - block.call(dialog, index, total) + yield_event(block, dialog, index, total) end end diff --git a/sig/ferrum/interceptable.rbs b/sig/ferrum/interceptable.rbs index 7271aafa..dc79a7e0 100644 --- a/sig/ferrum/interceptable.rbs +++ b/sig/ferrum/interceptable.rbs @@ -9,5 +9,9 @@ module Ferrum def off: (Symbol | String name, Integer id) -> void def subscribed?: (String event) -> bool + + private + + def yield_event: (Proc block, untyped object, Integer index, Integer total) -> untyped end end diff --git a/spec/page_spec.rb b/spec/page_spec.rb index 356e007f..c3eae2af 100644 --- a/spec/page_spec.rb +++ b/spec/page_spec.rb @@ -484,6 +484,30 @@ def is_mobile? end end + context "with :request" do + it "continues the request when given the continue method as a block" do + network.intercept + page.on(:request, &:continue) + + page.go_to("/foo") + + expect(page.body).to include("Another World") + end + + it "yields the request with its index and total to a regular block" do + network.intercept + args = nil + page.on(:request) do |request, index, total| + args ||= [index, total] + request.continue + end + + page.go_to("/foo") + + expect(args).to eq([0, 1]) + end + end + context "with :response" do it "yields the exchange once its response is fully loaded" do exchanges = []