1

I am using Selenium WebDriver (a.k.a Selenium 2), and want to keep only one window across all test cases and avoid the new windows created by each test cases, so that I can work on consistent data on the web.

I've done my search but most of them are using Selenium RC, which appears to be very different from WebDriver (in that I don't know how to keep session ID etc.). And also, I am using c#..

Could you please provide any easy sample code to demonstrate your thoughts. I really appreciate it!!

Thanks in advance!

Ripon Al Wasim
  • 36,924
  • 42
  • 155
  • 176
jamesdeath123
  • 4,268
  • 11
  • 52
  • 93

4 Answers4

4

well I'd share approach I currently use on my project. Try using static initialization of webdriver. Hope this will do a trick for you. Well, my structure is quite simple: I've got BaseSeleniumTest.java where I store all my basic methods. Also I have other TestSuite.java which inherit all methods from BaseSeleniumTest.java: enter image description here

BaseSeleniumTest.java:

package simulator.selenium;


import com.google.common.base.Function;
import com.thoughtworks.selenium.SeleneseTestBase;
import org.apache.commons.lang.RandomStringUtils;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.openqa.selenium.*;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.core.io.support.PropertiesLoaderUtils;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;
import java.util.concurrent.TimeUnit;




public class BaseSeleniumTest extends SeleneseTestBase {
    static WebDriver driver;

    private static Logger log = LoggerFactory.getLogger(BaseSeleniumTest.class);
    private String loginBaseUrl;


    @BeforeClass
    public static void firefoxSetUp() throws MalformedURLException {

          DesiredCapabilities capability = DesiredCapabilities.firefox();

        driver = new FirefoxDriver();  

        driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
        driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
        driver.manage().window().setSize(new Dimension(1920, 1080));
    }
    @Before
    public void homePageRefresh() throws IOException {
        driver.manage().deleteAllCookies();
        driver.get(propertyKeysLoader("login.base.url"));
    }


    @AfterClass
    public static void closeFirefox(){
        driver.quit();

    }

    public WebElement findElementByXpath(String key) throws IOException {

        int i=0;
        while(!isElementPresent(By.xpath(propertyKeysLoader(key))) && i<5){
            driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
            i++;
        }
        return fluentWait(By.xpath(propertyKeysLoader(key)));
    }
    public WebElement findElementByCssSelector(String key) throws IOException {

        int i=0;

        while(!isElementPresent(By.cssSelector(propertyKeysLoader(key))) && i<5){
            driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
            i++;
        }

    }


    public void locatorFindingHandling(String key) throws IOException /*throws IOException*/ {

        fluentWait(By.cssSelector(propertyKeysLoader(key))).click();

    }
    public void locatorFindingHandling(String key, String key1) throws IOException {

        driver.findElement(By.xpath(propertyKeysLoader(key))).sendKeys(propertyKeysLoader(key1));

    }



    public String propertyKeysLoader(String key) throws IOException {
        Properties props = PropertiesLoaderUtils.loadAllProperties("selenium-config.properties");
        PropertyPlaceholderConfigurer props2 = new PropertyPlaceholderConfigurer();
        props2.setProperties(props);
        return (String)props.get(key)          ;
    }

    public WebElement fluentWait(final By locator){
        Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
                .withTimeout(30, TimeUnit.SECONDS)
                .pollingEvery(5, TimeUnit.SECONDS)
        .ignoring(org.openqa.selenium.NoSuchElementException.class);
        WebElement foo = wait.until(
                new Function<WebDriver, WebElement>() {
                    public WebElement apply(WebDriver driver) {
                        return driver.findElement(locator);
                    }
                }
        );
        return  foo;              }     ;


   public boolean isElementPresent(By selector)
   {
       return driver.findElements(selector).size()>0;
   }

    public boolean isElementVisible(By selector){
        return driver.findElement(selector).isDisplayed();
    }

    public void jsDirectClickUsingDOM_GEBi(String key) throws IOException {
        JavascriptExecutor js = (JavascriptExecutor) driver;
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("document.getElementById(\'"+propertyKeysLoader(key) +"\').click();");
        js.executeScript(stringBuilder.toString());

    }

    public void jsCodeExecution(String jsCode){
        JavascriptExecutor js = (JavascriptExecutor)driver;
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(jsCode);
        js.executeScript(stringBuilder.toString());
    }

    public void jsDirectClickUsingDOM_GEBTagName(String tagName,int argNum) throws IOException {
        JavascriptExecutor js = (JavascriptExecutor) driver;
        StringBuilder stringBuilder = new StringBuilder();
//        stringBuilder.append("document.getElementsByClassName(\'"+propertyKeysLoader(key) +"\')["+argArrNum+"].click();");
//        stringBuilder.append("document.getElementsByTagName(\'"+tagName+"\')[document.getElementsByTagName('div').length-"+argNum+"].click()");
        stringBuilder.append("document.getElementsByTagName(\'"+tagName+"\')[document.getElementsByTagName(\'"+tagName+"\').length-"+argNum+"].click()");
        js.executeScript(stringBuilder.toString());

    }


    public String jsGetColor(String css){

        JavascriptExecutor js = (JavascriptExecutor) driver;
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("var x=$(\'"+css+"\');");
        stringBuilder.append("return x.css('color')");
        String res= (String) js.executeScript(stringBuilder.toString());
        return res;

    }


    public String randomStringGenerator(){
        return  RandomStringUtils.randomAlphabetic(8);
    }

    public String randomIntSequenceGenerator(){
        return RandomStringUtils.randomNumeric(6);
    }
}

So to conclude my answer basic solution to your problem is :

   static WebDriver driver;   

        private String loginBaseUrl;


        @BeforeClass
        public static void firefoxSetUp() throws MalformedURLException {

              DesiredCapabilities capability = DesiredCapabilities.firefox();

            driver = new FirefoxDriver();  

            driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
            driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
            driver.manage().window().setSize(new Dimension(1920, 1080));
        }
        @Before
        public void homePageRefresh() throws IOException {
            driver.manage().deleteAllCookies();
            driver.get(propertyKeysLoader("login.base.url"));
        }


        @AfterClass
        public static void closeFirefox(){
            driver.quit();

        }

Hope this helps you.

eugene.polschikov
  • 7,254
  • 2
  • 31
  • 44
  • It seems pretty helpful! I will try out a little bit later but it makes sense! Thank you! – jamesdeath123 Nov 29 '12 at 21:04
  • hmm, just a question, what is SeleneseTestBase in your case? You have BaseSeleniumTest extends it. I assume BaseSeleniumTest is the abstract class where some other thing extends it? – jamesdeath123 Nov 29 '12 at 21:10
  • well, Class SeleneseTestBase is in com.thoughtworks.selenium (selenium framework class) Provides a base class that implements some handy functionality for Selenium testing (you are not required to extend this class). This class adds a number of "verify" commands, which are like "assert" commands, but they don't stop the test when they fail. Instead, verification errors are all thrown at once during tearDown. Details on it: http://www.jarvana.com/jarvana/view/org/seleniumhq/selenium/selenium-java/2.1.0/selenium-java-2.1.0-javadoc.jar!/com/thoughtworks/selenium/SeleneseTestBase.html – eugene.polschikov Nov 29 '12 at 22:40
  • It turned out what I asked for has fairly simple answer: just use [TestFixtureTearDown] instead of [TearDown] and it will keep a single window for all test cases in defined in the same class :) – jamesdeath123 Jan 02 '13 at 19:07
  • comment out driver.quit(); in the test scripts and it conditionally invoke webdriver like if (driver == null) { //code to invoke the desired webdriver} else{ //do nothing} ...your tests will be conducted in single session. – Anirudh Apr 20 '14 at 11:36
1

You can extend RemoteWebDriver and override startSession method like this:

@Override
protected void startSession(Capabilities desiredCapabilities) {
String sid = getPreviousSessionIdFromSomeStorage();
if (sid != null) {
  setSessionId(sid);
  try {
    getCurrentUrl();
  } catch (WebDriverException e) {
    // session is not valid
    sid = null;
  }
}
if (sid == null) {
  super.startSession(desiredCapabilities);
  saveSessionIdToSomeStorage(getSessionId().toString());
}
}

Put this code in your class where you are creating the driver.

Abhishek_Mishra
  • 4,551
  • 4
  • 25
  • 38
1

This worked for me in webdriver.io

var webdriverio = require('webdriverjs-angular');
var options = {
    desiredCapabilities: {
        browserName: 'firefox'
    },
    ngRoot: 'html' // main application selector
};

var wd = webdriverio.remote(options).init();

var wd2 = webdriverio.remote(options);
wd2.requestHandler.sessionID=wd.requestHandler.sessionID
wd2.url('http://www.seamless.com');
citynorman
  • 4,918
  • 3
  • 38
  • 39
0

CREDIS: Can't save the session of Whatsapp web with Selenium c#


  1. First choose a FOLDER where to save the webdriver session.

  1. Then if folder not exist create a new Chrome Driver Session and saveit using this function:

    public static IWebDriver OpenNewChrome(string FolderPathToStoreSession)
    {
        ChromeOptions options = null;
        ChromeDriver driver = null;
        try
        {
            //chrome process id
            int ProcessId = -1;
            //time to wait until open chrome
            //var TimeToWait = TimeSpan.FromMinutes(TimeToWaitInMinutes);
            ChromeDriverService cService = 
            ChromeDriverService.CreateDefaultService();
            //hide dos screen
            cService.HideCommandPromptWindow = true;
            options = new ChromeOptions();
            //options.AddArguments("chrome.switches", "--disable-extensions");

            //session file directory
            options.AddArgument("--user-data-dir=" + FolderPathToStoreSession);
            driver = new ChromeDriver(cService, options);

            //set process id of chrome
            ProcessId = cService.ProcessId;

            return driver;
        }
        catch (Exception ex)
        {
            if (driver != null)
            {
                driver.Close();
                driver.Quit();
                driver.Dispose();
            }
            driver = null;
            throw ex;
        }
    }
  1. If the folder exist open again the Previus Chrome session using this function:

public static IWebDriver OpenOldChrome(string FolderPathToStoreSession)
    {
        ChromeOptions options = null;
        ChromeDriver driver = null;
        try
        {
            //chrome process id
            int ProcessId = -1;
            //time to wait until open chrome
            //var TimeToWait = TimeSpan.FromMinutes(TimeToWaitInMinutes);
            ChromeDriverService cService = ChromeDriverService.CreateDefaultService();

            //hide dos screen
            cService.HideCommandPromptWindow = true;

            options = new ChromeOptions();

            //session file directory
            options.AddArgument("--user-data-dir=" + FolderPathToStoreSession);
            //options.AddArgument("--no-sandbox");

            //options.AddArgument("--headless=new");

            //Add EditThisCookie Extension
            //options.AddArguments("chrome.switches", "--disable-extensions");
 //options.AddExtensions("\\ChromeExtensions\\editthiscookie.crx");

            driver = new ChromeDriver(cService, options);

            //set process id of chrome
            ProcessId = cService.ProcessId;

            return driver;
        }
        catch (Exception ex)
        {
            if (driver != null)
            {
                driver.Close();
                driver.Quit();
                driver.Dispose();
            }
            driver = null;
            throw ex;
        }
    }

PS. If you doesn't want Chrome Extensions to be installed or saved uncomment this option:

options.AddArguments("chrome.switches", "--disable-extensions");
gabrielepetteno
  • 89
  • 1
  • 11