Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
8b75d92
Add environment variable support for driver executables in Chrome, Ed…
iampopovich Jun 21, 2025
7e7a17d
Add environment variable support for driver executables in Chrome, Ed…
iampopovich Jun 21, 2025
2679e24
Refactor service tests to remove unnecessary whitespace and improve r…
iampopovich Jun 21, 2025
6f32bc3
Merge branch 'trunk' into feat-14045/nodejs-env-var-driver-location
diemol Jun 23, 2025
09b2e91
Merge branch 'trunk' into feat-14045/nodejs-env-var-driver-location
diemol Jun 23, 2025
49c39ee
Add support for resolving relative driver executable paths using Baze…
iampopovich Jun 23, 2025
52bbdd5
applied format.sh
iampopovich Jun 24, 2025
e567d9d
Merge branch 'trunk' into feat-14045/nodejs-env-var-driver-location
iampopovich Jun 29, 2025
e1bf92e
Merge branch 'trunk' into feat-14045/nodejs-env-var-driver-location
diemol Jun 30, 2025
da56618
Remove unused runfiles import from chrome.js
iampopovich Jun 30, 2025
6506402
Refactor error handling in chrome.js and firefox.js to omit error var…
iampopovich Jun 30, 2025
de65192
Merge branch 'trunk' into feat-14045/nodejs-env-var-driver-location
iampopovich Jul 15, 2025
c0c470b
Merge branch 'trunk' into feat-14045/nodejs-env-var-driver-location
iampopovich Oct 6, 2025
c1cc944
Remove unused runfiles resolution logic from Chrome and Firefox servi…
iampopovich Oct 6, 2025
c7d90b0
Add tests to verify environment variable overrides for chromedriver a…
iampopovich Oct 6, 2025
683ed01
Merge branch 'trunk' into feat-14045/nodejs-env-var-driver-location
iampopovich Oct 6, 2025
6693bb3
Merge branch 'trunk' into feat-14045/nodejs-env-var-driver-location
iampopovich Oct 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions javascript/selenium-webdriver/chrome.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ const { Browser } = require('./lib/capabilities')
const chromium = require('./chromium')
const CHROME_CAPABILITY_KEY = 'goog:chromeOptions'

/**
* Environment variable that defines the location of the ChromeDriver executable.
* @const {string}
*/
const CHROME_DRIVER_EXE_ENV_VAR = 'SE_CHROMEDRIVER'

/** @type {remote.DriverService} */

/**
Expand All @@ -138,14 +144,15 @@ const CHROME_CAPABILITY_KEY = 'goog:chromeOptions'
class ServiceBuilder extends chromium.ServiceBuilder {
/**
* @param {string=} opt_exe Path to the server executable to use. If omitted,
* the builder will attempt to locate the chromedriver on the current
* the builder will attempt to use the chromedriver path from the
* SE_CHROMEDRIVER environment variable, then locate the chromedriver on the current
* PATH. If the chromedriver is not available in path, selenium-manager will
* download the chromedriver
* @throws {Error} If provided executable does not exist, or the chromedriver
* cannot be found on the PATH.
*/
constructor(opt_exe) {
super(opt_exe)
super(opt_exe || process.env[CHROME_DRIVER_EXE_ENV_VAR])
}
}

Expand Down
11 changes: 9 additions & 2 deletions javascript/selenium-webdriver/edge.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ const { Browser } = require('./lib/capabilities')
const chromium = require('./chromium')
const EDGE_CAPABILITY_KEY = 'ms:edgeOptions'

/**
* Environment variable that defines the location of the MSEdgeDriver executable.
* @const {string}
*/
const EDGE_DRIVER_EXE_ENV_VAR = 'SE_EDGEDRIVER'

/** @type {remote.DriverService} */

/**
Expand All @@ -93,13 +99,14 @@ const EDGE_CAPABILITY_KEY = 'ms:edgeOptions'
class ServiceBuilder extends chromium.ServiceBuilder {
/**
* @param {string=} opt_exe Path to the server executable to use. If omitted,
* the builder will attempt to locate the msedgedriver on the current
* the builder will attempt to use the msedgedriver path from the
* SE_EDGEDRIVER environment variable, then locate the msedgedriver on the current
* PATH.
* @throws {Error} If provided executable does not exist, or the msedgedriver
* cannot be found on the PATH.
*/
constructor(opt_exe) {
super(opt_exe)
super(opt_exe || process.env[EDGE_DRIVER_EXE_ENV_VAR])
this.setLoopback(true)
}
}
Expand Down
11 changes: 9 additions & 2 deletions javascript/selenium-webdriver/firefox.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ const { getBinaryPaths } = require('./common/driverFinder')
const { findFreePort } = require('./net/portprober')
const FIREFOX_CAPABILITY_KEY = 'moz:firefoxOptions'

/**
* Environment variable that defines the location of the GeckoDriver executable.
* @const {string}
*/
const GECKO_DRIVER_EXE_ENV_VAR = 'SE_GECKODRIVER'

/**
* Thrown when there an add-on is malformed.
* @final
Expand Down Expand Up @@ -489,10 +495,11 @@ function configureExecutor(executor) {
class ServiceBuilder extends remote.DriverService.Builder {
/**
* @param {string=} opt_exe Path to the server executable to use. If omitted,
* the builder will attempt to locate the geckodriver on the system PATH.
* the builder will attempt to use the geckodriver path from the
* SE_GECKODRIVER environment variable, then locate the geckodriver on the system PATH.
*/
constructor(opt_exe) {
super(opt_exe)
super(opt_exe || process.env[GECKO_DRIVER_EXE_ENV_VAR])
this.setLoopback(true) // Required.
}

Expand Down
6 changes: 4 additions & 2 deletions javascript/selenium-webdriver/ie.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const error = require('./lib/error')
const { getBinaryPaths } = require('./common/driverFinder')

const OPTIONS_CAPABILITY_KEY = 'se:ieOptions'
const IE_DRIVER_EXE_ENV_VAR = 'SE_IEDRIVER'
const SCROLL_BEHAVIOUR = {
BOTTOM: 1,
TOP: 0,
Expand Down Expand Up @@ -422,10 +423,11 @@ function createServiceFromCapabilities(capabilities) {
class ServiceBuilder extends remote.DriverService.Builder {
/**
* @param {string=} opt_exe Path to the server executable to use. If omitted,
* the builder will attempt to locate the IEDriverServer on the system PATH.
* the builder will attempt to use the IEDriverServer path from the
* SE_IEDRIVER environment variable, then locate the IEDriverServer on the system PATH.
*/
constructor(opt_exe) {
super(opt_exe)
super(opt_exe || process.env[IE_DRIVER_EXE_ENV_VAR])
this.setLoopback(true) // Required.
}
}
Expand Down
11 changes: 9 additions & 2 deletions javascript/selenium-webdriver/safari.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ const webdriver = require('./lib/webdriver')
const { Browser, Capabilities } = require('./lib/capabilities')
const { getBinaryPaths } = require('./common/driverFinder')

/**
* Environment variable that defines the location of the SafariDriver executable.
* @const {string}
*/
const SAFARI_DRIVER_EXE_ENV_VAR = 'SE_SAFARIDRIVER'

/**
* Creates {@link remote.DriverService} instances that manage
* a [safaridriver] server in a child process.
Expand All @@ -38,10 +44,11 @@ const { getBinaryPaths } = require('./common/driverFinder')
class ServiceBuilder extends remote.DriverService.Builder {
/**
* @param {string=} opt_exe Path to the server executable to use. If omitted,
* the builder will attempt to locate the safaridriver on the system PATH.
* the builder will attempt to use the safaridriver path from the
* SE_SAFARIDRIVER environment variable, then locate the safaridriver on the system PATH.
*/
constructor(opt_exe) {
super(opt_exe)
super(opt_exe || process.env[SAFARI_DRIVER_EXE_ENV_VAR])
this.setLoopback(true) // Required.
}
}
Expand Down
45 changes: 45 additions & 0 deletions javascript/selenium-webdriver/test/chrome/service_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,51 @@ test.suite(
assert.ok(url.endsWith('/foo/bar/baz'), 'unexpected url: ' + url)
})
})

describe('environment variable support', function () {
let originalEnvValue

beforeEach(function () {
originalEnvValue = process.env.SE_CHROMEDRIVER
})

afterEach(function () {
if (originalEnvValue) {
process.env.SE_CHROMEDRIVER = originalEnvValue
} else {
delete process.env.SE_CHROMEDRIVER
}
})

it('uses SE_CHROMEDRIVER environment variable when set', function () {
const testPath = '/custom/path/to/chromedriver'
process.env.SE_CHROMEDRIVER = testPath

const serviceBuilder = new chrome.ServiceBuilder()
const service = serviceBuilder.build()
assert.strictEqual(service.getExecutable(), testPath)
})

it('explicit path overrides environment variable', function () {
const envPath = '/env/path/to/chromedriver'
const explicitPath = '/explicit/path/to/chromedriver'

process.env.SE_CHROMEDRIVER = envPath
const serviceBuilder = new chrome.ServiceBuilder(explicitPath)
const service = serviceBuilder.build()

assert.strictEqual(service.getExecutable(), explicitPath)
})

it('falls back to default behavior when environment variable is not set', function () {
delete process.env.SE_CHROMEDRIVER

const serviceBuilder = new chrome.ServiceBuilder()
const service = serviceBuilder.build()
// Should be null/undefined when no explicit path and no env var
assert.ok(!service.getExecutable())
})
})
})
},
{ browsers: ['chrome'] },
Expand Down
45 changes: 45 additions & 0 deletions javascript/selenium-webdriver/test/edge/service_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,51 @@ test.suite(
let url = await service.start()
assert(/127\.0\.0\.1/.test(url), `unexpected url: ${url}`)
})

describe('environment variable support', function () {
let originalEnvValue

beforeEach(function () {
originalEnvValue = process.env.SE_EDGEDRIVER
})

afterEach(function () {
if (originalEnvValue) {
process.env.SE_EDGEDRIVER = originalEnvValue
} else {
delete process.env.SE_EDGEDRIVER
}
})

it('uses SE_EDGEDRIVER environment variable when set', function () {
const testPath = '/custom/path/to/edgedriver'
process.env.SE_EDGEDRIVER = testPath

const serviceBuilder = new edge.ServiceBuilder()
const service = serviceBuilder.build()
assert.strictEqual(service.getExecutable(), testPath)
})

it('explicit path overrides environment variable', function () {
const envPath = '/env/path/to/edgedriver'
const explicitPath = '/explicit/path/to/edgedriver'

process.env.SE_EDGEDRIVER = envPath
const serviceBuilder = new edge.ServiceBuilder(explicitPath)
const service = serviceBuilder.build()

assert.strictEqual(service.getExecutable(), explicitPath)
})

it('falls back to default behavior when environment variable is not set', function () {
delete process.env.SE_EDGEDRIVER

const serviceBuilder = new edge.ServiceBuilder()
const service = serviceBuilder.build()
// Should be null/undefined when no explicit path and no env var
assert.ok(!service.getExecutable())
})
})
})
},
{ browsers: ['MicrosoftEdge'] },
Expand Down
90 changes: 90 additions & 0 deletions javascript/selenium-webdriver/test/firefox/service_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

'use strict'

const assert = require('node:assert')
const firefox = require('selenium-webdriver/firefox')
const test = require('../../lib/test')
const { getBinaryPaths } = require('selenium-webdriver/common/driverFinder')

test.suite(
function (_env) {
describe('geckodriver', function () {
let service

afterEach(function () {
if (service) {
return service.kill()
}
})

it('can start geckodriver', async function () {
service = new firefox.ServiceBuilder().build()
service.setExecutable(getBinaryPaths(new firefox.Options()).driverPath)
let url = await service.start()
assert(/127\.0\.0\.1/.test(url), `unexpected url: ${url}`)
})

describe('environment variable support', function () {
let originalEnvValue

beforeEach(function () {
originalEnvValue = process.env.SE_GECKODRIVER
})

afterEach(function () {
if (originalEnvValue) {
process.env.SE_GECKODRIVER = originalEnvValue
} else {
delete process.env.SE_GECKODRIVER
}
})

it('uses SE_GECKODRIVER environment variable when set', function () {
const testPath = '/custom/path/to/geckodriver'
process.env.SE_GECKODRIVER = testPath

const serviceBuilder = new firefox.ServiceBuilder()
const service = serviceBuilder.build()
assert.strictEqual(service.getExecutable(), testPath)
})

it('explicit path overrides environment variable', function () {
const envPath = '/env/path/to/geckodriver'
const explicitPath = '/explicit/path/to/geckodriver'

process.env.SE_GECKODRIVER = envPath
const serviceBuilder = new firefox.ServiceBuilder(explicitPath)
const service = serviceBuilder.build()

assert.strictEqual(service.getExecutable(), explicitPath)
})

it('falls back to default behavior when environment variable is not set', function () {
delete process.env.SE_GECKODRIVER

const serviceBuilder = new firefox.ServiceBuilder()
const service = serviceBuilder.build()
// Should be null/undefined when no explicit path and no env var
assert.ok(!service.getExecutable())
})
})
})
},
{ browsers: ['firefox'] },
)
Loading
Loading