web-dev-qa-db-fra.com

définition des en-têtes de demande en sélénium

J'essaie de définir l'en-tête de requête 'Référant' pour falsifier une requête provenant d'un autre site. Nous avons besoin du test de capacité selon lequel un référent spécifique est utilisé, qui renvoie un formulaire spécifique à l'utilisateur, sinon un formulaire alternatif est fourni.

Je peux le faire dans poltergeist en:

page.driver.headers = {"Referer" => referer_string}

mais je ne trouve pas la fonctionnalité équivalente pour le pilote selemium.

Comment définir des en-têtes de requête dans le pilote capybara Selenium?

40
tamouse

Webdriver ne contient pas d'API pour le faire. Voir numéro 141 de Selenium Tracker pour plus d'informations. Le titre du problème indique qu'il s'agit d'en-têtes de réponse, mais il a été décidé que Selenium ne contiendrait pas d'API pour les en-têtes de demande dans le cadre de ce problème. Plusieurs problèmes liés à l'ajout d'API dans les en-têtes de requête ont été signalés comme des doublons: first , second , third .

Voici quelques possibilités que je peux proposer:

  1. Utilisez un autre pilote/bibliothèque au lieu de Selenium
  2. Ecrivez un plugin spécifique au navigateur (ou trouvez-en un existant) qui vous permette d'ajouter un en-tête pour la requête.
  3. Utilisez browsermob-proxy ou un autre proxy.

J'irais avec l'option 3 dans la plupart des cas. C'est pas difficile.

Notez que Ghostdriver dispose d’une API mais elle n’est pas prise en charge par les autres pilotes.

29
Andrei Botalov

J'ai eu le même problème. Je l'ai résolu en téléchargeant le module complémentaire firefox de modify-headers et en l'activant avec Selenium.

Le code en python est le suivant

fp = webdriver.FirefoxProfile()
path_modify_header = 'C:/xxxxxxx/modify_headers-0.7.1.1-fx.xpi'
fp.add_extension(path_modify_header)

fp.set_preference("modifyheaders.headers.count", 1)
fp.set_preference("modifyheaders.headers.action0", "Add")
fp.set_preference("modifyheaders.headers.name0", "Name_of_header") # Set here the name of the header
fp.set_preference("modifyheaders.headers.value0", "value_of_header") # Set here the value of the header
fp.set_preference("modifyheaders.headers.enabled0", True)
fp.set_preference("modifyheaders.config.active", True)
fp.set_preference("modifyheaders.config.alwaysOn", True)

driver = webdriver.Firefox(firefox_profile=fp)
8
Fernando Marengo

Avait le même problème aujourd'hui, sauf que je devais définir un référent différent pour chaque test. J'ai fini par utiliser un middleware et une classe pour y passer des en-têtes. Je pensais partager (ou peut-être une solution plus propre?):

lib/request_headers.rb:

class CustomHeadersHelper
  cattr_accessor :headers
end

class RequestHeaders
  def initialize(app, helper = nil)
    @app, @helper = app, helper
  end

  def call(env)
    if @helper
      headers = @helper.headers

      if headers.is_a?(Hash)
        headers.each do |k,v|
          env["HTTP_#{k.upcase.gsub("-", "_")}"] = v
        end
      end
    end

    @app.call(env)
  end
end

config/initializers/middleware.rb

require 'request_headers'

if %w(test cucumber).include?(Rails.env)
  Rails.application.config.middleware.insert_before Rack::Lock, "RequestHeaders", CustomHeadersHelper
end

spec/support/capybara_headers.rb

require 'request_headers'

module CapybaraHeaderHelpers
  shared_context "navigating within the site" do
    before(:each) { add_headers("Referer" => Capybara.app_Host + "/") }
  end

  def add_headers(custom_headers)
    if Capybara.current_driver == :rack_test
      custom_headers.each do |name, value|
        page.driver.browser.header(name, value)
      end
    else
      CustomHeadersHelper.headers = custom_headers
    end
  end
end

spec/spec_helper.rb

...
config.include CapybaraHeaderHelpers

Ensuite, je peux inclure le contexte partagé où j'en ai besoin ou passer différents en-têtes dans un autre bloc before. Je ne l'ai pas testé avec autre chose que Selenium et RackTest, mais il devrait être transparent, car l'injection d'en-tête est effectuée avant que la demande ne frappe réellement l'application.

5
HargrimmTheBleak

Si vous utilisez Python, vous pouvez utiliser Selenium Wire , qui permet de définir des en-têtes de requête et de vous permettre d’inspecter les requêtes et les réponses.

from seleniumwire import webdriver  # Import from seleniumwire

# Create a new instance of the Firefox driver
driver = webdriver.Firefox()

driver.header_overrides = {
    'Referer': 'referer_string',
}

# All subsequent requests will now contain the Referer
5
Will Keeling

Si vous utilisez la variable HtmlUnitDriver, vous pouvez définir les en-têtes de requête en modifiant la variable WebClient, comme suit:

final case class Header(name: String, value: String)

final class HtmlUnitDriverWithHeaders(headers: Seq[Header]) extends HtmlUnitDriver {
  super.modifyWebClient {
    val client = super.getWebClient
    headers.foreach(h => client.addRequestHeader(h.name, h.value))
    client
  }
}

Les en-têtes seront alors sur toutes les demandes faites par le navigateur Web.

0
John P

Vous pouvez le faire avec PhantomJSDriver.

PhantomJSDriver pd = ((PhantomJSDriver) ((WebDriverFacade) getDriver()).getProxiedDriver());
pd.executePhantomJS(
            "this.onResourceRequested = function(request, net) {" +
            "   net.setHeader('header-name', 'header-value')" +
            "};");

À l'aide de l'objet de requête, vous pouvez également filtrer pour que l'en-tête ne soit pas défini pour chaque requête.

0