commit ece7aabb541a58ed74b7579393572af67ef8b40c
parent d83315f0c1bdaf2048921dea936151a5330b7115
Author: Florian Dold <dold@taler.net>
Date: Wed, 1 Jul 2026 22:48:22 +0200
make sure all tests run, delete two legacy/umaintained test files
Diffstat:
17 files changed, 23 insertions(+), 515 deletions(-)
diff --git a/package.json b/package.json
@@ -8,7 +8,8 @@
"lint": "pnpm --filter @gnu-taler/qa-tooling install && ./packages/qa-tooling/bin/eslint.mjs .",
"i18n:source2po": "pnpm run --filter '@gnu-taler/*' i18n:source2po",
"i18n:po2strings": "pnpm run --filter '@gnu-taler/*' i18n:po2strings",
- "check": "pnpm run --filter '@gnu-taler/*' --if-present --sequential test"
+ "check": "pnpm run --filter '@gnu-taler/*' --if-present --sequential --no-bail test",
+ "test": "pnpm run --filter '@gnu-taler/*' --if-present --sequential --no-bail test"
},
"devDependencies": {
"esbuild": "^0.28.0",
diff --git a/packages/anastasis-core/package.json b/packages/anastasis-core/package.json
@@ -8,8 +8,8 @@
"scripts": {
"compile": "tsc",
"pretty": "prettier --write src",
- "test": "tsc && node --test lib/*.test.js lib/**/*.test.js",
- "coverage": "tsc && c8 --src src --all node --test lib/*.test.js lib/**/*.test.js",
+ "test": "tsc && node --test 'lib/*.test.js' 'lib/**/*.test.js'",
+ "coverage": "tsc && c8 --src src --all node --test 'lib/*.test.js' 'lib/**/*.test.js'",
"typedoc": "pnpm dlx typedoc --out dist/typedoc ./src/",
"clean": "rm -rf dist lib tsconfig.tsbuildinfo"
},
diff --git a/packages/anastasis-webui/test.mjs b/packages/anastasis-webui/test.mjs
@@ -17,7 +17,7 @@
import { build } from "@gnu-taler/web-util/build";
import { getFilesInDirectory } from "@gnu-taler/web-util/build";
-const allTestFiles = getFilesInDirectory("src", /\\.test\\.tsx?$/);
+const allTestFiles = getFilesInDirectory("src", /\.test\.tsx?$/);
await build({
type: "test",
diff --git a/packages/challenger-webui/test.mjs b/packages/challenger-webui/test.mjs
@@ -18,7 +18,7 @@
import { build } from "@gnu-taler/web-util/build";
import { getFilesInDirectory } from "@gnu-taler/web-util/build";
-const allTestFiles = getFilesInDirectory("src", /\\.test\\.tsx?$/);
+const allTestFiles = getFilesInDirectory("src", /\.test\.tsx?$/);
await build({
type: "test",
diff --git a/packages/idb-bridge/package.json b/packages/idb-bridge/package.json
@@ -10,7 +10,7 @@
"license": "AGPL-3.0-or-later",
"private": false,
"scripts": {
- "test": "tsc && node --test lib/*.test.js lib/**/*.test.js",
+ "test": "tsc && node --test 'lib/*.test.js' 'lib/**/*.test.js'",
"typedoc": "pnpm dlx typedoc --out dist/typedoc ./src/",
"compile": "tsc",
"clean": "rm -rf dist lib tsconfig.tsbuildinfo",
diff --git a/packages/libeufin-bank-webui/test.mjs b/packages/libeufin-bank-webui/test.mjs
@@ -18,7 +18,7 @@
import { build } from "@gnu-taler/web-util/build";
import { getFilesInDirectory } from "@gnu-taler/web-util/build";
-const allTestFiles = getFilesInDirectory("src", /\\.test\\.tsx?$/);
+const allTestFiles = getFilesInDirectory("src", /\.test\.tsx?$/);
await build({
type: "test",
diff --git a/packages/pogen/package.json b/packages/pogen/package.json
@@ -8,7 +8,7 @@
"license": "GPL-2.0+",
"scripts": {
"clean": "rm -rf lib",
- "test": "tsc && node --test lib/*.test.js lib/**/*.test.js",
+ "test": "tsc && node --test 'lib/*.test.js' 'lib/**/*.test.js'",
"compile": "tsc"
},
"type": "module",
diff --git a/packages/taler-auditor-webui/test.mjs b/packages/taler-auditor-webui/test.mjs
@@ -18,7 +18,7 @@
import { build } from "@gnu-taler/web-util/build";
import { getFilesInDirectory } from "@gnu-taler/web-util/build";
-const allTestFiles = getFilesInDirectory("src", /\\.test\\.tsx?$/);
+const allTestFiles = getFilesInDirectory("src", /\.test\.tsx?$/);
await build({
type: "test",
diff --git a/packages/taler-exchange-aml-webui/test.mjs b/packages/taler-exchange-aml-webui/test.mjs
@@ -18,7 +18,7 @@
import { build } from "@gnu-taler/web-util/build";
import { getFilesInDirectory } from "@gnu-taler/web-util/build";
-const allTestFiles = getFilesInDirectory("./src", /\\.test\\.tsx?$/);
+const allTestFiles = getFilesInDirectory("./src", /\.test\.tsx?$/);
await build({
type: "test",
diff --git a/packages/taler-exchange-kyc-webui/test.mjs b/packages/taler-exchange-kyc-webui/test.mjs
@@ -18,7 +18,7 @@
import { build } from "@gnu-taler/web-util/build";
import { getFilesInDirectory } from "@gnu-taler/web-util/build";
-const allTestFiles = getFilesInDirectory("src", /\\.test\\.tsx?$/);
+const allTestFiles = getFilesInDirectory("src", /\.test\.tsx?$/);
await build({
type: "test",
diff --git a/packages/taler-merchant-webui/test.mjs b/packages/taler-merchant-webui/test.mjs
@@ -18,7 +18,7 @@
import { build } from "@gnu-taler/web-util/build";
import { getFilesInDirectory } from "@gnu-taler/web-util/build";
-const allTestFiles = getFilesInDirectory("src", /\\.test\\.tsx?$/);
+const allTestFiles = getFilesInDirectory("src", /\.test\.tsx?$/);
await build({
type: "test",
diff --git a/packages/taler-util/package.json b/packages/taler-util/package.json
@@ -62,8 +62,8 @@
},
"scripts": {
"compile": "tsc",
- "test": "tsc && node --test lib/*.test.js lib/**/*.test.js",
- "coverage": "tsc && c8 --src src --all node --test lib/*.test.js lib/**/*.test.js",
+ "test": "tsc && node --test 'lib/*.test.js' 'lib/**/*.test.js'",
+ "coverage": "tsc && c8 --src src --all node --test 'lib/*.test.js' 'lib/**/*.test.js'",
"clean": "rm -rf dist lib tsconfig.tsbuildinfo",
"typedoc": "pnpm dlx typedoc --out dist/typedoc ./src/",
"pretty": "prettier --write src"
diff --git a/packages/taler-wallet-core/package.json b/packages/taler-wallet-core/package.json
@@ -14,10 +14,10 @@
"scripts": {
"compile": "tsc",
"pretty": "prettier --write src",
- "test": "tsc && node --test lib/*.test.js lib/**/*.test.js",
+ "test": "tsc && node --test 'lib/*.test.js' 'lib/**/*.test.js'",
"typedoc": "pnpm dlx typedoc --out dist/typedoc ./src/",
- "coverage": "tsc && c8 --src src --all node --test lib/*.test.js lib/**/*.test.js",
- "coverage:html": "tsc && c8 -r html --src src --all node --test lib/*.test.js lib/**/*.test.js",
+ "coverage": "tsc && c8 --src src --all node --test 'lib/*.test.js' 'lib/**/*.test.js'",
+ "coverage:html": "tsc && c8 -r html --src src --all node --test 'lib/*.test.js' 'lib/**/*.test.js'",
"clean": "rm -rf dist lib tsconfig.tsbuildinfo"
},
"files": [
diff --git a/packages/taler-wallet-webextension/src/cta/Payment/Payment.test.ts b/packages/taler-wallet-webextension/src/cta/Payment/Payment.test.ts
@@ -1,430 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 Taler Systems S.A.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { describe, it, after } from "node:test";
-
-import {
- Amounts,
- ConfirmPayResult,
- ConfirmPayResultType,
- Duration,
- MerchantContractTermsV0,
- NotificationType,
- PreparePayResultInsufficientBalance,
- PreparePayResultPaymentPossible,
- PreparePayResultType,
-} from "@gnu-taler/taler-util";
-import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
-import * as tests from "@gnu-taler/web-util/testing";
-import { expect } from "chai";
-import { nullFunction } from "../../mui/handlers.js";
-import { createWalletApiMock } from "../../test-utils.js";
-import { useComponentStateFromUri as useComponentState } from "./state.js";
-
-describe("Payment CTA states", () => {
- it("should tell the user that the URI is missing", async () => {
- const { handler, TestingContext } = createWalletApiMock();
- const props = {
- talerPayUri: "",
- cancel: nullFunction,
- goToWalletManualWithdraw: nullFunction,
- onSuccess: nullFunction,
- };
-
- const hookBehavior = await tests.hookBehaveLikeThis(
- useComponentState,
- props,
- [
- ({ status, error }) => {
- expect(status).equals("loading");
- expect(error).undefined;
- },
- ({ status, error }) => {
- expect(status).equals("error");
- if (error === undefined) expect.fail();
- },
- ],
- TestingContext,
- );
-
- expect(hookBehavior).deep.equal({ result: "ok" });
- expect(handler.getCallingQueueState()).eq("empty");
- });
-
- it("should response with no balance", async () => {
- const { handler, TestingContext } = createWalletApiMock();
- const props = {
- talerPayUri: "taller://pay",
- cancel: nullFunction,
- goToWalletManualWithdraw: nullFunction,
- onSuccess: nullFunction,
- };
-
- handler.addWalletCallResponse(
- WalletApiOperation.PreparePayForUri,
- undefined,
- {
- status: PreparePayResultType.InsufficientBalance,
- amountRaw: "USD:10",
- contractTerms: {
- pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()),
- } as unknown as MerchantContractTermsV0,
- } as PreparePayResultInsufficientBalance,
- );
-
- const hookBehavior = await tests.hookBehaveLikeThis(
- useComponentState,
- props,
- [
- ({ status, error }) => {
- expect(status).equals("loading");
- expect(error).undefined;
- },
- (state) => {
- if (state.status !== "no-enough-balance") {
- expect(state).eq({});
- return;
- }
- // expect(state.balance).undefined;
- expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:10"));
- },
- ],
- TestingContext,
- );
-
- expect(hookBehavior).deep.equal({ result: "ok" });
- expect(handler.getCallingQueueState()).eq("empty");
- });
-
- it("should not be able to pay if there is no enough balance", async () => {
- const { handler, TestingContext } = createWalletApiMock();
- const props = {
- talerPayUri: "taller://pay",
- cancel: nullFunction,
- goToWalletManualWithdraw: nullFunction,
- onSuccess: nullFunction,
- };
-
- handler.addWalletCallResponse(
- WalletApiOperation.PreparePayForUri,
- undefined,
- {
- status: PreparePayResultType.InsufficientBalance,
- amountRaw: "USD:10",
- contractTerms: {
- pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()),
- } as unknown as MerchantContractTermsV0,
- } as PreparePayResultInsufficientBalance,
- );
-
- const hookBehavior = await tests.hookBehaveLikeThis(
- useComponentState,
- props,
- [
- ({ status, error }) => {
- expect(status).equals("loading");
- expect(error).undefined;
- },
- (state) => {
- if (state.status !== "no-enough-balance") expect.fail();
- // expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:5"));
- expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:10"));
- },
- ],
- TestingContext,
- );
-
- expect(hookBehavior).deep.equal({ result: "ok" });
- expect(handler.getCallingQueueState()).eq("empty");
- });
-
- it("should be able to pay (without fee)", async () => {
- const { handler, TestingContext } = createWalletApiMock();
- const props = {
- talerPayUri: "taller://pay",
- cancel: nullFunction,
- goToWalletManualWithdraw: nullFunction,
- onSuccess: nullFunction,
- };
-
- handler.addWalletCallResponse(
- WalletApiOperation.PreparePayForUri,
- undefined,
- {
- status: PreparePayResultType.PaymentPossible,
- amountRaw: "USD:10",
- amountEffective: "USD:10",
- contractTerms: {
- pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()),
- } as unknown as MerchantContractTermsV0,
- } as PreparePayResultPaymentPossible,
- );
-
- const hookBehavior = await tests.hookBehaveLikeThis(
- useComponentState,
- props,
- [
- ({ status, error }) => {
- expect(status).equals("loading");
- expect(error).undefined;
- },
- (state) => {
- if (state.status !== "ready") {
- expect(state).eq({});
- return;
- }
- // expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
- expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:10"));
- expect(state.payHandler.onClick).not.undefined;
- },
- ],
- TestingContext,
- );
-
- expect(hookBehavior).deep.equal({ result: "ok" });
- expect(handler.getCallingQueueState()).eq("empty");
- });
-
- it("should be able to pay (with fee)", async () => {
- const { handler, TestingContext } = createWalletApiMock();
- const props = {
- talerPayUri: "taller://pay",
- cancel: nullFunction,
- goToWalletManualWithdraw: nullFunction,
- onSuccess: nullFunction,
- };
-
- handler.addWalletCallResponse(
- WalletApiOperation.PreparePayForUri,
- undefined,
- {
- status: PreparePayResultType.PaymentPossible,
- amountRaw: "USD:9",
- amountEffective: "USD:10",
- contractTerms: {
- pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()),
- } as unknown as MerchantContractTermsV0,
- } as PreparePayResultPaymentPossible,
- );
-
- const hookBehavior = await tests.hookBehaveLikeThis(
- useComponentState,
- props,
- [
- ({ status, error }) => {
- expect(status).equals("loading");
- expect(error).undefined;
- },
- (state) => {
- if (state.status !== "ready") expect.fail();
- // expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
- expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
- expect(state.payHandler.onClick).not.undefined;
- },
- ],
- TestingContext,
- );
-
- expect(hookBehavior).deep.equal({ result: "ok" });
- expect(handler.getCallingQueueState()).eq("empty");
- });
-
- it("should get confirmation done after pay successfully", async () => {
- const { handler, TestingContext } = createWalletApiMock();
- const props = {
- talerPayUri: "taller://pay",
- cancel: nullFunction,
- goToWalletManualWithdraw: nullFunction,
- onSuccess: nullFunction,
- };
-
- handler.addWalletCallResponse(
- WalletApiOperation.PreparePayForUri,
- undefined,
- {
- status: PreparePayResultType.PaymentPossible,
- amountRaw: "USD:9",
- amountEffective: "USD:10",
- contractTerms: {
- pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()),
- } as unknown as MerchantContractTermsV0,
- } as PreparePayResultPaymentPossible,
- );
-
- handler.addWalletCallResponse(WalletApiOperation.ConfirmPay, undefined, {
- type: ConfirmPayResultType.Done,
- contractTerms: {},
- } as ConfirmPayResult);
-
- const hookBehavior = await tests.hookBehaveLikeThis(
- useComponentState,
- props,
- [
- ({ status, error }) => {
- expect(status).equals("loading");
- expect(error).undefined;
- },
- (state) => {
- if (state.status !== "ready") {
- expect(state).eq({});
- return;
- }
- // expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
- expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
- if (state.payHandler.onClick === undefined) expect.fail();
- state.payHandler.onClick();
- },
- ],
- TestingContext,
- );
-
- expect(hookBehavior).deep.equal({ result: "ok" });
- expect(handler.getCallingQueueState()).eq("empty");
- });
-
- it("should not stay in ready state after pay with error", async () => {
- const { handler, TestingContext } = createWalletApiMock();
- const props = {
- talerPayUri: "taller://pay",
- cancel: nullFunction,
- goToWalletManualWithdraw: nullFunction,
- onSuccess: nullFunction,
- };
- handler.addWalletCallResponse(
- WalletApiOperation.PreparePayForUri,
- undefined,
- {
- status: PreparePayResultType.PaymentPossible,
- amountRaw: "USD:9",
- amountEffective: "USD:10",
- contractTerms: {
- pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()),
- } as unknown as MerchantContractTermsV0,
- } as PreparePayResultPaymentPossible,
- );
-
- handler.addWalletCallResponse(WalletApiOperation.ConfirmPay, undefined, {
- type: ConfirmPayResultType.Pending,
- lastError: { code: 1 },
- } as ConfirmPayResult);
-
- // const hookBehavior = await tests.hookBehaveLikeThis(
- // () => {
- // const state = useComponentState(props);
- // // const { alerts } = useAlertContext();
- // return { ...state, alerts: {} };
- // },
- // {},
- // [
- // ({ status, error }) => {
- // expect(status).equals("loading");
- // expect(error).undefined;
- // },
- // (state) => {
- // if (state.status !== "ready") expect.fail();
- // // expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
- // expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
- // // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1"));
- // if (state.payHandler.onClick === undefined) expect.fail();
- // state.payHandler.onClick();
- // },
- // ],
- // TestingContext,
- // );
-
- // expect(hookBehavior).deep.equal({ result: "ok" });
- expect(handler.getCallingQueueState()).eq("empty");
- });
-
- it("should update balance if a coins is withdraw", async () => {
- const { handler, TestingContext } = createWalletApiMock();
-
- const props = {
- talerPayUri: "taller://pay",
- cancel: nullFunction,
- goToWalletManualWithdraw: nullFunction,
- onSuccess: nullFunction,
- };
-
- handler.addWalletCallResponse(
- WalletApiOperation.PreparePayForUri,
- undefined,
- {
- status: PreparePayResultType.PaymentPossible,
- amountRaw: "USD:9",
- amountEffective: "USD:10",
- contractTerms: {
- pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()),
- } as unknown as MerchantContractTermsV0,
- } as PreparePayResultPaymentPossible,
- );
-
- handler.addWalletCallResponse(
- WalletApiOperation.PreparePayForUri,
- undefined,
- {
- status: PreparePayResultType.PaymentPossible,
- amountRaw: "USD:9",
- amountEffective: "USD:10",
- contractTerms: {
- pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()),
- } as unknown as MerchantContractTermsV0,
- } as PreparePayResultPaymentPossible,
- );
-
- const hookBehavior = await tests.hookBehaveLikeThis(
- useComponentState,
- props,
- [
- ({ status, error }) => {
- expect(status).equals("loading");
- expect(error).undefined;
- },
- (state) => {
- if (state.status !== "ready") expect.fail();
- // expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:10"));
- expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
- // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1"));
- expect(state.payHandler.onClick).not.undefined;
-
- handler.notifyEventFromWallet({
- type: NotificationType.TransactionStateTransition,
- newTxState: {} as any,
- oldTxState: {} as any,
- transactionId: "123",
- newStId: 1,
- });
- },
- (state) => {
- if (state.status !== "ready") expect.fail();
- // expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
- expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
- // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1"));
- expect(state.payHandler.onClick).not.undefined;
- },
- ],
- TestingContext,
- );
-
- expect(hookBehavior).deep.equal({ result: "ok" });
- expect(handler.getCallingQueueState()).eq("empty");
- });
-});
diff --git a/packages/taler-wallet-webextension/src/stories.test.ts b/packages/taler-wallet-webextension/src/stories.test.ts
@@ -1,67 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 Taler Systems S.A.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { describe, it } from "node:test";
-import { setupI18n } from "@gnu-taler/taler-util";
-import { parseGroupImport } from "@gnu-taler/web-util/browser";
-import * as tests from "@gnu-taler/web-util/testing";
-import chromeAPI from "./platform/chrome.js";
-import { setupPlatform } from "./platform/foreground.js";
-
-import * as components from "./components/index.stories.js";
-import * as cta from "./cta/index.stories.js";
-import * as mui from "./mui/index.stories.js";
-import * as popup from "./popup/index.stories.js";
-import * as wallet from "./wallet/index.stories.js";
-// import { renderNodeOrBrowser } from "./test-utils.js";
-import { h, VNode, ComponentChildren } from "preact";
-import { AlertProvider } from "./context/alert.js";
-
-setupI18n("en", { en: {} });
-setupPlatform(chromeAPI);
-
-describe("All the examples:", () => {
- const cms = parseGroupImport({ popup, wallet, cta, mui, components });
- cms.forEach((group) => {
- describe(`Example for group "${group.title}:"`, () => {
- group.list.forEach((component) => {
- describe(`Component ${component.name}:`, () => {
- component.examples.forEach((example) => {
- it(`should render example: ${example.name}`, () => {
- tests.renderUI(example.render, DefaultTestingContext);
- });
- });
- });
- });
- });
- });
-});
-function DefaultTestingContext({
- children,
-}: {
- children: ComponentChildren;
-}): VNode {
- //FIXME:
- //some components push the alter in the UI function
- //that's not correct, should be moved into the state function
- // until then, we ran the tests with the alert provider
- return h(AlertProvider, { children });
-}
diff --git a/packages/taler-wallet-webextension/test.mjs b/packages/taler-wallet-webextension/test.mjs
@@ -17,7 +17,7 @@
import { build, getFilesInDirectory } from "@gnu-taler/web-util/build";
-const allTestFiles = getFilesInDirectory("src", /\\.test\\.tsx?$/);
+const allTestFiles = getFilesInDirectory("src", /\.test\.tsx?$/);
await build({
type: "test",
diff --git a/packages/web-util/src/index.build.ts b/packages/web-util/src/index.build.ts
@@ -268,6 +268,10 @@ export function computeConfig(params: BuildParams): {
__VERSION__: `"${version}"`,
__GIT_HASH__: `"${GIT_HASH}"`,
},
+ // Test files import node: built-in modules (e.g. node:test, node:assert)
+ // which can't be resolved with platform:"browser". Mark them as external
+ // so they are resolved by Node.js at runtime.
+ ...(params.type === "test" ? { external: ["node:*"] } : {}),
plugins,
};