Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

selenium js webdriver - attach to active session

I am using Node.js with selenium-webdriver package to run my tests.
every time a test start, the web driver starts a new session and open a new window.
I am trying to get the session Id and use it later using getSession() (doc referance link )

var webdriver = require('selenium-webdriver');
var SeleniumServer = require('selenium-webdriver/remote').SeleniumServer;

var server = new SeleniumServer('./seleniumServer/selenium-server-standalone-2.43.1.jar', {
    port: 4444
});
server.start();

var driver = new webdriver.Builder()
        .usingServer(server.address())
        .withCapabilities(webdriver.Capabilities.firefox())
        .build();

console.log(driver.getSession());

But this causes an exception:

getSession();
^
TypeError: Object [object Object] has no method 'getSession'
    at Object.<anonymous> (\testing\demo_1.js:14:3)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:906:3

Can anyone tell me what's wrong with it and how I get and set the selenium session id?
Most importantly, how do I use the sessionId for attaching to an opened browser session?

like image 565
Wazime Avatar asked Feb 12 '23 21:02

Wazime


2 Answers

If your webdriver building procedure was successful, driver should have method getSession(). The documentation of getSession() can be found here.

However, what is returned by getSession()is a promise, so you won't get the session id directly from the return value. You need to do this:

 driver.getSession()
                .then( function(session){
                    var session_id = session.getId();
                });

Very likely you need to save the session id in a file, and then when running the program next time, attach to this session id using this function:

browser = webdriver.WebDriver.attachToSession(...);

, of which documentation can be found here.

However, the problem is that the above function call attachToSession() does not notify you whether it has succeeded. The way I worked around it is to call browser.getTitle() using the returned WebDriver object, and wait for it to resolve/reject. And we will know whether we have successfully attached to the session id.


Set up webdriver:

In response to user3789620 's question, I put the code for setting up webdriver here:

var webdriver_server = 'http://localhost:9515', // chromedriver.exe serves at this port 
chrome = require('selenium-webdriver/chrome'),
options = new chrome.Options(),
webdriver = require( 'selenium-webdriver'),
Http = require( 'selenium-webdriver/http');
options.setChromeBinaryPath(your_chrome_binary_path);

var browser = new webdriver.Builder()
  .withCapabilities(webdriver.Capabilities.chrome())
  .setChromeOptions(options)
  .usingServer(webdriver_server)
  .build()

if( 'undefined' != typeof saved_session_id && saved_session_id!= ""){
  console.log("Going to attach to existing session  of id: " + saved_session_id);
  client = new Http.HttpClient( webdriver_server );
  executor = new Http.Executor( client);
  browser = webdriver.WebDriver.attachToSession( executor, saved_session_id);
}
like image 88
gm2008 Avatar answered Feb 14 '23 10:02

gm2008


Thanks to gm2008, whose answer got me on the right track. The attachToSession function was showing up as undefined for me which may have been an implementation change (I am using 4.0.0-alpha.1 of selenium-webdriver). However, I was able to accomplish the desired behavior with the following in TypeScript:

import wd, { WebDriver, Session } from 'selenium-webdriver'
import { HttpClient, Executor } from 'selenium-webdriver/http'

// My server URL comes from running selenium-standalone on my machine
const server: string = 'http://localhost:4444/wd/hub'

async function newBrowserSessionId(): Promise<string> {
  const browser: WebDriver = new wd.Builder()
    .withCapabilities(wd.Capabilities.chrome())
    .usingServer(server)
    .build()

  const session: Session = await browser.getSession()

  return session.getId()
}

async function getExistingBrowser(sessionId: string): Promise<WebDriver> {
  const client: HttpClient = new HttpClient(server)
  const executor: Executor = new Executor(client)
  const session: Session = new Session(sessionId, wd.Capabilities.chrome())

  return new WebDriver(session, executor)
}

async function driveExistingBrowser(browser: WebDriver): Promise<void> {
  await browser.get('https://www.google.com/')
}

async function closeExistingBrowser(browser: WebDriver): Promise<void> {
  await browser.close()
}

async function connectAndDrive(): Promise<void> {
  const sessionId: string = await newBrowserSessionId()
  const existingBrowser: WebDriver = await getExistingBrowser(sessionId)

  await driveExistingBrowser(existingBrowser)
  await closeExistingBrowser(existingBrowser)
}

connectAndDrive()

As long as you keep the session open and have a way of passing the ID around, you can attach to the existing Session even after your script that initiates it has completed executing. The closeExistingBrowser() function can be used whenever you are ready to perform cleanup.

like image 39
Jack Barry Avatar answered Feb 14 '23 10:02

Jack Barry