From b5a5ae8c6cee8959cf610a582fdeda5cba20ebca Mon Sep 17 00:00:00 2001 From: Jonathan Miles Date: Sun, 7 Jan 2024 01:43:32 +1300 Subject: [PATCH] Fix: Do not expect response for initiatorType Ping requests (#417) * Add Request#response_expected? method * Add Exchange#response_expected? method * Exchange#finished? returns true if no response expected * Add HTML test for with ping attribute --- lib/ferrum/network/exchange.rb | 13 ++++++++++++- lib/ferrum/network/request.rb | 9 +++++++++ spec/network/exchange_spec.rb | 26 ++++++++++++++++++++++++++ spec/network/request_spec.rb | 14 +++++++++++++- spec/network_spec.rb | 22 ++++++++++++++++------ spec/node_spec.rb | 10 ++++++++++ spec/support/application.rb | 6 ++++++ spec/support/views/link_with_ping.erb | 3 +++ 8 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 spec/support/views/link_with_ping.erb diff --git a/lib/ferrum/network/exchange.rb b/lib/ferrum/network/exchange.rb index d1e2d5ec..3249ef26 100644 --- a/lib/ferrum/network/exchange.rb +++ b/lib/ferrum/network/exchange.rb @@ -79,7 +79,7 @@ def blocked? # @return [Boolean] # def finished? - blocked? || response&.loaded? || !error.nil? + blocked? || response&.loaded? || !error.nil? || !response_expected? end # @@ -118,6 +118,17 @@ def redirect? response&.redirect? end + # + # Determines if the exchange expects a response + # + # @return [Boolean] + # + def response_expected? + return true if request.nil? + + !!request.response_expected? + end + # # Returns request's URL. # diff --git a/lib/ferrum/network/request.rb b/lib/ferrum/network/request.rb index 9981b4fc..e018b388 100644 --- a/lib/ferrum/network/request.rb +++ b/lib/ferrum/network/request.rb @@ -80,6 +80,15 @@ def time @time ||= Time.strptime(@params["wallTime"].to_s, "%s") end + # + # Determines if a response is expected. + # + # @return [Boolean] + # + def response_expected? + !type?("ping") + end + # # Converts the request to a Hash. # diff --git a/spec/network/exchange_spec.rb b/spec/network/exchange_spec.rb index c485b446..03e3b5a3 100644 --- a/spec/network/exchange_spec.rb +++ b/spec/network/exchange_spec.rb @@ -109,6 +109,22 @@ expect(last_exchange.finished?).to be true end + + it "returns true if an error occurred" do + exchange = Ferrum::Network::Exchange.new(page, "1") + + expect(exchange.finished?).to be false + exchange.error = Ferrum::Network::Error.new + expect(exchange.finished?).to be true + end + + it "returns true for ping requests" do + exchange = Ferrum::Network::Exchange.new(page, "1") + expect(exchange.finished?).to be false + + exchange.request = Ferrum::Network::Request.new({"type" => "Ping"}) + expect(exchange.finished?).to be true + end end describe "#redirect?" do @@ -119,6 +135,16 @@ end end + describe "#response_expected?" do + it "determines if exchange expects a response" do + exchange = Ferrum::Network::Exchange.new(page, "1") + expect(exchange.response_expected?).to be true + + exchange.request = Ferrum::Network::Request.new({"type" => "Ping"}) + expect(exchange.response_expected?).to be false + end + end + describe "#pending?" do it "determines if exchange is not fully loaded" do allow(page).to receive(:timeout) { 2 } diff --git a/spec/network/request_spec.rb b/spec/network/request_spec.rb index 62f45d1e..c47b5977 100644 --- a/spec/network/request_spec.rb +++ b/spec/network/request_spec.rb @@ -1,5 +1,17 @@ # frozen_string_literal: true describe Ferrum::Network::Request do - skip + describe "#response_expected?" do + it "returns true for document requests" do + request = Ferrum::Network::Request.new({"type" => "Document"}) + + expect(request.response_expected?).to be(true) + end + + it "returns false for ping requests" do + request = Ferrum::Network::Request.new({"type" => "Ping"}) + + expect(request.response_expected?).to be(false) + end + end end diff --git a/spec/network_spec.rb b/spec/network_spec.rb index ee1e0d77..3934b09e 100644 --- a/spec/network_spec.rb +++ b/spec/network_spec.rb @@ -47,13 +47,23 @@ expect(page.body).to include("test_cookie") end - it "#idle?" do - page.go_to("/ferrum/with_slow_ajax_connection") - expect(page.at_xpath("//h1[text() = 'Slow AJAX']")).to be + describe "#idle?" do + it "waits for network to be idle" do + page.go_to("/ferrum/with_slow_ajax_connection") + expect(page.at_xpath("//h1[text() = 'Slow AJAX']")).to be + + expect(network.idle?).to be_falsey + network.wait_for_idle + expect(network.idle?).to be_truthy + end - expect(network.idle?).to be_falsey - network.wait_for_idle - expect(network.idle?).to be_truthy + it "does not wait for responses to PING requests" do + page.go_to("/ferrum/link_with_ping") + page.at_css("a").click + + network.wait_for_idle + expect(network.idle?).to be_truthy + end end it "#total_connections" do diff --git a/spec/node_spec.rb b/spec/node_spec.rb index 14143d8e..62d51cdf 100644 --- a/spec/node_spec.rb +++ b/spec/node_spec.rb @@ -10,6 +10,16 @@ expect(browser.current_url).to eq(base_url("/")) end + it "fires a ping request for anchor elements" do + browser.go_to("/ferrum/link_with_ping") + + expect(browser.network.traffic.length).to eq(1) + browser.at_css("a").click + + # 1 for first load, 1 for load of new url, 1 for ping = 3 total + expect(browser.network.traffic.length).to eq(3) + end + it "does not run into content quads error" do browser.go_to("/ferrum/index") diff --git a/spec/support/application.rb b/spec/support/application.rb index eae2909b..2ad58961 100644 --- a/spec/support/application.rb +++ b/spec/support/application.rb @@ -326,6 +326,12 @@ def authorized?(login, password) params["remaining_path"] end + post "/ferrum/ping" do + # Sleeping to simulate a server that does not send a response to PING requests + sleep 5 + halt 204 + end + protected def render_view(view) diff --git a/spec/support/views/link_with_ping.erb b/spec/support/views/link_with_ping.erb new file mode 100644 index 00000000..aa3ba7f5 --- /dev/null +++ b/spec/support/views/link_with_ping.erb @@ -0,0 +1,3 @@ +

+ Link with ping +