diff --git a/lib/ferrum/network.rb b/lib/ferrum/network.rb index 905ad1e3..752967a8 100644 --- a/lib/ferrum/network.rb +++ b/lib/ferrum/network.rb @@ -11,9 +11,10 @@ module Ferrum class Network CLEAR_TYPE = %i[traffic cache].freeze AUTHORIZE_TYPE = %i[server proxy].freeze - RESOURCE_TYPES = %w[Document Stylesheet Image Media Font Script TextTrack - XHR Fetch EventSource WebSocket Manifest - SignedExchange Ping CSPViolationReport Other].freeze + REQUEST_STAGES = %i[Request Response].freeze + RESOURCE_TYPES = %i[Document Stylesheet Image Media Font Script TextTrack + XHR Fetch Prefetch EventSource WebSocket Manifest + SignedExchange Ping CSPViolationReport Preflight Other].freeze AUTHORIZE_BLOCK_MISSING = "Block is missing, call `authorize(...) { |r| r.continue } " \ "or subscribe to `on(:request)` events before calling it" AUTHORIZE_TYPE_WRONG = ":type should be in #{AUTHORIZE_TYPE}" @@ -187,11 +188,20 @@ def whitelist=(patterns) # end # browser.go_to("https://google.com") # - def intercept(pattern: "*", resource_type: nil) + def intercept(pattern: "*", resource_type: nil, request_stage: nil, handle_auth_requests: true) pattern = { urlPattern: pattern } - pattern[:resourceType] = resource_type if resource_type && RESOURCE_TYPES.include?(resource_type.to_s) - @page.command("Fetch.enable", handleAuthRequests: true, patterns: [pattern]) + if resource_type && RESOURCE_TYPES.none?(resource_type.to_sym) + raise ArgumentError, "Unknown resource type '#{resource_type}' must be #{RESOURCE_TYPES.join(' | ')}" + end + + if request_stage && REQUEST_STAGES.none?(request_stage.to_sym) + raise ArgumentError, "Unknown request stage '#{request_stage}' must be #{REQUEST_STAGES.join(' | ')}" + end + + pattern[:resourceType] = resource_type if resource_type + pattern[:requestStage] = request_stage if request_stage + @page.command("Fetch.enable", patterns: [pattern], handleAuthRequests: handle_auth_requests) end # diff --git a/spec/network_spec.rb b/spec/network_spec.rb index 1b207aa3..ce89d506 100644 --- a/spec/network_spec.rb +++ b/spec/network_spec.rb @@ -302,6 +302,55 @@ end describe "#intercept" do + it "supports :pattern argument" do + network.intercept(pattern: "*/ferrum/frame_child") + page.on(:request) do |request| + request.respond(body: "

hello

") + end + + page.go_to("/ferrum/frame_parent") + + expect(network.status).to eq(200) + frame = page.at_xpath("//iframe").frame + expect(frame.body).to include("hello") + end + + context "with :resource_type argument" do + it "raises an error with wrong type" do + expect { network.intercept(resource_type: :BlaBla) }.to raise_error(ArgumentError) + end + + it "intercepts only given type" do + network.intercept(resource_type: :Document) + page.on(:request) do |request| + request.respond(body: "

hello

") + end + + page.go_to("/ferrum/non_existing") + + expect(network.status).to eq(200) + expect(page.body).to include("hello") + end + end + + context "with :request_stage argument" do + it "raises an error with wrong stage" do + expect { network.intercept(request_stage: :BlaBla) }.to raise_error(ArgumentError) + end + + it "intercepts only given stage" do + network.intercept(request_stage: :Response) + page.on(:request) do |request| + request.respond(body: "

hello

") + end + + page.go_to("/ferrum/index") + + expect(network.status).to eq(200) + expect(page.body).to include("hello") + end + end + it "supports custom responses" do network.intercept page.on(:request) do |request|