4

I want to add "iv-user" request header to log into web app.
I'm using the newest ChromeDriver. Using extensions like ModHeader or ModifyHeaders is not working in this case. Fiddler is working, but I need a solution that will allow me to change accounts during the test case execution.

Can someone help me with this, please?

Now, I'm trying to use BrowserMob Proxy in Embedded mode, to achieve it, but something is not working. Proxy is running and ChromeDriver too, request header is set and sent to the app server, but after checking network log in browser, this custom header is not received by it.

Class Case:

@BeforeEach
public void setUp() throws Exception {
    LOGER.setLevel(Level.WARNING);
    loadProperties();

    if (driver != null) {
        driver.quit();
    }

    BrowserMobProxy proxy = new BrowserMobProxyServer();
    proxy.start(0);
    Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy);

    proxy.addRequestFilter((request, contents, messageInfo)->{
        request.headers().add("iv-user", "login");
        System.out.println(request.headers().entries().toString());
        return null;
    });

    chromeOptions = new ChromeOptions();
    String proxyOption = "--proxy-server=" + seleniumProxy.getHttpProxy();
    chromeOptions.addArguments(proxyOption);
    chromeOptions.addArguments("-incognito");
    chromeOptions.addArguments("disable-infobars");
    chromeOptions.setCapability(CapabilityType.PLATFORM_NAME, Platform.WINDOWS);
    chromeOptions.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.ACCEPT);
    chromeOptions.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
    System.setProperty("webdriver.chrome.driver", CHROMEDRIVER_PATH);
    driver = new ChromeDriver(chromeOptions);

    actions = new Actions(driver);
    driver.manage().timeouts().implicitlyWait(IMPLICITLY_WAIT_TIME_OUT, TimeUnit.SECONDS);

    driver.manage().window().maximize();
    new WebDriverWait(driver, 30);
    wait = new FluentWait<WebDriver>(driver)
            .withTimeout(ConstConfig.FLUENTWAIT_TIMEOUT_SEC, TimeUnit.SECONDS)
            .pollingEvery(1, TimeUnit.SECONDS)
            .ignoring(StaleElementReferenceException.class)
            .ignoring(NoSuchElementException.class)
            .ignoring(ElementNotVisibleException.class);
    jsExecutor = (JavascriptExecutor) driver;
}

Class Test:

public class Test_Proxy extends Case {

@Test
public void test_Proxy() throws Exception {

    try{
        driver.get(TESTAPP_URL);
        MainMenu mainMenu = new MainMenu();
        //..........

    } finally {//....................}}}
5
+50

Here is the completed example that demonstrates how you can modify requests from your Selenium tests. To demonstrate one I have created a sample REST mock service via SoapUI that would return just a {"SUCCESS"} message for any response.

The test code (TestNg is used for test running, and borwsermob-proxy for proxying requests):

public class MiscTests {

    WebDriver driver;

    @BeforeTest
    public void setUp(){

        BrowserMobProxy proxy = new BrowserMobProxyServer();
        proxy.start(0);
        Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy);

        // put our custom header to each request
        proxy.addRequestFilter((request, contents, messageInfo)->{
            request.headers().add("my-test-header", "my-test-value");
            System.out.println(request.headers().entries().toString());
            return null;
        });

        // Setting up Proxy for chrome
        ChromeOptions opts = new ChromeOptions();
        String proxyOption = "--proxy-server=" + seleniumProxy.getHttpProxy();
        opts.addArguments(proxyOption);
        System.setProperty("webdriver.chrome.driver", "E:/Dev/WebDrivers/chromedriver.exe");
        driver = new ChromeDriver(opts);
    }

    @Test
    public void testProxifying(){
        driver.get("http://localhost:8080/");
        Assert.assertEquals(driver.findElement(By.xpath("//body")).getText(), "{\"SUCCESS\"}");
    }

    @AfterTest
    public void tearDown(){
        if(driver != null){
            driver.quit();
            System.out.println("Driver was instantiated. Quitting..");
        }else{
            System.out.println("Driver was null so nothing to do");
        }
    }

}

In above code you set up a proxy and configure the request filter that process all the outgoing requests. In that filter you add a sample header (modify according to your purpose). In SoapUI log we can see that our added header has successfully came to the server.

enter image description here

  • Alexey, I've used your code, but it is not working. BMP starts, and Chrome is running, but network log in browser shows, that this header is not sent in the request. I'll update the question. – M. Murawski Jan 15 at 16:38
  • 1
    Your log in browser won't show the new header because it is altered after the request leaves the browser. – Alexey R. Jan 15 at 16:54
  • Okay, but when I'm using manually ModHeader extension, it shows up in log, and logs me in. (Doesn't work with ChromeDriver). – M. Murawski Jan 15 at 17:18
  • @M.Murawski You can check with httpbin.org/get. Test with System.out.println(driver.getPageSource()); It responds with the headers which come from your client. I tested https connection in that way and it worked in my case. If in your case your header will be returned, then your issue has nothing to do with headers. – Alexey R. Jan 15 at 19:05
3

Selenium doesn't have API to do that. You need to use something external.

As Alexey suggested one of the solutions would be setting up proxy like this.

  • Michał, I'm already using BrowserMobProxy as you recommended, but now I have to develop a method to modify one of the request headers. Maybe you could help me with this? – M. Murawski Jan 11 at 13:53
3

You cannot achieve it by Selenium, but as you mentioned you are using BrowserMobProxy , I would recommend you to try once below .

  1. Apache Module mod_headers ( Refer : http://httpd.apache.org/docs/current/mod/mod_headers.html#page-header )
  2. You can also install Fiddler (http://www.fiddler2.com/fiddler2/) which is very easy to install (easier than Apache for example). After launching it, it will register itself as system proxy. Then open the "Rules" menu, and choose "Customize Rules..." to open a JavaScript file which allow you to customize requests. To add a custom header, just add a line in the OnBeforeRequest function:

    oSession.oRequest.headers.Add("MyHeader", "MyValue");

Hope this helps.

  • I've tried Fiddler, and it works, but I need something, which will be working in Continuous Integration (Bamboo), and will allow relogging to another account during test case execution. – M. Murawski Jan 15 at 16:46
  • Its really lengthy to explain it here with very little background hard to help. – Prasad_Joshi Jan 16 at 4:33

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.