0

I have a situation where webdriver object is hide in a wrapper in dependency project and I can only able to retrieve session id in string format and return driver.manage()/cookies from those functions.

Now I am trying to use this session Id and pass it to my webdriver reference variable so I can extend my requirement.

I have also find an reference of same as below:

https://tarunlalwani.com/post/reusing-existing-browser-session-selenium-java/

I tried but having error as below:

Exception in thread "main" org.openqa.selenium.json.JsonException: Unable to determine type from: <. Last 1 characters read: < Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03' System info: host: 'xxxxxx', ip: 'xxx.xx.xx.xx', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_151'

Code with cookie:

public static void main(String[] args) throws URISyntaxException, MalformedURLException {
    WebDriver driver = null;

    //WebDriverManager.chromedriver().setup();
    WebDriverManager.chromedriver().version(Configuration.getConfigurationValueForProperty("chrome-version"))
            .setup();
    ChromeOptions options = new ChromeOptions();
    options.addArguments("start-maximized");
    options.addArguments("enable-automation");
    // options.addArguments("--headless");
    options.addArguments("--no-sandbox");
    options.addArguments("--disable-infobars");
    options.addArguments("--disable-dev-shm-usage");
    options.addArguments("--disable-browser-side-navigation");
    options.addArguments("--disable-gpu");
    driver = new ChromeDriver(options);
    driver.get(Configuration.applicationUnderTestURL());

    Set<Cookie> name =driver.manage().getCookies();

    WebDriver driver3 = null;

    for(Cookie test: name) 
    {
        driver3.manage().addCookie(test);
    }

    driver3.get("https://stackoverflow.com/questions/8638241/setting-cookie-through-foreach-loop-inside-while-loop");

}

Demo Code I have tried to with session id :

package stepdef;

import java.io.IOException;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
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;

import automationframework.Configuration;
import io.github.bonigarcia.wdm.WebDriverManager;

public class testing {

public static void main(String[] args) throws URISyntaxException, MalformedURLException {
    WebDriver driver = null;

    //WebDriverManager.chromedriver().setup();
    WebDriverManager.chromedriver().version(Configuration.getConfigurationValueForProperty("chrome-version"))
            .setup();
    ChromeOptions options = new ChromeOptions();
    options.addArguments("start-maximized");
    options.addArguments("enable-automation");
    // options.addArguments("--headless");
    options.addArguments("--no-sandbox");
    options.addArguments("--disable-infobars");
    options.addArguments("--disable-dev-shm-usage");
    options.addArguments("--disable-browser-side-navigation");
    options.addArguments("--disable-gpu");
    driver = new ChromeDriver(options);
    driver.get(Configuration.applicationUnderTestURL());

    SessionId session = ((ChromeDriver)driver).getSessionId();

    String session2 = session.toString();

    System.out.println(session2);

    String str = "http://google.com"; // just passing random URL as I have only session id
    URI uri = new URI(str);
    URL url = uri.toURL();


    RemoteWebDriver driver2 = createDriverFromSession(session, url);    
    driver2.get("http://tarunlalwani.com"); // here I am getting error where I need to resue the existing browser using session id



}

public static RemoteWebDriver createDriverFromSession(final SessionId 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.toString());
            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());
}
}

Please Let me know if it is possible or any way around

Shubham Jain
  • 16,610
  • 15
  • 78
  • 125
  • What line throws the exception? – natn2323 Jan 02 '20 at 16:32
  • driver2.get("http://tarunlalwani.com"); this line – Shubham Jain Jan 02 '20 at 16:33
  • I have cookies too .. can I create Webdriver reference from exsiting cookies too? – Shubham Jain Jan 02 '20 at 16:36
  • I think you can. You could create a `WebDriver` instance and then load the existing cookies. From there, you *might* be able to access the website as if you were using the same browser as before. As reference, [this](https://stackoverflow.com/questions/15058462/how-to-save-and-load-cookies-using-python-selenium-webdriver) has been done in Python – natn2323 Jan 02 '20 at 16:39
  • I have added that code too but its throwing null error – Shubham Jain Jan 02 '20 at 16:40
  • What error? It looks like you're not initializing the `WebDriver` object. You set it to `null` at first, and never to `new ChromeDriver()` or something – natn2323 Jan 02 '20 at 16:41
  • If I initialize it, then it will open an another window while I want to continnue with existing browser which is open – Shubham Jain Jan 02 '20 at 16:42
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/205245/discussion-between-natn2323-and-shubham-jain). – natn2323 Jan 02 '20 at 16:49

2 Answers2

0

It appears that trying to modify an existing WebDriver object's Options is not possible. That means that trying to modify an existing WebDriver object's cookies or session ID is also not possible.

The only workaround here, then, would be to create a new WebDriver instance. However, creating a new WebDriver instance is a restriction that the OP has placed, so this isn't viable.

natn2323
  • 1,983
  • 1
  • 13
  • 30
0

Assuming you don't have access to driver instance and only have access to session id of wrapped driver. Here we will try to attached existing session to newly created instance. Ultimately we will quit both the instances.

Extend the RemoteWebDriver class

public class MyRemoteDriver extends RemoteWebDriver{

public MyRemoteDriver(URL remoteAddress, Capabilities capabilities) {
    super(remoteAddress,capabilities);
  }

@Override 
public void setSessionId(String opaqueKey) {
    super.setSessionId(opaqueKey);
  }


}

Now Test : Using MyRemoteDriver we will create new instance and attached existing session to this instance .

public class StackOverflow59566324 {

@Test
public void testing() {
    WebDriver driver = null;
    MyRemoteDriver mydriver = null;

    try {

        ChromeOptions option = new ChromeOptions();

        final URL url = new URL("http", "localhost", 4444, "/wd/hub");

        driver = new RemoteWebDriver(url, option);
        driver.get("https://www.google.com");

        mydriver = new MyRemoteDriver(url, option);
        mydriver.get("http://www.google.com");

       // store new session id 
        String newSession = mydriver.getSessionId().toString();

        // Set the session of wrapped driver here 
        mydriver.setSessionId(((RemoteWebDriver)driver).getSessionId().toString());  

        // Now we are controlling wrapped driver session using our own driver instance
        mydriver.get("http://www.bing.com");
        mydriver.manage().window().maximize();

        // Just to see the magic
        Thread.sleep(10000);

        //Quit the wrapped session 
        mydriver.quit();

        //Quit the new orphaned session which we are not using anyway 
        mydriver.setSessionId(newSession);
        mydriver.quit();

    }        
    catch(Exception e) {          
        System.out.println(e.getMessage());          
        mydriver.quit();           
    }
}

}
Rahul L
  • 4,249
  • 15
  • 18