Tuesday, 23 August 2016

Selenium: WebDriver: Cookies handling

A Cookie is a small piece of data sent from a website and stored in a user's web browser while the user is browsing that website. Every time the user loads the website, the browser sends the cookie back to the server to notify the website of the user's previous activity.

Why should you handle cookies?
Lets assume, you are automating a web application, where you require a login, to access all other pages. To test all the other pages, you must login, and then proceed your testing.

 When you login to an application, a session is created by the server, and a sessionId points to the session. For all other subsequent communications with the server, browser sends this session id as part of cookie, server verifies the cookie comes from browser, if it is valid it sends proper response, else redirect to login page.

To test the application multiple times, you no need to login every time. Login once and store all the cookie information to a file, before executing your tests, load the cookie information to the WebDriver. That’s it, this will works, until your session expires. We can achieve above functionality using ‘driver.manage().getCookies()’ function. Following step-by-step summary explains, what I am going to do.

Step1: Get all cookies.
driver.manage().getCookies()
Above statement gets all the cookies for the current domain.

Step 2: Store all the cookies you got from step 1 to a properties file, so for all other requests, you can load this information to the driver.

Following snippet stores all the cookies to “session.properties” file.
private static void storeSessionProps(WebDriver driver) throws IOException {
         File cookiesFile = new File("session.properties");
         cookiesFile.delete();
         cookiesFile.createNewFile();

         try (PrintWriter file = new PrintWriter(cookiesFile, "UTF-8")) {
                  for (Cookie c : driver.manage().getCookies()) {
                           file.println("document.cookie='" + c.toString() + "';");
                  }
         }
}

Following snippet is used to load all the cookies information to WebDriver.

private static void loadPropertiesToDriver(WebDriver driver)
                           throws IOException {
         JavascriptExecutor js = (JavascriptExecutor) driver;
         String cookies = new String(Files.readAllBytes(Paths.get("session.properties")), "UTF-8");
         js.executeScript(cookies);
}

Note
One important step is (myself I struggled to find out this one), before creating a cookie, you need to load a page with a domain that will match the domain of the cookie.

Assume login.jsp is available at ‘http://localhost:8080/selenium_app/login’.

‘restricted.jsp’ is available at ‘http://localhost:8080/selenium_app/restricted’.


Following is the complete working application.

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;

import org.openqa.selenium.By;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class App {

 private static void loginApp(WebDriver driver) {
  driver.get("http://localhost:8080/selenium_app/login");

  WebElement userName = driver.findElement(By.name("userName"));
  WebElement password = driver.findElement(By.name("password"));

  userName.sendKeys("admin");
  password.sendKeys("admin");

  userName.submit();
 }

 private static void storeSessionProps(WebDriver driver) throws IOException {
  File cookiesFile = new File("session.properties");
  cookiesFile.delete();
  cookiesFile.createNewFile();

  try (PrintWriter file = new PrintWriter(cookiesFile, "UTF-8")) {
   for (Cookie c : driver.manage().getCookies()) {
    file.println("document.cookie='" + c.toString() + "';");
   }
  }
 }

 private static void loadPropertiesToDriver(WebDriver driver)
   throws IOException {
  JavascriptExecutor js = (JavascriptExecutor) driver;
  String cookies = new String(Files.readAllBytes(Paths
    .get("session.properties")), "UTF-8");
  System.out.println(cookies);
  js.executeScript(cookies);
 }

 public static void main(String[] args) throws InterruptedException,
   IOException {
  WebDriver driver = new FirefoxDriver();

  /*
   * Before creating a cookie, your need to load a page with a domain that
   * will match the domain of the cookie.
   */
  driver.get("http://localhost:8080/selenium_app");

  loginApp(driver);
  storeSessionProps(driver);

  loadPropertiesToDriver(driver);
  driver.get("http://localhost:8080/selenium_app/restricted");
  Thread.sleep(5000);

  driver.quit();
 }
}


Run above program once, it stores all the cookies information to ‘session.properties’. Next time onwards you can comment following line, and access the restricted.jsp page.


For demo purpose, I am going to use the web application developed at following url.

Above application has three pages login.jsp, restricted.jsp, success.jsp. You can access restricted.jsp, only after login (trying to access restricted.jsp without login will redirect to login.jsp page).

//loginApp(driver);
//storeSessionProps(driver);



Previous                                                 Next                                                 Home

1 comment: