buni
buni

Reputation: 662

Use Selenium with same browser session

import java.util.regex.Pattern;
import java.util.concurrent.TimeUnit;
import org.junit.*;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.support.ui.Select;

public class Test1 {
  private WebDriver driver;
  private String baseUrl;
  private boolean acceptNextAlert = true;
  private StringBuffer verificationErrors = new StringBuffer();

  @Before
  public void setUp() throws Exception {
    System.setProperty("webdriver.ie.driver",  "D:/Development/ProgrammingSoftware/Testing/IEDriverServer.exe");

    WebDriver driver = new InternetExplorerDriver();
    baseUrl = "http://seleniumhq.org/";
    driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
  }

  @Test
  public void test1() throws Exception {
    driver.get(baseUrl + "/download/");
    driver.findElement(By.linkText("Latest Releases")).click();
    driver.findElement(By.linkText("All variants of the Selenium Server: stand-alone, jar with dependencies and sources.")).click();
  }

  @After
  public void tearDown() throws Exception {
    driver.quit();
    String verificationErrorString = verificationErrors.toString();
    if (!"".equals(verificationErrorString)) {
      fail(verificationErrorString);
    }
  }

  private boolean isElementPresent(By by) {
    try {
      driver.findElement(by);
      return true;
    } catch (NoSuchElementException e) {
      return false;
    }
  }

  private String closeAlertAndGetItsText() {
    try {
      Alert alert = driver.switchTo().alert();
      if (acceptNextAlert) {
        alert.accept();
      } else {
        alert.dismiss();
      }
      return alert.getText();
    } finally {
      acceptNextAlert = true;
    }
  }
}

I would like to have the IE with the same session but this code opens always a new instance of IE. How I get this work?

Upvotes: 0

Views: 3230

Answers (2)

rajeshkt
rajeshkt

Reputation: 1

This question has been asked several times in the past and the one I'm about to answer is not even close to recent. However I still gonna go ahead and post an answer because recently I've been engulfed with questions related to same browser session. How would I be able to leverage the browser which is already open, so I can continue my test run, rather than restart it from the scratch. It's even painstaking in some cases, after navigating through tons of pages, when you encounter the issue of restarting your Selenium test. Instead I was left wondering "where is the silver bullet?". Finally I saw one of the articles written by "http://tarunlalwani.com/post/reusing-existing-browser-session-selenium/". However still there are a few missing links. So I wanted to unravel it here with the help of a suitable example. In the following code snippet, I'm trying to launch SeleniumHQ and Clicking Download link in a Selenium session in Chrome browser.

    System.setProperty("webdriver.chrome.driver","C:\\Selenium\\chromedriver.exe");
//First Session
        ChromeDriver driver = new ChromeDriver();
        HttpCommandExecutor executor = (HttpCommandExecutor) 
        driver.getCommandExecutor();
        URL url = executor.getAddressOfRemoteServer();
        SessionId session_id = driver.getSessionId();
        storeSessionAttributesToFile("Id",session_id.toString());
        storeSessionAttributesToFile("URL",url.toString());
        driver.get("https://docs.seleniumhq.org/");
        WebElement download = driver.findElementByLinkText("Download");
        download.click();

If you read the above code, I'm capturing the URL of Selenium remote server and the session id of the current selenium (browser) session and writing it to a properties file. Now if I need to continue executing in the same browser window/session, despite stopping the current test run, all I need to do is comment the code below the commented First session in the aforementioned code snippet and continuing your tests from the code below:

System.setProperty("webdriver.chrome.driver","C:\\Selenium\\chromedriver.exe");
//First Session
  //ChromeDriver driver = new ChromeDriver();
  //HttpCommandExecutor executor = (HttpCommandExecutor) driver.getCommandExecutor();
 //URL url = executor.getAddressOfRemoteServer();
//SessionId session_id = driver.getSessionId();
//storeSessionAttributesToFile("Id",session_id.toString());
//      storeSessionAttributesToFile("URL",url.toString());
//      driver.get("https://docs.seleniumhq.org/");
//      WebElement download = driver.findElementByLinkText("Download");
//      download.click();
//Attaching to the session
    String existingSession = readSessionId("Id");
    String url1 = readSessionId("URL");
    URL existingDriverURL = new URL(url1);
    RemoteWebDriver attachToDriver = createDriverFromSession(existingSession, existingDriverURL);
    WebElement previousReleases = attachToDriver.findElementByLinkText("Previous Releases");
    previousReleases.click();

Now you may have to refactor and rename the driver object (even leaving the name would still work, but I just wanted to differentiate between attaching it to an existing driver and the launching the driver). In the above code block, I continue my tests, after reading and assigning the URL and sessionid and create the driver from session to continue leveraging the browser and session. Please view the complete code below:

package org.openqa.selenium.example;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Collections;
import java.util.Properties;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.Command;
import org.openqa.selenium.remote.CommandExecutor;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.Response;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.W3CHttpCommandCodec;
import org.openqa.selenium.remote.http.W3CHttpResponseCodec;

public class AttachingToSession {

public static String SESSION_FILE = "C:\\example\\Session.Properties";
public static Properties prop = new Properties();

public static void main(String[] args) throws Exception {
    System.setProperty("webdriver.chrome.driver","C:\\Selenium\\chromedriver.exe");
//First Session
    ChromeDriver driver = new ChromeDriver();
    HttpCommandExecutor executor = (HttpCommandExecutor) driver.getCommandExecutor();
    URL url = executor.getAddressOfRemoteServer();
    SessionId session_id = driver.getSessionId();
    storeSessionAttributesToFile("Id",session_id.toString());
    storeSessionAttributesToFile("URL",url.toString());
    driver.get("https://docs.seleniumhq.org/");
    WebElement download = driver.findElementByLinkText("Download");
    download.click();
//Attaching to the session
    String existingSession = readSessionId("Id");
    String url1 = readSessionId("URL");
    URL existingDriverURL = new URL(url1);
    RemoteWebDriver attachToDriver = createDriverFromSession(existingSession, existingDriverURL);
    WebElement previousReleases = attachToDriver.findElementByLinkText("Previous Releases");
    previousReleases.click();
}

public static RemoteWebDriver createDriverFromSession(final String sessionId, URL command_executor){
    CommandExecutor executor = new HttpCommandExecutor(command_executor) {

        @Override
        public Response execute(Command command) throws IOException {
            Response response = null;
            if (command.getName() == "newSession") {
                response = new Response();
                response.setSessionId(sessionId);
                response.setStatus(0);
                response.setValue(Collections.<String, String>emptyMap());
                try {
                    Field commandCodec = null;
                    commandCodec = this.getClass().getSuperclass().getDeclaredField("commandCodec");
                    commandCodec.setAccessible(true);
                    commandCodec.set(this, new W3CHttpCommandCodec());

                    Field responseCodec = null;
                    responseCodec = this.getClass().getSuperclass().getDeclaredField("responseCodec");
                    responseCodec.setAccessible(true);
                    responseCodec.set(this, new W3CHttpResponseCodec());
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

            } else {
                response = super.execute(command);
            }
            return response;
        }
    };

    return new RemoteWebDriver(executor, new DesiredCapabilities());
}


public static void storeSessionAttributesToFile(String key,String value) throws Exception{
        OutputStream output = null;
        try{
            output = new FileOutputStream(SESSION_FILE);
            //prop.load(output);
            prop.setProperty(key, value);
            prop.store(output, null);
        }
        catch(IOException e){
            e.printStackTrace();
        }
        finally {
            if(output !=null){
                output.close();
            }
        }

}

public static String readSessionId(String ID) throws Exception{

    Properties prop = new Properties();
    InputStream input = null;
    String SessionID = null;
    try {
        input = new FileInputStream(SESSION_FILE);
        // load a properties file
        prop.load(input);
        // get the property value and print it out
        System.out.println(prop.getProperty(ID));
        SessionID = prop.getProperty(ID);
    } catch (IOException ex) {
        ex.printStackTrace();
    } finally {
        if (input != null) {
            try {
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return SessionID;
}
}

Upvotes: 0

Code Enthusiastic
Code Enthusiastic

Reputation: 2847

I don't think it is possible to attach driver to an existing session.

If You've done executing a test method and if you want to execute another test method which is present in another class or package, call the method by passing the present driver to it so that you can use the present instance of the driver over there.

Upvotes: 2

Related Questions