How to send an http RequestHeader using Selenium 2?

泄露秘密 提交于 2019-11-27 03:05:41

问题


I needed to send an Http request with a few modified headers. After several hours trying to find an equivalent method to that of Selenium RC Selenium.addCustomRequestHeader for Selenium 2, I gave up and used JavaScript for my purposes. I have expected this to be a lot easier!

Does someone know a better method?

This is what I have done:

javascript.js

var test = {
    "sendHttpHeaders": function(dst, header1Name, header1Val, header2Name, header2Val) {
        var http = new XMLHttpRequest();

        http.open("GET", dst, "false");
        http.setRequestHeader(header1Name,header1Val);
        http.setRequestHeader(header2Name,header2Val);
        http.send(null);
    }
}

MyTest.java

// ...

@Test
public void testFirstLogin() throws Exception {
    WebDriver driver = new FirefoxDriver();

    String url = System.getProperty(Constants.URL_PROPERTY_NAME);
    driver.get(url);

    // Using javascript to send http headers
    String scriptResource = this.getClass().getPackage().getName()
        .replace(".", "/") + "/javascript.js";

    String script = getFromResource(scriptResource)
            + "test.sendHttpHeaders(\"" + url + "\", \"" + h1Name
            + "\", \"" + h1Val + "\", \"" + h2Name + "\", \"" + h2Val + "\");";
    LOG.debug("script: " + script);

    ((JavascriptExecutor)driver).executeScript(loginScript);

    // ...
}

// I don't like mixing js with my code. I've written this utility method to get
// the js from the classpath
/**
 * @param src name of a resource that must be available from the classpath
 * @return new string with the contents of the resource
 * @throws IOException if resource not found
 */
public static String getFromResource(String src) throws IOException {
    InputStream is = Thread.currentThread().getContextClassLoader().
            getResourceAsStream(src);
    if (null == is) {
        throw new IOException("Resource " + src + " not found.");
    }
    InputStreamReader isr = new InputStreamReader(is);
    BufferedReader br = new BufferedReader(isr);
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);

    String line = null;
    int nLines = 0;
    while (null != (line = br.readLine())) {
        pw.println(line);
        nLines ++;
    }
    LOG.info("Resource " + src + " successfully copied into String (" + nLines + " lines copied).");
    return sw.toString();
}

// ...

Notice: To simplify this post, I have edited my original code. I hope I haven't introduced any errors!


回答1:


Unfortunately you can not change headers with Selenium 2. This has been a conscious decision on the teams part as we are trying to create a browser automation framework that emulates what a user can do.




回答2:


As per Alberto's answer you can add modify headers to the Firefox profile if you are using it:

FirefoxDriver createFirefoxDriver() throws URISyntaxException, IOException {
    FirefoxProfile profile = new FirefoxProfile();
    URL url = this.getClass().getResource("/modify_headers-0.7.1.1-fx.xpi");
    File modifyHeaders = modifyHeaders = new File(url.toURI());

    profile.setEnableNativeEvents(false);
    profile.addExtension(modifyHeaders);

    profile.setPreference("modifyheaders.headers.count", 1);
    profile.setPreference("modifyheaders.headers.action0", "Add");
    profile.setPreference("modifyheaders.headers.name0", SOME_HEADER);
    profile.setPreference("modifyheaders.headers.value0", "true");
    profile.setPreference("modifyheaders.headers.enabled0", true);
    profile.setPreference("modifyheaders.config.active", true);
    profile.setPreference("modifyheaders.config.alwaysOn", true);

    DesiredCapabilities capabilities = new DesiredCapabilities();
    capabilities.setBrowserName("firefox");
    capabilities.setPlatform(org.openqa.selenium.Platform.ANY);
    capabilities.setCapability(FirefoxDriver.PROFILE, profile);
    return new FirefoxDriver(capabilities);
}



回答3:


I encountered the same issue 2 weeks ago. I tried the approach suggested by Carl but it seemed a bit to much "overhead" to realize this task.

In the end I used the fiddlerCore library in order to host a proxy server in my code and just use the build in proxy feature of web driver 2. It works pretty good and is much more intuitive/stable in my opinion. Furthermore it works for all browsers and you don't depend on binary files which you need to maintain inside your code repository.

Here an example made in C# for Chrome (Firefox and IE are very similar)

// Check if the server is already running
if (!FiddlerApplication.IsStarted())
{
    // Append your delegate to the BeforeRequest event
    FiddlerApplication.BeforeRequest += delegate(Fiddler.Session oS)
    {
        // Make the modifications needed - change header, logging, ...
        oS.oRequest["SM_USER"] = SeleniumSettings.TestUser;
    };
    // Startup the proxy server
    FiddlerApplication.Startup(SeleniumSettings.ProxyPort, false, false);
}

// Create the proxy setting for the browser
var proxy = new Proxy();
proxy.HttpProxy = string.Format("localhost:{0}", SeleniumSettings.ProxyPort);

// Create ChromeOptions object and add the setting
var chromeOptions = new ChromeOptions();
chromeOptions.Proxy = proxy;

// Create the driver
var Driver = new ChromeDriver(path, chromeOptions);

// Afterwards shutdown the proxy server if it's running
if (FiddlerApplication.IsStarted())
{
    FiddlerApplication.Shutdown();
}


来源:https://stackoverflow.com/questions/6478672/how-to-send-an-http-requestheader-using-selenium-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!