commit dfe3a3c9d10fd4f60c2c6b4ccbbbee5c44cfe928
parent 16d14cc2f21a6ec65bd9729fe275ea6629458e61
Author: Florian Dold <florian@dold.me>
Date: Mon, 17 Aug 2026 16:28:46 +0200
harness: lazy-load selenium
Diffstat:
2 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/packages/taler-harness/src/harness/environments.ts b/packages/taler-harness/src/harness/environments.ts
@@ -97,12 +97,30 @@ import {
} from "./harness.js";
import * as fs from "node:fs";
-import { Browser, Builder, ThenableWebDriver } from "selenium-webdriver";
-import * as Chrome from "selenium-webdriver/chrome.js";
-import * as Firefox from "selenium-webdriver/firefox.js";
+import type { ThenableWebDriver } from "selenium-webdriver";
const logger = new Logger("helpers.ts");
+function seleniumLoadError(error: unknown): Error {
+ return new Error(
+ "Unable to load selenium-webdriver. Browser integration tests require " +
+ "this module. From the taler-typescript-core checkout, run " +
+ "`pnpm install --filter @gnu-taler/taler-harness...` and rebuild the " +
+ "harness. For a standalone installation, run " +
+ "`npm install selenium-webdriver@4.40.0` in the harness Node.js " +
+ "installation directory",
+ { cause: error },
+ );
+}
+
+export async function loadSelenium() {
+ try {
+ return await import("selenium-webdriver");
+ } catch (e) {
+ throw seleniumLoadError(e);
+ }
+}
+
/**
* @deprecated
*/
@@ -321,11 +339,22 @@ export function createBrowser(t: GlobalTestState) {
: undefined;
const type = browserType ?? defaultBrowser ?? "chrome";
+ // Keep Selenium out of the startup path for integration tests that don't
+ // use a browser. The harness bundle externalizes this dependency because
+ // Selenium locates browser-related files relative to its package.
+ const { Browser, Builder } = await loadSelenium();
+
const b = new BrowserService(t, type);
await b.start();
switch (type) {
case "firefox": {
+ let Firefox;
+ try {
+ Firefox = await import("selenium-webdriver/firefox.js");
+ } catch (e) {
+ throw seleniumLoadError(e);
+ }
const firefoxOpts = new Firefox.Options();
firefoxOpts.addArguments("--headless");
if (process.env.BROWSER_BINARY) {
@@ -339,6 +368,12 @@ export function createBrowser(t: GlobalTestState) {
}
case "chrome": {
+ let Chrome;
+ try {
+ Chrome = await import("selenium-webdriver/chrome.js");
+ } catch (e) {
+ throw seleniumLoadError(e);
+ }
const chromeOpts = new Chrome.Options();
// https://peter.sh/experiments/chromium-command-line-switches
chromeOpts.addArguments("--no-sandbox", "-headless");
diff --git a/packages/taler-harness/src/integrationtests/test-web-merchant-login.ts b/packages/taler-harness/src/integrationtests/test-web-merchant-login.ts
@@ -17,14 +17,18 @@
/**
* Imports.
*/
-import { By } from "selenium-webdriver";
-import { createSimpleTestkudosEnvironmentV3 } from "../harness/environments.js";
+import {
+ createSimpleTestkudosEnvironmentV3,
+ loadSelenium,
+} from "../harness/environments.js";
import { GlobalTestState, MERCHANT_DEFAULT_AUTH } from "../harness/harness.js";
/**
* Do basic checks on instance management and authentication.
*/
export async function runWebMerchantLoginTest(t: GlobalTestState) {
+ const { By } = await loadSelenium();
+
// Set up test environment
const { merchant, createBrowser } =