Skip to content

Commit

Permalink
feat: support spawnOpts for geckodriver child process (#552)
Browse files Browse the repository at this point in the history
* feat: support spawnOpts for geckodriver child process

* add documentation on new spawnOpts parameter

* correctly reflect spawnOptions argument

* update readme docs with correct spawnOpts type
  • Loading branch information
AtofStryker authored Sep 27, 2024
1 parent 2b429a4 commit 3edaf8e
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 2 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,15 @@ The path to the root of the cache directory.
Type: `string`<br />
Default: `process.env.GECKODRIVER_CACHE_DIR || os.tmpdir()`

### `spawnOpts`
Options to pass into the geckodriver process. This can be useful if needing
Firefox to spawn with `MOZ_` prefix variables, such as `MOZ_HEADLESS_WIDTH`.
See https://nodejs.org/api/child_process.html#child_processspawncommand-args-options for
all options.

Type: `SpawnOptionsWithoutStdio | SpawnOptionsWithStdioTuple`<br />
Default: `undefined`

# Other Browser Driver

If you also look for other browser driver NPM wrappers, you can find them here:
Expand Down
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { GeckodriverParameters } from './types.js'
const log = logger('geckodriver')

export async function start (params: GeckodriverParameters) {
const { cacheDir, customGeckoDriverPath, ...startArgs } = params
const { cacheDir, customGeckoDriverPath, spawnOpts, ...startArgs } = params
let geckoDriverPath = (
customGeckoDriverPath ||
process.env.GECKODRIVER_PATH ||
Expand Down Expand Up @@ -42,7 +42,7 @@ export async function start (params: GeckodriverParameters) {

const args = parseParams(startArgs)
log.info(`Starting Geckodriver at ${geckoDriverPath} with params: ${args.join(' ')}`)
return cp.spawn(geckoDriverPath, args)
return cp.spawn(geckoDriverPath, args, spawnOpts)
}

export const download = downloadDriver
Expand Down
10 changes: 10 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import type { SpawnOptionsWithoutStdio, SpawnOptionsWithStdioTuple, StdioPipe, StdioNull } from 'node:child_process'

export type LogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'config' | 'debug' | 'trace'

type StdioOption = StdioNull | StdioPipe
export interface GeckodriverParameters {
/**
* List of hostnames to allow. By default the value of --host is allowed, and in addition if that's a well
Expand Down Expand Up @@ -77,6 +80,13 @@ export interface GeckodriverParameters {
* @default process.env.GECKODRIVER_CACHE_DIR || os.tmpdir()
*/
cacheDir?: string

/**
* options to be passed into the process.
* @see options in https://nodejs.org/api/child_process.html#child_processspawncommand-args-options
* @default undefined
*/
spawnOpts?: SpawnOptionsWithoutStdio | SpawnOptionsWithStdioTuple<StdioOption, StdioOption, StdioOption>
}

declare global {
Expand Down
41 changes: 41 additions & 0 deletions tests/start-unit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

import cp from 'node:child_process'
import { vi, test, expect } from 'vitest'
import { type GeckodriverParameters, start } from '../src/index.ts'

test('start', async () => {
vi.mock('../src/install.js', () => {
return {
download: vi.fn().mockResolvedValue('foo')
}
})

vi.mock('../src/utils.js', async (original) => {
const actual: any = await original()
return {
hasAccess: vi.fn().mockResolvedValue(true),
parseParams: actual.parseParams
}
})

vi.mock('node:child_process', () => ({
default: {
spawn: vi.fn(),
}
}))

const args: GeckodriverParameters = {
spawnOpts: {
env: {
MOZ_HEADLESS_WIDTH: '720'
}
}
}

await start(args)
expect(cp.spawn).toHaveBeenCalledWith('foo', ['--host=0.0.0.0', '--websocket-port=0'], {
env: {
MOZ_HEADLESS_WIDTH: '720'
}
})
})

0 comments on commit 3edaf8e

Please sign in to comment.