如何使用Selenium 2发送http RequestHeader?

时间:2011-06-25 15:21:17

标签: selenium selenium-webdriver selenium-rc

我需要发送带有一些修改过的标头的Http请求。经过几个小时试图找到Selenium RC Selenium.addCustomRequestHeader的等效方法,我放弃并使用JavaScript作为我的目的。我原以为这会更容易!

有人知道更好的方法吗?

这就是我所做的:

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();
}

// ...

注意:为了简化这篇文章,我编辑了原始代码。我希望我没有提出任何错误!

4 个答案:

答案 0 :(得分:3)

不幸的是,你不能用Selenium 2更改标题。这是团队的一个有意识的决定,因为我们正在尝试创建一个模拟用户可以做的事情的浏览器自动化框架。

答案 1 :(得分:3)

根据Alberto的回答,您可以在Firefox配置文件中添加修改标题:

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);
}

答案 2 :(得分:0)

我在2周前遇到了同样的问题。我尝试了卡尔建议的方法,但它似乎有点太多"开销"实现这个任务。

最后,我使用了fiddlerCore库,以便在我的代码中托管代理服务器,并且只使用web驱动程序2的内置代理功能。在我看来,它工作得非常好,更加直观/稳定。此外,它适用于所有浏览器,并且您不依赖于需要在代码存储库中维护的二进制文件。

这里用C#为Chrome做了一个例子(Firefox和IE非常相似)

// 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();
}

答案 3 :(得分:0)

(此示例使用Chrome浏览器完成)

这就是我解决此问题的方式。希望对那些设置类似的人有所帮助。

  1. 将ModHeader扩展名添加到Chrome浏览器

如何下​​载Modheader?链接

ChromeOptions options = new ChromeOptions();
options.addExtensions(new File(C://Downloads//modheader//modheader.crx));

// Set the Desired capabilities 
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(ChromeOptions.CAPABILITY, options);

// Instantiate the chrome driver with capabilities
WebDriver driver = new RemoteWebDriver(new URL(YOUR_HUB_URL), options);
  1. 转到浏览器扩展并捕获ModHeader的本地存储上下文ID

Capture ID from ModHeader

  1. 导航到ModHeader的URL以设置本地存储上下文

// set the context on the extension so the localStorage can be accessed
driver.get("chrome-extension://idgpnmonknjnojddfkpgkljpfnnfcklj/_generated_background_page.html");

Where `idgpnmonknjnojddfkpgkljpfnnfcklj` is the value captured from the Step# 2
  1. 现在使用Javascript
  2. 将标头添加到请求中

   ((Javascript)driver).executeScript(
         "localStorage.setItem('profiles', JSON.stringify([{  title: 'Selenium', hideComment: true, appendMode: '', 
             headers: [                        
               {enabled: true, name: 'token-1', value: 'value-1', comment: ''},
               {enabled: true, name: 'token-2', value: 'value-2', comment: ''}
             ],                          
             respHeaders: [],
             filters: []
          }]));");

其中token-1value-1token-2value-2是要添加的请求标头和值。

  1. 现在导航到所需的Web应用程序。

    driver.get("your-desired-website");