51 lines
1.4 KiB
JavaScript
51 lines
1.4 KiB
JavaScript
import { execFileSync } from "node:child_process";
|
|
import { Builder } from "selenium-webdriver";
|
|
import firefox from "selenium-webdriver/firefox.js";
|
|
|
|
/**
|
|
* Resolve the geckodriver path from $PATH.
|
|
*
|
|
* @returns {string}
|
|
*/
|
|
function findGeckodriver() {
|
|
try {
|
|
return execFileSync("which", ["geckodriver"], { encoding: "utf-8" }).trim();
|
|
} catch {
|
|
throw new Error(
|
|
"geckodriver not found on $PATH. Install it (e.g. via Nix or your package manager).",
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create a Firefox WebDriver instance.
|
|
*
|
|
* @param {object} opts
|
|
* @param {boolean} [opts.headless=false] - Run Firefox in headless mode.
|
|
* @param {string} [opts.existingUrl] - Connect to an already-running
|
|
* WebDriver server (e.g. "http://localhost:4444").
|
|
* @returns {Promise<import("selenium-webdriver").WebDriver>}
|
|
*/
|
|
export async function createDriver({ headless = false, existingUrl } = {}) {
|
|
const options = new firefox.Options();
|
|
|
|
// Configure Headless
|
|
if (headless) {
|
|
options.addArguments("--headless");
|
|
}
|
|
|
|
const builder = new Builder().forBrowser("firefox").setFirefoxOptions(options);
|
|
|
|
// Connect to Existing Server
|
|
if (existingUrl) {
|
|
builder.usingServer(existingUrl);
|
|
} else {
|
|
// Use System Geckodriver - Bypasses the bundled selenium-manager which
|
|
// is x86-64 only and doesn't work on aarch64.
|
|
const service = new firefox.ServiceBuilder(findGeckodriver());
|
|
builder.setFirefoxService(service);
|
|
}
|
|
|
|
return builder.build();
|
|
}
|