webdriver | Cell 8 | Cell 10 | Search

The connectSession function connects a client to a session by managing existing sessions, creating a new one if necessary, and configuring the client's connection retry timeout. It returns the client's session ID if successful, or throws an error if an issue occurs.

Cell 9

var importer = require('../Core');
var readSessions = importer.import("load webdriver sessions");
var {
    getSessions,
    lockPromise,
    updateOrAddSession
} = importer.import("manage webdriver sessions");

var TIMEOUT = 10000;
var MAX_SESSIONS = 4;

function connectSession(client) {
    var isError = false;
    return lockPromise(true, true)
        .then(() => getSessions(client, true))
        // save current session
        .then(validSessions => {
            isError = false;
            var sessions = readSessions();
            // the next null or end will be the next available profile id
            var index = sessions.map(s => s[1]).indexOf(validSessions[0] || 0);
            if(index === -1) {
                console.log('session not found ' + validSessions[0]);
                index = sessions.length;
            }
            if(index >= MAX_SESSIONS) {
                throw new Error('Already running max sessions ' + MAX_SESSIONS);
            }
            client.options.connectionRetryTimeout = TIMEOUT;
            //client.options.capabilities['goog:chromeOptions'].args[0] = 'user-data-dir=/tmp/profile-' + index;
            // TODO: fix this, doesn't work on second init, keeps opening new windows if chrome profile path is alreading open for read/write
            if(typeof validSessions[0] !== 'undefined') {
                console.log('using existing session ' + index + ' - ' + validSessions[0]);
                client.sessionId = validSessions[0];
            } else {
                console.log('new session ' + index);
            }
        })
        .then(() => client.status())
        .then(r => updateOrAddSession(client.sessionId))
        .catch(e => {
            console.log(e);
            client.sessionId = null;
            isError = e;
        })
        .then(() => lockPromise(false, true))
        .then(() => {
            if(isError)
                throw isError;
            return client.sessionId;
        })
}
module.exports = connectSession;

What the code could have been:

const { importCore, manageWebdriverSessions, loadWebdriverSessions } = require('../Core');

const {
  getSessions,
  lockPromise,
  updateOrAddSession,
} = importCore('manage webdriver sessions');

const { readSessions } = importCore('load webdriver sessions');

const TIMEOUT = 10 * 1000; // 10 seconds
const MAX_SESSIONS = 4;

/**
 * Connect to a Webdriver session.
 * @param {object} client - Webdriver client instance.
 * @returns {Promise<string>} The ID of the connected session, or throws an error if failed.
 */
function connectSession(client) {
  let isError = false;

  return lockPromise(true, true)
   .then(() => {
      const validSessions = getSessions(client, true);
      return validSessions;
    })
   .then((validSessions) => {
      const sessions = loadWebdriverSessions();
      const lastIndex = sessions.map((s) => s[1]).indexOf(validSessions[0] || 0);
      if (lastIndex === -1) {
        console.log(`Session not found: ${validSessions[0]}`);
        lastIndex = sessions.length;
      }
      if (lastIndex >= MAX_SESSIONS) {
        throw new Error(`Already running max sessions: ${MAX_SESSIONS}`);
      }

      // Set connection retry timeout
      client.options.connectionRetryTimeout = TIMEOUT;

      // TODO: Fix Chrome profile path conflict issue
      if (typeof validSessions[0]!== 'undefined') {
        console.log(`Using existing session ${lastIndex} - ${validSessions[0]}`);
        client.sessionId = validSessions[0];
      } else {
        console.log(`New session ${lastIndex}`);
      }
    })
   .then(() => client.status())
   .then((r) => updateOrAddSession(client.sessionId))
   .catch((e) => {
      console.log(e);
      client.sessionId = null;
      isError = e;
    })
   .then(() => lockPromise(false, true))
   .then(() => {
      if (isError) {
        throw isError;
      }
      return client.sessionId;
    });
}

module.exports = connectSession;

Function Breakdown: connectSession

Parameters

Variables

Function Flow

  1. Acquires a lock using lockPromise to ensure exclusive access to session management.
  2. Retrieves existing valid sessions using getSessions and updates the sessions array.
  3. Checks if a session with the same ID already exists; if not, creates a new session index.
  4. Verifies that the number of sessions does not exceed the maximum allowed (MAX_SESSIONS).
  5. Configures the client's connection retry timeout using client.options.connectionRetryTimeout.
  6. Updates the client's session ID based on whether an existing session was found or a new one needs to be created.
  7. Queries the client's status using client.status.
  8. Updates the session in the session store using updateOrAddSession.
  9. Releases the lock using lockPromise.
  10. If an error occurred, throws the error; otherwise, returns the client's session ID.

Return Value