This Node.js script uses Selenium WebDriver to create a Chrome browser session, setting environment variables and defining Chrome profile paths based on the operating system. The getClient
function creates a new Chrome browser session by setting Chrome profile paths, adding arguments, and returning a promise with the created client instance.
npm run import -- "selenium client"
const { updateOrAddSession } = importer.import("selenium sessions")
const { Builder, Browser, By, Key, until } = require('selenium-webdriver')
const chrome = require('selenium-webdriver/chrome');
const os = require('os')
const path = require('path')
const fs = require('fs')
const APP_SUPPORT = process.env.APP_SUPPORT_DIR || process.env.LOCALAPPDATA
|| (process.env.HOME ? (os.platform() == 'darwin' ? path.join(process.env.HOME, 'Library/Application Support') : path.join(process.env.HOME, '.config')) : void 0)
|| path.join(process.env.USERPROFILE, 'AppData/Local')
const WIN_PROFILE = path.join(APP_SUPPORT, 'Google/Chrome/User Data/Default')
const DARWIN_PROFILE = path.join(APP_SUPPORT, 'Google/Chrome/Default')
const LINUX_PROFILE = path.join(APP_SUPPORT, 'google-chrome/default')
const CHROME_PROFILE = os.platform() == 'win32' ? WIN_PROFILE : (os.platform() == 'darwin' ? DARWIN_PROFILE : LINUX_PROFILE)
async function getClient() {
//var client = await remote(webdriverServer);
//client.setTimeout({ 'implicit': 15000 })
//client.setTimeout({ 'pageLoad': 15000 })
//let windows = await client.getWindowHandles();
let builder = await new Builder().forBrowser(Browser.CHROME)
let options = new chrome.Options()
options.port = 4444
// this ensures the profile stays the same between runs, default is randomly generate a new profile every time
if(fs.existsSync(CHROME_PROFILE)) {
console.log('starting client', path.join(path.dirname(CHROME_PROFILE), 'not-Default'))
options.addArguments('--user-data-dir=' + path.join(path.dirname(CHROME_PROFILE), 'not-Default'))
} else {
console.log('starting client', '/tmp/profile-1')
options.addArguments('--user-data-dir=/tmp/profile-1')
}
options.addArguments('--no-sandbox')
options.addArguments('--disable-session-crashed-bubble')
options.addArguments('--disable-infobars')
options.addArguments('--new-window')
options.addArguments('--disable-geolocation')
options.addArguments('--disable-notifications')
options.addArguments('--show-saved-copy')
options.addArguments('--silent-debugger-extension-api')
options.addArguments('--disable-blink-features=AutomationControlled')
options.addArguments('--port=4444')
//options.setUserPreferences({'download.default_directory': });
options.setUserPreferences({
'profile.default_content_setting_values.notifications': 2,
'exited_cleanly': true,
'exit_type': 'None'
})
builder.setChromeOptions(options)
// builder.withCapabilities(options.toCapabilities())
let driver = builder.build()
await driver.manage().setTimeouts({ pageLoad: 10000 })
// keep track of session in case it can be reattached later
await updateOrAddSession((await driver.getSession()).getId())
//let sessions = await getSessions(driver, true)
let session = await driver.getSession()
let original = session.getId()
//for(let i = 0; i < sessions.length; i++) {
// if(sessions[i][1] != original) {
// await closeAllWindows(driver, sessions[i])
// }
//}
session.id_ = original
return driver
}
module.exports = getClient
const { updateOrAddSession } = require('./selenium-sessions');
const { Builder, Browser, By, Key, until } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const os = require('os');
const path = require('path');
const fs = require('fs');
const APP_SUPPORT_DIR = getSupportDir();
const CHROME_PROFILE =
os.platform() === 'win32'
? path.join(APP_SUPPORT_DIR, 'Google/Chrome/User Data/Default')
: (os.platform() === 'darwin'
? path.join(APP_SUPPORT_DIR, 'Google/Chrome/Default')
: path.join(APP_SUPPORT_DIR, 'google-chrome/default'));
async function getClient() {
// Create a new instance of the Chrome driver
const builder = new Builder().forBrowser(Browser.CHROME);
const chromeOptions = new chrome.Options();
// Set up Chrome options
chromeOptions
.addArguments('--no-sandbox')
.addArguments('--disable-session-crashed-bubble')
.addArguments('--disable-infobars')
.addArguments('--new-window')
.addArguments('--disable-geolocation')
.addArguments('--disable-notifications')
.addArguments('--show-saved-copy')
.addArguments('--silent-debugger-extension-api')
.addArguments('--disable-blink-features=AutomationControlled')
.addArguments('--port=4444');
// Use the existing profile if it exists
if (fs.existsSync(CHROME_PROFILE)) {
console.log('Using existing profile:', CHROME_PROFILE);
chromeOptions.addArguments('--user-data-dir=' + path.join(path.dirname(CHROME_PROFILE), 'not-Default'));
} else {
console.log('Creating new profile at:', '/tmp/profile-1');
chromeOptions.addArguments('--user-data-dir=/tmp/profile-1');
}
// Set Chrome user preferences
chromeOptions.setUserPreferences({
'profile.default_content_setting_values.notifications': 2,
'exited_cleanly': true,
'exit_type': 'None',
});
// Set up the driver
const driver = builder.setChromeOptions(chromeOptions).build();
// Set up timeouts
await driver.manage().setTimeouts({ pageLoad: 10000 });
// Keep track of the session
await updateOrAddSession((await driver.getSession()).getId());
return driver;
}
// Helper function to get the application support directory
function getSupportDir() {
const appSupportDir =
process.env.APP_SUPPORT_DIR ||
process.env.LOCALAPPDATA ||
(process.env.HOME
? os.platform() === 'darwin'
? path.join(process.env.HOME, 'Library/Application Support')
: path.join(process.env.HOME, '.config')
: void 0) ||
path.join(process.env.USERPROFILE, 'AppData/Local');
return appSupportDir;
}
module.exports = getClient;
Code Breakdown
This code is a Node.js script that utilizes the Selenium WebDriver to create a Chrome browser session. Here's a simplified explanation of the code:
The script starts by importing necessary dependencies:
selenium-webdriver
for interacting with the browserselenium-webdriver/chrome
for Chrome-specific capabilitiesos
for interacting with the operating systempath
for working with file pathsfs
for interacting with the file systemimporter
for importing Selenium sessions (not shown in the code snippet)The script sets environment variables for the application support directory:
APP_SUPPORT
is set to the first available environment variable:
APP_SUPPORT_DIR
LOCALAPPDATA
HOME/Library/Application Support
HOME/.config
USERPROFILE\AppData\Local
Based on the operating system, the script defines paths to the Chrome profile:
WIN_PROFILE
for WindowsDARWIN_PROFILE
for macOSLINUX_PROFILE
for LinuxCHROME_PROFILE
is set to the profile path based on the operating systemThe getClient
function creates a new Chrome browser session using Selenium WebDriver. Here's a breakdown of the function:
Builder
instance for the Chrome browser.chrome.Options
.--user-data-dir
).The function uses asynchronous code to create the client instance, which can be consumed by other parts of the script.
The script contains some unused code:
var client = await remote(webdriverServer);
is commented out.client.setTimeout
calls are commented out.let windows = await client.getWindowHandles();
is commented out.These lines seem to be leftovers from a previous implementation or testing.