gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated (a10f9650 -> a5681579)


From: gnunet
Subject: [taler-wallet-core] branch master updated (a10f9650 -> a5681579)
Date: Tue, 12 Jan 2021 20:04:22 +0100

This is an automated email from the git hooks/post-receive script.

dold pushed a change to branch master
in repository wallet-core.

    from a10f9650 integration test: drop less responses
     new 6772c547 backup WIP
     new a5681579 make integration tests part of taler-wallet-cli

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 packages/taler-integrationtests/package.json       |  25 ---
 packages/taler-integrationtests/scenario           |  26 ---
 .../src/scenario-rerun-payment-multiple.ts         | 128 ---------------
 packages/taler-integrationtests/testrunner         |  77 ---------
 packages/taler-integrationtests/tsconfig.json      |  32 ----
 packages/taler-wallet-cli/package.json             |   2 +
 packages/taler-wallet-cli/src/index.ts             |  20 +++
 .../src/integrationtests}/denomStructures.ts       |   0
 .../src/integrationtests}/faultInjection.ts        |   0
 .../src/integrationtests}/harness.ts               | 123 ++++++--------
 .../src/integrationtests}/helpers.ts               |   0
 .../src/integrationtests}/merchantApiTypes.ts      |   0
 .../integrationtests}/scenario-prompt-payment.ts   |   6 +-
 .../src/integrationtests}/test-bank-api.ts         |   5 +-
 .../src/integrationtests}/test-claim-loop.ts       |   6 +-
 .../integrationtests}/test-exchange-management.ts  |   5 +-
 .../src/integrationtests}/test-fee-regression.ts   |   6 +-
 .../integrationtests}/test-merchant-longpolling.ts |   6 +-
 .../integrationtests}/test-merchant-refund-api.ts  |   6 +-
 .../src/integrationtests}/test-pay-abort.ts        |   7 +-
 .../src/integrationtests}/test-pay-paid.ts         |   6 +-
 .../src/integrationtests}/test-payment-claim.ts    |  11 +-
 .../src/integrationtests}/test-payment-fault.ts    |   5 +-
 .../integrationtests}/test-payment-idempotency.ts  |   6 +-
 .../src/integrationtests}/test-payment-multiple.ts |   5 +-
 .../integrationtests}/test-payment-transient.ts    |   6 +-
 .../src/integrationtests}/test-payment.ts          |   6 +-
 .../src/integrationtests}/test-paywall-flow.ts     |   6 +-
 .../src/integrationtests}/test-refund-auto.ts      |   8 +-
 .../src/integrationtests}/test-refund-gone.ts      |   6 +-
 .../integrationtests}/test-refund-incremental.ts   |  11 +-
 .../src/integrationtests}/test-refund.ts           |   6 +-
 .../src/integrationtests}/test-revocation.ts       |   6 +-
 .../test-timetravel-autorefresh.ts                 |   5 +-
 .../integrationtests}/test-timetravel-withdraw.ts  |   6 +-
 .../src/integrationtests}/test-tipping.ts          |   5 +-
 .../src/integrationtests}/test-wallettesting.ts    |   6 +-
 .../test-withdrawal-abort-bank.ts                  |   6 +-
 .../test-withdrawal-bank-integrated.ts             |   6 +-
 .../integrationtests}/test-withdrawal-manual.ts    |   6 +-
 .../src/integrationtests/testrunner.ts             | 176 +++++++++++++++++++++
 .../taler-wallet-core/src/operations/backup.ts     |   4 +
 packages/taler-wallet-core/src/types/dbTypes.ts    |  21 ++-
 pnpm-lock.yaml                                     |  36 +++--
 tsconfig.build.json                                |   5 +-
 45 files changed, 360 insertions(+), 490 deletions(-)
 delete mode 100644 packages/taler-integrationtests/package.json
 delete mode 100755 packages/taler-integrationtests/scenario
 delete mode 100644 
packages/taler-integrationtests/src/scenario-rerun-payment-multiple.ts
 delete mode 100755 packages/taler-integrationtests/testrunner
 delete mode 100644 packages/taler-integrationtests/tsconfig.json
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/denomStructures.ts (100%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/faultInjection.ts (100%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/harness.ts (95%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/helpers.ts (100%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/merchantApiTypes.ts (100%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/scenario-prompt-payment.ts (92%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-bank-api.ts (98%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-claim-loop.ts (97%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-exchange-management.ts (98%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-fee-regression.ts (97%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-merchant-longpolling.ts (96%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-merchant-refund-api.ts (99%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-pay-abort.ts (98%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-pay-paid.ts (97%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-payment-claim.ts (95%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-payment-fault.ts (98%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-payment-idempotency.ts (95%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-payment-multiple.ts (98%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-payment-transient.ts (97%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-payment.ts (92%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-paywall-flow.ts (98%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-refund-auto.ts (93%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-refund-gone.ts (96%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-refund-incremental.ts (97%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-refund.ts (95%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-revocation.ts (97%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-timetravel-autorefresh.ts (98%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-timetravel-withdraw.ts (95%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-tipping.ts (98%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-wallettesting.ts (95%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-withdrawal-abort-bank.ts (92%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-withdrawal-bank-integrated.ts (93%)
 rename packages/{taler-integrationtests/src => 
taler-wallet-cli/src/integrationtests}/test-withdrawal-manual.ts (94%)
 create mode 100644 packages/taler-wallet-cli/src/integrationtests/testrunner.ts

diff --git a/packages/taler-integrationtests/package.json 
b/packages/taler-integrationtests/package.json
deleted file mode 100644
index 7da65b14..00000000
--- a/packages/taler-integrationtests/package.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
-  "name": "taler-integrationtests",
-  "version": "0.0.1",
-  "description": "Integration tests and fault injection for GNU Taler 
components",
-  "main": "index.js",
-  "scripts": {
-    "compile": "tsc -b",
-    "pretty": "prettier --write src"
-  },
-  "author": "Florian Dold <dold@taler.net>",
-  "license": "AGPL-3.0-or-later",
-  "devDependencies": {
-    "esm": "^3.2.25",
-    "nyc": "^15.1.0",
-    "prettier": "^2.1.2",
-    "source-map-support": "^0.5.19",
-    "ts-node": "^9.0.0",
-    "typescript": "^4.0.5"
-  },
-  "dependencies": {
-    "axios": "^0.21.0",
-    "taler-wallet-core": "workspace:*",
-    "tslib": "^2.0.3"
-  }
-}
diff --git a/packages/taler-integrationtests/scenario 
b/packages/taler-integrationtests/scenario
deleted file mode 100755
index 9bef68ff..00000000
--- a/packages/taler-integrationtests/scenario
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env bash
-
-# Simple test runner for the wallet integration tests.
-#
-# Usage: $0 TESTGLOB
-#
-# The TESTGLOB can be used to select which test cases to execute
-
-set -eu
-
-if [ "$#" -ne 1 ]; then
-    echo "Usage: $0 SCENARIO"
-    exit 1
-fi
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
-
-cd $DIR
-
-./node_modules/.bin/tsc -b
-
-export ESM_OPTIONS='{"sourceMap": true}'
-
-file=lib/scenario-$1.js
-
-exec node -r source-map-support/register -r esm $file
diff --git 
a/packages/taler-integrationtests/src/scenario-rerun-payment-multiple.ts 
b/packages/taler-integrationtests/src/scenario-rerun-payment-multiple.ts
deleted file mode 100644
index 3a98987b..00000000
--- a/packages/taler-integrationtests/src/scenario-rerun-payment-multiple.ts
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2020 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/>
- */
-
-/**
- * Imports.
- */
-import {
-  GlobalTestState,
-  BankService,
-  ExchangeService,
-  MerchantService,
-  WalletCli,
-  runTestWithState,
-  MerchantPrivateApi,
-} from "./harness";
-import { withdrawViaBank } from "./helpers";
-import fs from "fs";
-
-let existingTestDir =
-  process.env["TALER_TEST_OLD_DIR"] ?? "/tmp/taler-integrationtest-current";
-
-if (!fs.existsSync(existingTestDir)) {
-  throw Error("old test dir not found");
-}
-
-existingTestDir = fs.realpathSync(existingTestDir);
-
-const prevT = new GlobalTestState({
-  testDir: existingTestDir,
-});
-
-async function withdrawAndPay(
-  t: GlobalTestState,
-  wallet: WalletCli,
-  bank: BankService,
-  exchange: ExchangeService,
-  merchant: MerchantService,
-): Promise<void> {
-  await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:100" 
});
-
-  // Set up order.
-
-  const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", {
-    order: {
-      summary: "Buy me!",
-      amount: "TESTKUDOS:80",
-      fulfillment_url: "taler://fulfillment-success/thx",
-    },
-  });
-
-  let orderStatus = await MerchantPrivateApi.queryPrivateOrderStatus(merchant, 
{
-    orderId: orderResp.order_id,
-  });
-
-  t.assertTrue(orderStatus.order_status === "unpaid");
-
-  // Make wallet pay for the order
-
-  const r1 = await wallet.apiRequest("preparePay", {
-    talerPayUri: orderStatus.taler_pay_uri,
-  });
-  t.assertTrue(r1.type === "response");
-
-  const r2 = await wallet.apiRequest("confirmPay", {
-    // FIXME: should be validated, don't cast!
-    proposalId: (r1.result as any).proposalId,
-  });
-  t.assertTrue(r2.type === "response");
-
-  // Check if payment was successful.
-
-  orderStatus = await MerchantPrivateApi.queryPrivateOrderStatus(merchant, {
-    orderId: orderResp.order_id,
-  });
-
-  t.assertTrue(orderStatus.order_status === "paid");
-}
-
-/**
- * Run test.
- */
-runTestWithState(prevT, async (t: GlobalTestState) => {
-  // Set up test environment
-
-  const bank = BankService.fromExistingConfig(t);
-  const exchange = ExchangeService.fromExistingConfig(t, "testexchange-1");
-  const merchant = MerchantService.fromExistingConfig(t, "testmerchant-1");
-
-  await bank.start();
-  await exchange.start();
-  await merchant.start();
-  await Promise.all([
-    bank.pingUntilAvailable(),
-    merchant.pingUntilAvailable(),
-    exchange.pingUntilAvailable(),
-  ]);
-
-  const wallet = new WalletCli(t);
-
-  // Withdraw digital cash into the wallet.
-
-  const repetitions = Number.parseInt(process.env["TALER_TEST_REPEAT"] ?? "1");
-
-  for (let rep = 0; rep < repetitions; rep++) {
-    console.log("repetition", rep);
-    try {
-      wallet.deleteDatabase();
-      await withdrawAndPay(t, wallet, bank, exchange, merchant);
-    } catch (e) {
-      console.log("ignoring exception", e);
-    }
-  }
-
-  await t.shutdown();
-});
diff --git a/packages/taler-integrationtests/testrunner 
b/packages/taler-integrationtests/testrunner
deleted file mode 100755
index c03f6ed9..00000000
--- a/packages/taler-integrationtests/testrunner
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env bash
-
-# Simple test runner for the wallet integration tests.
-#
-# Usage: $0 TESTGLOB
-#
-# The TESTGLOB can be used to select which test cases to execute
-
-set -eu
-
-exit_int() {
-  echo "Interrupted..."
-  exit 2
-}
-
-trap "exit_int" INT
-
-if [ "$#" -ne 1 ]; then
-    echo "Usage: $0 TESTGLOB"
-    exit 1
-fi
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
-
-cd $DIR
-
-./node_modules/.bin/tsc -b
-
-export ESM_OPTIONS='{"sourceMap": true}'
-
-shopt -s extglob
-
-num_exec=0
-num_fail=0
-num_succ=0
-
-files_failed=''
-
-# Glob tests
-for file in lib/$1?(.js); do
-  case "$file" in
-    */test-*.js)
-      echo "executing test $file"
-      ret=0
-      node -r source-map-support/register -r esm $file || ret=$?
-      num_exec=$((num_exec+1))
-      case $ret in
-        0)
-          num_succ=$((num_succ+1))
-          ;;
-        *)
-          num_fail=$((num_fail+1))
-          files_failed=$files_failed:$file
-          ;;
-      esac
-      ;;
-    *)
-      continue
-    ;;
-  esac
-done
-
-echo "-----------------------------------"
-echo "Tests finished"
-echo "$num_succ/$num_exec tests succeeded"
-if [[ $num_fail != 0 ]]; then
-  echo "These tests failed:"
-  echo $files_failed | tr : \\n | sed '/^$/d'
-fi
-echo "-----------------------------------"
-
-if [[ $num_fail = 0 ]]; then
-  exit 0
-else
-  exit 1
-fi
-
diff --git a/packages/taler-integrationtests/tsconfig.json 
b/packages/taler-integrationtests/tsconfig.json
deleted file mode 100644
index 2fe0853d..00000000
--- a/packages/taler-integrationtests/tsconfig.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-  "compileOnSave": true,
-  "compilerOptions": {
-    "composite": true,
-    "declaration": true,
-    "declarationMap": false,
-    "target": "ES6",
-    "module": "ESNext",
-    "moduleResolution": "node",
-    "sourceMap": true,
-    "lib": ["es6"],
-    "types": ["node"],
-    "noImplicitReturns": true,
-    "noFallthroughCasesInSwitch": true,
-    "strict": true,
-    "strictPropertyInitialization": false,
-    "outDir": "lib",
-    "noImplicitAny": true,
-    "noImplicitThis": true,
-    "incremental": true,
-    "esModuleInterop": true,
-    "importHelpers": true,
-    "rootDir": "./src",
-    "typeRoots": ["./node_modules/@types"]
-  },
-  "references": [
-    {
-      "path": "../taler-wallet-core"
-    }
-  ],
-  "include": ["src/**/*"]
-}
diff --git a/packages/taler-wallet-cli/package.json 
b/packages/taler-wallet-cli/package.json
index 564cf7f4..c3fa6e79 100644
--- a/packages/taler-wallet-cli/package.json
+++ b/packages/taler-wallet-cli/package.json
@@ -43,7 +43,9 @@
     "typescript": "^4.0.5"
   },
   "dependencies": {
+    "@types/minimatch": "^3.0.3",
     "axios": "^0.21.0",
+    "minimatch": "^3.0.4",
     "source-map-support": "^0.5.19",
     "taler-wallet-core": "workspace:*",
     "tslib": "^2.0.3"
diff --git a/packages/taler-wallet-cli/src/index.ts 
b/packages/taler-wallet-cli/src/index.ts
index 87a51f30..e4f1ccb5 100644
--- a/packages/taler-wallet-cli/src/index.ts
+++ b/packages/taler-wallet-cli/src/index.ts
@@ -41,6 +41,7 @@ import {
 } from "taler-wallet-core";
 import * as clk from "./clk";
 import { deepStrictEqual } from "assert";
+import { getTestInfo, runTests } from "./integrationtests/testrunner";
 
 // This module also serves as the entry point for the crypto
 // thread worker, and thus must expose these two handlers.
@@ -749,6 +750,25 @@ const testCli = walletCli.subcommand("testingArgs", 
"testing", {
   help: "Subcommands for testing GNU Taler deployments.",
 });
 
+testCli
+  .subcommand("listIntegrationtests", "list-integrationtests")
+  .action(async (args) => {
+    for (const t of getTestInfo()) {
+      console.log(t.name);
+    }
+  });
+
+testCli
+  .subcommand("runIntegrationtests", "run-integrationtests")
+  .maybeArgument("pattern", clk.STRING, {
+    help: "Glob pattern to select which tests to run",
+  })
+  .action(async (args) => {
+    await runTests({
+      include_pattern: args.runIntegrationtests.pattern,
+    });
+  });
+
 testCli.subcommand("vectors", "vectors").action(async (args) => {
   printTestVectors();
 });
diff --git a/packages/taler-integrationtests/src/denomStructures.ts 
b/packages/taler-wallet-cli/src/integrationtests/denomStructures.ts
similarity index 100%
rename from packages/taler-integrationtests/src/denomStructures.ts
rename to packages/taler-wallet-cli/src/integrationtests/denomStructures.ts
diff --git a/packages/taler-integrationtests/src/faultInjection.ts 
b/packages/taler-wallet-cli/src/integrationtests/faultInjection.ts
similarity index 100%
rename from packages/taler-integrationtests/src/faultInjection.ts
rename to packages/taler-wallet-cli/src/integrationtests/faultInjection.ts
diff --git a/packages/taler-integrationtests/src/harness.ts 
b/packages/taler-wallet-cli/src/integrationtests/harness.ts
similarity index 95%
rename from packages/taler-integrationtests/src/harness.ts
rename to packages/taler-wallet-cli/src/integrationtests/harness.ts
index 58bcf2cf..108b7854 100644
--- a/packages/taler-integrationtests/src/harness.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/harness.ts
@@ -77,6 +77,7 @@ import {
   codecForPrepareTipResult,
   AcceptTipRequest,
   AbortPayWithRefundRequest,
+  handleWorkerError,
 } from "taler-wallet-core";
 import { URL } from "url";
 import axios, { AxiosError } from "axios";
@@ -93,6 +94,7 @@ import {
 import { ApplyRefundResponse } from "taler-wallet-core";
 import { PendingOperationsResponse } from "taler-wallet-core";
 import { CoinConfig } from "./denomStructures";
+import { after } from "taler-wallet-core/src/util/timer";
 
 const exec = util.promisify(require("child_process").exec);
 
@@ -236,11 +238,6 @@ export class GlobalTestState {
     this.testDir = params.testDir;
     this.procs = [];
     this.servers = [];
-
-    process.on("SIGINT", () => this.shutdownSync());
-    process.on("SIGTERM", () => this.shutdownSync());
-    process.on("unhandledRejection", () => this.shutdownSync());
-    process.on("uncaughtException", () => this.shutdownSync());
   }
 
   async assertThrowsOperationErrorAsync(
@@ -307,7 +304,7 @@ export class GlobalTestState {
     }
   }
 
-  private shutdownSync(): void {
+  shutdownSync(): void {
     for (const s of this.servers) {
       s.close();
       s.removeAllListeners();
@@ -315,12 +312,8 @@ export class GlobalTestState {
     for (const p of this.procs) {
       if (p.proc.exitCode == null) {
         p.proc.kill("SIGTERM");
-      } else {
       }
     }
-    console.log("*** test harness interrupted");
-    console.log("*** test state can be found under", this.testDir);
-    process.exit(1);
   }
 
   spawnService(
@@ -362,11 +355,6 @@ export class GlobalTestState {
     }
     this.inShutdown = true;
     console.log("shutting down");
-    if (shouldLingerAlways()) {
-      console.log("*** test finished, but requested to linger");
-      console.log("*** test state can be found under", this.testDir);
-      return;
-    }
     for (const s of this.servers) {
       s.close();
       s.removeAllListeners();
@@ -1047,7 +1035,7 @@ export class ExchangeService implements 
ExchangeServiceInterface {
     }
 
     const year = new Date().getFullYear();
-    for (let i = year; i < year+5; i++) {
+    for (let i = year; i < year + 5; i++) {
       await runCommand(
         this.globalState,
         "exchange-offline",
@@ -1438,76 +1426,57 @@ export interface MerchantInstanceConfig {
   defaultPayDelay?: Duration;
 }
 
-/**
- * Check if the test should hang around after it failed.
- */
-function shouldLinger(): boolean {
-  return (
-    process.env["TALER_TEST_LINGER"] == "1" ||
-    process.env["TALER_TEST_LINGER_ALWAYS"] == "1"
-  );
-}
+type TestStatus = "pass" | "fail" | "skip";
 
-/**
- * Check if the test should hang around even after it finished
- * successfully.
- */
-function shouldLingerAlways(): boolean {
-  return process.env["TALER_TEST_LINGER_ALWAYS"] == "1";
-}
+export interface TestRunResult {
+  /**
+   * Name of the test.
+   */
+  name: string;
 
-function updateCurrentSymlink(testDir: string): void {
-  const currLink = path.join(os.tmpdir(), "taler-integrationtest-current");
-  try {
-    fs.unlinkSync(currLink);
-  } catch (e) {
-    // Ignore
-  }
-  try {
-    fs.symlinkSync(testDir, currLink);
-  } catch (e) {
-    console.log(e);
-    // Ignore
-  }
+  /**
+   * How long did the test run?
+   */
+  timeSec: number;
+
+  status: TestStatus;
 }
 
-export function runTestWithState(
+export async function runTestWithState(
   gc: GlobalTestState,
   testMain: (t: GlobalTestState) => Promise<void>,
-) {
-  const main = async () => {
-    let ret = 0;
-    try {
-      updateCurrentSymlink(gc.testDir);
-      console.log("running test in directory", gc.testDir);
-      await testMain(gc);
-    } catch (e) {
-      console.error("FATAL: test failed with exception", e);
-      ret = 1;
-    } finally {
-      if (gc) {
-        if (shouldLinger()) {
-          console.log("test logs and config can be found under", gc.testDir);
-          console.log("keeping test environment running");
-        } else {
-          await gc.shutdown();
-          console.log("test logs and config can be found under", gc.testDir);
-          process.exit(ret);
-        }
-      }
-    }
+  testName: string,
+): Promise<TestRunResult> {
+  const startMs = new Date().getTime();
+
+  const handleSignal = () => {
+    gc.shutdownSync();
+    console.warn("**** received fatal signal, shutting down test harness");
+    process.exit(1);
   };
 
-  main();
-}
+  process.on("SIGINT", handleSignal);
+  process.on("SIGTERM", handleSignal);
+  process.on("unhandledRejection", handleSignal);
+  process.on("uncaughtException", handleSignal);
 
-export function runTest(
-  testMain: (gc: GlobalTestState) => Promise<void>,
-): void {
-  const gc = new GlobalTestState({
-    testDir: fs.mkdtempSync(path.join(os.tmpdir(), "taler-integrationtest-")),
-  });
-  runTestWithState(gc, testMain);
+  let status: TestStatus;
+  try {
+    console.log("running test in directory", gc.testDir);
+    await testMain(gc);
+    status = "pass";
+  } catch (e) {
+    console.error("FATAL: test failed with exception", e);
+    status = "fail";
+  } finally {
+    await gc.shutdown();
+  }
+  const afterMs = new Date().getTime();
+  return {
+    name: testName,
+    timeSec: (afterMs - startMs) / 1000,
+    status,
+  };
 }
 
 function shellWrap(s: string) {
diff --git a/packages/taler-integrationtests/src/helpers.ts 
b/packages/taler-wallet-cli/src/integrationtests/helpers.ts
similarity index 100%
rename from packages/taler-integrationtests/src/helpers.ts
rename to packages/taler-wallet-cli/src/integrationtests/helpers.ts
diff --git a/packages/taler-integrationtests/src/merchantApiTypes.ts 
b/packages/taler-wallet-cli/src/integrationtests/merchantApiTypes.ts
similarity index 100%
rename from packages/taler-integrationtests/src/merchantApiTypes.ts
rename to packages/taler-wallet-cli/src/integrationtests/merchantApiTypes.ts
diff --git a/packages/taler-integrationtests/src/scenario-prompt-payment.ts 
b/packages/taler-wallet-cli/src/integrationtests/scenario-prompt-payment.ts
similarity index 92%
rename from packages/taler-integrationtests/src/scenario-prompt-payment.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/scenario-prompt-payment.ts
index 3c34075d..e3c2af8e 100644
--- a/packages/taler-integrationtests/src/scenario-prompt-payment.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/scenario-prompt-payment.ts
@@ -17,13 +17,13 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPromptPaymentScenario(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -57,4 +57,4 @@ runTest(async (t: GlobalTestState) => {
 
   // Wait "forever"
   await new Promise(() => {});
-});
+}
diff --git a/packages/taler-integrationtests/src/test-bank-api.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-bank-api.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-bank-api.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-bank-api.ts
index 08991e27..b5cf6d5b 100644
--- a/packages/taler-integrationtests/src/test-bank-api.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-bank-api.ts
@@ -18,7 +18,6 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   WalletCli,
   ExchangeService,
@@ -35,7 +34,7 @@ import { defaultCoinConfig } from "./denomStructures";
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runBankApiTest(t: GlobalTestState) {
   // Set up test environment
 
   const db = await setupDb(t);
@@ -134,4 +133,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertTrue(
     balResp.balance.credit_debit_indicator === CreditDebitIndicator.Debit,
   );
-});
+}
diff --git a/packages/taler-integrationtests/src/test-claim-loop.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-claim-loop.ts
similarity index 97%
rename from packages/taler-integrationtests/src/test-claim-loop.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-claim-loop.ts
index 8c4df874..5a0540e9 100644
--- a/packages/taler-integrationtests/src/test-claim-loop.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-claim-loop.ts
@@ -18,10 +18,8 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   MerchantPrivateApi,
-  WalletCli,
 } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 import { URL } from "url";
@@ -32,7 +30,7 @@ import { URL } from "url";
  * FIXME: Is this test still necessary?  We initially wrote if to 
confirm/document
  * assumptions about how the merchant should work.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runClaimLoopTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -80,4 +78,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertTrue(orderStatusAfter.order_status === "claimed");
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-exchange-management.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-exchange-management.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-exchange-management.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-exchange-management.ts
index be990d9b..0fbef568 100644
--- a/packages/taler-integrationtests/src/test-exchange-management.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-exchange-management.ts
@@ -18,7 +18,6 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   WalletCli,
   setupDb,
@@ -43,7 +42,7 @@ import { defaultCoinConfig } from "./denomStructures";
 /**
  * Test if the wallet handles outdated exchange versions correct.y
  */
-runTest(async (t: GlobalTestState) => {
+export async function runExchangeManagementTest(t: GlobalTestState) {
   // Set up test environment
 
   const db = await setupDb(t);
@@ -247,4 +246,4 @@ runTest(async (t: GlobalTestState) => {
 
   // Make sure the faulty exchange isn't used for the suggestion.
   t.assertTrue(wd.possibleExchanges.length === 0);
-});
+}
diff --git a/packages/taler-integrationtests/src/test-fee-regression.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-fee-regression.ts
similarity index 97%
rename from packages/taler-integrationtests/src/test-fee-regression.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-fee-regression.ts
index 7b3193df..c56fe7ab 100644
--- a/packages/taler-integrationtests/src/test-fee-regression.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-fee-regression.ts
@@ -17,9 +17,7 @@
 /**
  * Imports.
  */
-import { defaultCoinConfig } from "./denomStructures";
 import {
-  runTest,
   GlobalTestState,
   BankService,
   ExchangeService,
@@ -166,7 +164,7 @@ export async function createMyTestkudosEnvironment(
 /**
  * Run test for basic, bank-integrated withdrawal and payment.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runFeeRegressionTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -203,4 +201,4 @@ runTest(async (t: GlobalTestState) => {
   const txs = await wallet.getTransactions();
   t.assertAmountEquals(txs.transactions[1].amountEffective, "TESTKUDOS:1.30");
   console.log(txs);
-});
+}
diff --git a/packages/taler-integrationtests/src/test-merchant-longpolling.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-merchant-longpolling.ts
similarity index 96%
rename from packages/taler-integrationtests/src/test-merchant-longpolling.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-merchant-longpolling.ts
index 5189d247..7ceccbf6 100644
--- a/packages/taler-integrationtests/src/test-merchant-longpolling.ts
+++ 
b/packages/taler-wallet-cli/src/integrationtests/test-merchant-longpolling.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 import {
   PreparePayResultType,
@@ -30,7 +30,7 @@ import axios from "axios";
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runMerchantLongpollingTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -129,4 +129,4 @@ runTest(async (t: GlobalTestState) => {
   });
 
   t.assertTrue(confirmPayRes.type === ConfirmPayResultType.Done);
-});
+}
diff --git a/packages/taler-integrationtests/src/test-merchant-refund-api.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-merchant-refund-api.ts
similarity index 99%
rename from packages/taler-integrationtests/src/test-merchant-refund-api.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-merchant-refund-api.ts
index 121c571d..27cf34b5 100644
--- a/packages/taler-integrationtests/src/test-merchant-refund-api.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-merchant-refund-api.ts
@@ -18,10 +18,8 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   MerchantPrivateApi,
-  MerchantService,
   BankServiceInterface,
   MerchantServiceInterface,
   WalletCli,
@@ -256,7 +254,7 @@ async function testRefundApiWithFulfillmentMessage(
 /**
  * Test case for the refund API of the merchant backend.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runMerchantRefundApiTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -283,4 +281,4 @@ runTest(async (t: GlobalTestState) => {
     exchange,
     merchant,
   });
-});
+}
diff --git a/packages/taler-integrationtests/src/test-pay-abort.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-pay-abort.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-pay-abort.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-pay-abort.ts
index 56650009..4fd6edc9 100644
--- a/packages/taler-integrationtests/src/test-pay-abort.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-pay-abort.ts
@@ -23,7 +23,6 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   MerchantService,
   ExchangeService,
@@ -31,8 +30,6 @@ import {
   BankService,
   WalletCli,
   MerchantPrivateApi,
-  BankApi,
-  BankAccessApi,
 } from "./harness";
 import {
   FaultInjectedExchangeService,
@@ -46,7 +43,7 @@ import { withdrawViaBank, makeTestPayment } from "./helpers";
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPayAbortTest(t: GlobalTestState) {
   // Set up test environment
 
   const db = await setupDb(t);
@@ -199,4 +196,4 @@ runTest(async (t: GlobalTestState) => {
   const txTypes = txr.transactions.map((x) => x.type);
 
   t.assertDeepEqual(txTypes, ["withdrawal", "payment", "refund"]);
-});
+}
diff --git a/packages/taler-integrationtests/src/test-pay-paid.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-pay-paid.ts
similarity index 97%
rename from packages/taler-integrationtests/src/test-pay-paid.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-pay-paid.ts
index 40f7d014..4d270660 100644
--- a/packages/taler-integrationtests/src/test-pay-paid.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-pay-paid.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import {
   withdrawViaBank,
   createFaultInjectedMerchantTestkudosEnvironment,
@@ -39,7 +39,7 @@ import { FaultInjectionRequestContext } from 
"./faultInjection";
  * since we can't initiate payment via a "claimed" private order status
  * response.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPayPaidTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -203,4 +203,4 @@ runTest(async (t: GlobalTestState) => {
   // Make sure the wallet is actually doing the replay properly.
   t.assertTrue(numPaidRequested == 1);
   t.assertTrue(numPayRequested == 0);
-});
+}
diff --git a/packages/taler-integrationtests/src/test-payment-claim.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-payment-claim.ts
similarity index 95%
rename from packages/taler-integrationtests/src/test-payment-claim.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-payment-claim.ts
index 6aed7e9e..ee8a8e49 100644
--- a/packages/taler-integrationtests/src/test-payment-claim.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-payment-claim.ts
@@ -17,19 +17,14 @@
 /**
  * Imports.
  */
-import {
-  runTest,
-  GlobalTestState,
-  MerchantPrivateApi,
-  WalletCli,
-} from "./harness";
+import { GlobalTestState, MerchantPrivateApi, WalletCli } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 import { PreparePayResultType, TalerErrorCode } from "taler-wallet-core";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPaymentClaimTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -106,4 +101,4 @@ runTest(async (t: GlobalTestState) => {
   );
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-payment-fault.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-payment-fault.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-payment-fault.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-payment-fault.ts
index ca31e8ee..55609f3f 100644
--- a/packages/taler-integrationtests/src/test-payment-fault.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-payment-fault.ts
@@ -22,7 +22,6 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   MerchantService,
   ExchangeService,
@@ -44,7 +43,7 @@ import { defaultCoinConfig } from "./denomStructures";
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPaymentFaultTest(t: GlobalTestState) {
   // Set up test environment
 
   const db = await setupDb(t);
@@ -207,4 +206,4 @@ runTest(async (t: GlobalTestState) => {
   });
 
   t.assertTrue(orderStatus.order_status === "paid");
-});
+}
diff --git a/packages/taler-integrationtests/src/test-payment-idempotency.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-payment-idempotency.ts
similarity index 95%
rename from packages/taler-integrationtests/src/test-payment-idempotency.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-payment-idempotency.ts
index 85be04d5..4323a7c9 100644
--- a/packages/taler-integrationtests/src/test-payment-idempotency.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-payment-idempotency.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 import { PreparePayResultType } from "taler-wallet-core";
 
@@ -25,7 +25,7 @@ import { PreparePayResultType } from "taler-wallet-core";
  * Test the wallet-core payment API, especially that repeated operations
  * return the expected result.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPaymentIdempotencyTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -100,4 +100,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertTrue(preparePayResultAfter.paid === true);
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-payment-multiple.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-payment-multiple.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-payment-multiple.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-payment-multiple.ts
index c6a0868a..6d05df33 100644
--- a/packages/taler-integrationtests/src/test-payment-multiple.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-payment-multiple.ts
@@ -18,7 +18,6 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   setupDb,
   BankService,
@@ -109,7 +108,7 @@ async function setupTest(
  *
  * This test uses a very sub-optimal denomination structure.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPaymentMultipleTest(t: GlobalTestState) {
   // Set up test environment
 
   const { merchant, bank, exchange } = await setupTest(t);
@@ -158,4 +157,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertTrue(orderStatus.order_status === "paid");
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-payment-transient.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-payment-transient.ts
similarity index 97%
rename from packages/taler-integrationtests/src/test-payment-transient.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-payment-transient.ts
index dc7ebbb1..73973bdc 100644
--- a/packages/taler-integrationtests/src/test-payment-transient.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-payment-transient.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import {
   withdrawViaBank,
   createFaultInjectedMerchantTestkudosEnvironment,
@@ -41,7 +41,7 @@ import {
  * Run test for a payment where the merchant has a transient
  * failure in /pay
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPaymentTransientTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -169,4 +169,4 @@ runTest(async (t: GlobalTestState) => {
       `expected status 202 (after paying), but got 
${publicOrderStatusResp.status}`,
     );
   }
-});
+}
\ No newline at end of file
diff --git a/packages/taler-integrationtests/src/test-payment.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-payment.ts
similarity index 92%
rename from packages/taler-integrationtests/src/test-payment.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-payment.ts
index 8a1240da..68713fd9 100644
--- a/packages/taler-integrationtests/src/test-payment.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-payment.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState } from "./harness";
+import { GlobalTestState } from "./harness";
 import {
   createSimpleTestkudosEnvironment,
   withdrawViaBank,
@@ -27,7 +27,7 @@ import {
 /**
  * Run test for basic, bank-integrated withdrawal and payment.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPaymentTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -50,4 +50,4 @@ runTest(async (t: GlobalTestState) => {
   await makeTestPayment(t, { wallet, merchant, order });
 
   await wallet.runUntilDone();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-paywall-flow.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-paywall-flow.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-paywall-flow.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-paywall-flow.ts
index 54c8ab46..5eeb7d27 100644
--- a/packages/taler-integrationtests/src/test-paywall-flow.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-paywall-flow.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 import {
   PreparePayResultType,
@@ -29,7 +29,7 @@ import axios from "axios";
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPaywallFlowTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -230,4 +230,4 @@ runTest(async (t: GlobalTestState) => {
   console.log(publicOrderStatusResp.data);
 
   t.assertTrue(pubUnpaidStatus.already_paid_order_id === firstOrderId);
-});
+}
diff --git a/packages/taler-integrationtests/src/test-refund-auto.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-refund-auto.ts
similarity index 93%
rename from packages/taler-integrationtests/src/test-refund-auto.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-refund-auto.ts
index 1a7055fd..afac993b 100644
--- a/packages/taler-integrationtests/src/test-refund-auto.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-refund-auto.ts
@@ -17,14 +17,14 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
-import { CoreApiResponse, durationFromSpec } from "taler-wallet-core";
+import { durationFromSpec } from "taler-wallet-core";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runRefundAutoTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -97,4 +97,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertDeepEqual(transactionTypes, ["withdrawal", "payment", "refund"]);
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-refund-gone.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-refund-gone.ts
similarity index 96%
rename from packages/taler-integrationtests/src/test-refund-gone.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-refund-gone.ts
index 764d5c28..483e9e06 100644
--- a/packages/taler-integrationtests/src/test-refund-gone.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-refund-gone.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import {
   createSimpleTestkudosEnvironment,
   withdrawViaBank,
@@ -33,7 +33,7 @@ import {
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runRefundGoneTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -124,4 +124,4 @@ runTest(async (t: GlobalTestState) => {
   console.log(JSON.stringify(r, undefined, 2));
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-refund-incremental.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-refund-incremental.ts
similarity index 97%
rename from packages/taler-integrationtests/src/test-refund-incremental.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-refund-incremental.ts
index 7ad406da..d90a4b5f 100644
--- a/packages/taler-integrationtests/src/test-refund-incremental.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-refund-incremental.ts
@@ -17,19 +17,14 @@
 /**
  * Imports.
  */
-import {
-  runTest,
-  GlobalTestState,
-  delayMs,
-  MerchantPrivateApi,
-} from "./harness";
+import { GlobalTestState, delayMs, MerchantPrivateApi } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 import { TransactionType, Amounts, durationFromSpec } from "taler-wallet-core";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runRefundIncrementalTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -188,4 +183,4 @@ runTest(async (t: GlobalTestState) => {
   }
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-refund.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-refund.ts
similarity index 95%
rename from packages/taler-integrationtests/src/test-refund.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-refund.ts
index 90813651..12e6b178 100644
--- a/packages/taler-integrationtests/src/test-refund.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-refund.ts
@@ -18,13 +18,13 @@
  * Imports.
  */
 import { durationFromSpec } from "taler-wallet-core";
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runRefundTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -100,4 +100,4 @@ runTest(async (t: GlobalTestState) => {
   console.log(JSON.stringify(r, undefined, 2));
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-revocation.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-revocation.ts
similarity index 97%
rename from packages/taler-integrationtests/src/test-revocation.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-revocation.ts
index 32cb5d62..ac989855 100644
--- a/packages/taler-integrationtests/src/test-revocation.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-revocation.ts
@@ -18,9 +18,7 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
-  MerchantPrivateApi,
   ExchangeService,
   MerchantService,
   WalletCli,
@@ -63,7 +61,7 @@ async function revokeAllWalletCoins(req: {
 /**
  * Basic time travel test.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runRevocationTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -119,4 +117,4 @@ runTest(async (t: GlobalTestState) => {
   }
 
   await makeTestPayment(t, { wallet, merchant, order });
-});
+}
diff --git a/packages/taler-integrationtests/src/test-timetravel-autorefresh.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-timetravel-autorefresh.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-timetravel-autorefresh.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-timetravel-autorefresh.ts
index 382051c8..747f6d75 100644
--- a/packages/taler-integrationtests/src/test-timetravel-autorefresh.ts
+++ 
b/packages/taler-wallet-cli/src/integrationtests/test-timetravel-autorefresh.ts
@@ -31,7 +31,6 @@ import {
   GlobalTestState,
   MerchantPrivateApi,
   MerchantService,
-  runTest,
   setupDb,
   WalletCli,
 } from "./harness";
@@ -67,7 +66,7 @@ async function applyTimeTravel(
 /**
  * Basic time travel test.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runTimetravelAutorefreshTest(t: GlobalTestState) {
   // Set up test environment
 
   const db = await setupDb(t);
@@ -201,4 +200,4 @@ runTest(async (t: GlobalTestState) => {
   });
 
   t.assertTrue(cpr.type === ConfirmPayResultType.Done);
-});
+}
diff --git a/packages/taler-integrationtests/src/test-timetravel-withdraw.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-timetravel-withdraw.ts
similarity index 95%
rename from packages/taler-integrationtests/src/test-timetravel-withdraw.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-timetravel-withdraw.ts
index e0124d46..b4de50b9 100644
--- a/packages/taler-integrationtests/src/test-timetravel-withdraw.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-timetravel-withdraw.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState } from "./harness";
+import { GlobalTestState } from "./harness";
 import {
   createSimpleTestkudosEnvironment,
   withdrawViaBank,
@@ -28,7 +28,7 @@ import { Duration, TransactionType } from "taler-wallet-core";
 /**
  * Basic time travel test.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runTimetravelWithdrawTest(t: GlobalTestState){
   // Set up test environment
 
   const {
@@ -87,4 +87,4 @@ runTest(async (t: GlobalTestState) => {
   // This doesn't work yet, see https://bugs.taler.net/n/6585
 
   // await wallet.runUntilDone({ maxRetries: 5 });
-});
+}
\ No newline at end of file
diff --git a/packages/taler-integrationtests/src/test-tipping.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-tipping.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-tipping.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-tipping.ts
index 4735de81..01ec6c1b 100644
--- a/packages/taler-integrationtests/src/test-tipping.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-tipping.ts
@@ -18,7 +18,6 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   MerchantPrivateApi,
   BankApi,
@@ -28,7 +27,7 @@ import { createSimpleTestkudosEnvironment, withdrawViaBank } 
from "./helpers";
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runTippingTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -125,4 +124,4 @@ runTest(async (t: GlobalTestState) => {
   // Check twice so make sure tip handling is idempotent
   await doTip();
   await doTip();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-wallettesting.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-wallettesting.ts
similarity index 95%
rename from packages/taler-integrationtests/src/test-wallettesting.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-wallettesting.ts
index a6014a88..cdb95485 100644
--- a/packages/taler-integrationtests/src/test-wallettesting.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-wallettesting.ts
@@ -22,13 +22,13 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState } from "./harness";
+import { GlobalTestState } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runWallettestingTest(t: GlobalTestState) {
   const {
     wallet,
     bank,
@@ -84,4 +84,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertDeepEqual(txTypes, ["withdrawal", "payment"]);
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-withdrawal-abort-bank.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-abort-bank.ts
similarity index 92%
rename from packages/taler-integrationtests/src/test-withdrawal-abort-bank.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-withdrawal-abort-bank.ts
index dd848b93..9a4e6004 100644
--- a/packages/taler-integrationtests/src/test-withdrawal-abort-bank.ts
+++ 
b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-abort-bank.ts
@@ -17,14 +17,14 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, BankApi, BankAccessApi } from "./harness";
+import { GlobalTestState, BankApi, BankAccessApi } from "./harness";
 import { createSimpleTestkudosEnvironment } from "./helpers";
 import { codecForBalancesResponse, TalerErrorCode } from "taler-wallet-core";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runWithdrawalAbortBankTest(t: GlobalTestState) {
   // Set up test environment
 
   const { wallet, bank, exchange } = await createSimpleTestkudosEnvironment(t);
@@ -64,4 +64,4 @@ runTest(async (t: GlobalTestState) => {
   );
 
   await t.shutdown();
-});
+}
diff --git 
a/packages/taler-integrationtests/src/test-withdrawal-bank-integrated.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-bank-integrated.ts
similarity index 93%
rename from 
packages/taler-integrationtests/src/test-withdrawal-bank-integrated.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-withdrawal-bank-integrated.ts
index d54309b3..89f5104a 100644
--- a/packages/taler-integrationtests/src/test-withdrawal-bank-integrated.ts
+++ 
b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-bank-integrated.ts
@@ -17,14 +17,14 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, BankApi, BankAccessApi } from "./harness";
+import { GlobalTestState, BankApi, BankAccessApi } from "./harness";
 import { createSimpleTestkudosEnvironment } from "./helpers";
 import { codecForBalancesResponse } from "taler-wallet-core";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runWithdrawalBankIntegratedTest(t: GlobalTestState) {
   // Set up test environment
 
   const { wallet, bank, exchange } = await createSimpleTestkudosEnvironment(t);
@@ -68,4 +68,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertAmountEquals("TESTKUDOS:9.72", balResp.balances[0].available);
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-withdrawal-manual.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-manual.ts
similarity index 94%
rename from packages/taler-integrationtests/src/test-withdrawal-manual.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-withdrawal-manual.ts
index aeac74d9..ef0db4a1 100644
--- a/packages/taler-integrationtests/src/test-withdrawal-manual.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-manual.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, BankApi } from "./harness";
+import { GlobalTestState, BankApi } from "./harness";
 import { createSimpleTestkudosEnvironment } from "./helpers";
 import { CoreApiResponse } from "taler-wallet-core";
 import { codecForBalancesResponse } from "taler-wallet-core";
@@ -25,7 +25,7 @@ import { codecForBalancesResponse } from "taler-wallet-core";
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runTestWithdrawalManualTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -75,4 +75,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertAmountEquals("TESTKUDOS:9.72", balResp.balances[0].available);
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-wallet-cli/src/integrationtests/testrunner.ts 
b/packages/taler-wallet-cli/src/integrationtests/testrunner.ts
new file mode 100644
index 00000000..d9804562
--- /dev/null
+++ b/packages/taler-wallet-cli/src/integrationtests/testrunner.ts
@@ -0,0 +1,176 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 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/>
+ */
+
+import { GlobalTestState, runTestWithState, TestRunResult } from "./harness";
+import { runPaymentTest } from "./test-payment";
+import * as fs from "fs";
+import * as path from "path";
+import * as os from "os";
+import { runBankApiTest } from "./test-bank-api";
+import { runClaimLoopTest } from "./test-claim-loop";
+import { runExchangeManagementTest } from "./test-exchange-management";
+import { runFeeRegressionTest } from "./test-fee-regression";
+import { runMerchantLongpollingTest } from "./test-merchant-longpolling";
+import { runMerchantRefundApiTest } from "./test-merchant-refund-api";
+import { runPayAbortTest } from "./test-pay-abort";
+import { runPayPaidTest } from "./test-pay-paid";
+import { runPaymentClaimTest } from "./test-payment-claim";
+import { runPaymentFaultTest } from "./test-payment-fault";
+import { runPaymentIdempotencyTest } from "./test-payment-idempotency";
+import { runPaymentMultipleTest } from "./test-payment-multiple";
+import { runPaymentTransientTest } from "./test-payment-transient";
+import { runPaywallFlowTest } from "./test-paywall-flow";
+import { runRefundAutoTest } from "./test-refund-auto";
+import { runRefundGoneTest } from "./test-refund-gone";
+import { runRefundIncrementalTest } from "./test-refund-incremental";
+import { runRefundTest } from "./test-refund";
+import { runRevocationTest } from "./test-revocation";
+import { runTimetravelAutorefreshTest } from "./test-timetravel-autorefresh";
+import { runTimetravelWithdrawTest } from "./test-timetravel-withdraw";
+import { runTippingTest } from "./test-tipping";
+import { runWallettestingTest } from "./test-wallettesting";
+import { runTestWithdrawalManualTest } from "./test-withdrawal-manual";
+import { runWithdrawalAbortBankTest } from "./test-withdrawal-abort-bank";
+import { runWithdrawalBankIntegratedTest } from 
"./test-withdrawal-bank-integrated";
+import M from "minimatch";
+
+/**
+ * Test runner.
+ */
+
+/**
+ * Spec for one test.
+ */
+interface TestMainFunction {
+  (t: GlobalTestState): Promise<void>;
+}
+
+const allTests: TestMainFunction[] = [
+  runBankApiTest,
+  runClaimLoopTest,
+  runExchangeManagementTest,
+  runFeeRegressionTest,
+  runMerchantLongpollingTest,
+  runMerchantRefundApiTest,
+  runPayAbortTest,
+  runPayPaidTest,
+  runPaymentClaimTest,
+  runPaymentFaultTest,
+  runPaymentIdempotencyTest,
+  runPaymentMultipleTest,
+  runPaymentTransientTest,
+  runPaywallFlowTest,
+  runRefundAutoTest,
+  runRefundGoneTest,
+  runRefundIncrementalTest,
+  runRefundTest,
+  runRevocationTest,
+  runTimetravelAutorefreshTest,
+  runTimetravelWithdrawTest,
+  runTippingTest,
+  runWallettestingTest,
+  runWithdrawalAbortBankTest,
+  runWithdrawalBankIntegratedTest,
+  runWallettestingTest,
+  runPaymentTest,
+];
+
+export interface TestRunSpec {
+  include_pattern?: string;
+}
+
+export interface TestInfo {
+  name: string;
+}
+
+function updateCurrentSymlink(testDir: string): void {
+  const currLink = path.join(os.tmpdir(), "taler-integrationtests-current");
+  try {
+    fs.unlinkSync(currLink);
+  } catch (e) {
+    // Ignore
+  }
+  try {
+    fs.symlinkSync(testDir, currLink);
+  } catch (e) {
+    console.log(e);
+    // Ignore
+  }
+}
+
+export function getTestName(tf: TestMainFunction): string {
+  const res = tf.name.match(/run([a-zA-Z0-9]*)Test/);
+  if (!res) {
+    throw Error("invalid test name, must be 'run${NAME}Test'");
+  }
+  return res[1]
+    .replace(/[a-z0-9][A-Z]/, (x) => {
+      return x[0] + "-" + x[1];
+    })
+    .toLowerCase();
+}
+
+export async function runTests(spec: TestRunSpec) {
+  const testRootDir = fs.mkdtempSync(
+    path.join(os.tmpdir(), "taler-integrationtests-"),
+  );
+  updateCurrentSymlink(testRootDir);
+  console.log("testsuite root directory: ", testRootDir);
+
+  let numTotal = 0;
+  let numFail = 0;
+  let numSkip = 0;
+  let numPass = 0;
+
+  const testResults: TestRunResult[] = [];
+
+  for (const [n, testCase] of allTests.entries()) {
+    const testName = getTestName(testCase);
+    if (spec.include_pattern && !M(testName, spec.include_pattern)) {
+      continue;
+    }
+    const testDir = path.join(testRootDir, testName);
+    fs.mkdirSync(testDir);
+    console.log(`running test ${testName}`);
+    const gc = new GlobalTestState({
+      testDir,
+    });
+    const result = await runTestWithState(gc, testCase, testName);
+    testResults.push(result);
+    console.log(result);
+    numTotal++;
+    if (result.status === "fail") {
+      numFail++;
+    } else if (result.status === "skip") {
+      numSkip++;
+    } else if (result.status === "pass") {
+      numPass++;
+    }
+  }
+  const resultsFile = path.join(testRootDir, "results.json");
+  fs.writeFileSync(
+    path.join(testRootDir, "results.json"),
+    JSON.stringify({ testResults }, undefined, 2),
+  );
+  console.log(`See ${resultsFile} for details`);
+  console.log(`Passed: ${numPass}/${numTotal}`);
+}
+
+export function getTestInfo(): TestInfo[] {
+  return allTests.map((x) => ({
+    name: getTestName(x),
+  }));
+}
diff --git a/packages/taler-wallet-core/src/operations/backup.ts 
b/packages/taler-wallet-core/src/operations/backup.ts
index 0c856b7b..a9f1fc43 100644
--- a/packages/taler-wallet-core/src/operations/backup.ts
+++ b/packages/taler-wallet-core/src/operations/backup.ts
@@ -1690,6 +1690,8 @@ export async function addBackupProvider(
     },
     paymentProposalIds: [],
     baseUrl: canonUrl,
+    lastError: undefined,
+    retryInfo: initRetryInfo(false),
   });
 }
 
@@ -1808,6 +1810,8 @@ async function backupRecoveryTheirs(
             active: true,
             baseUrl: prov.url,
             paymentProposalIds: [],
+            retryInfo: initRetryInfo(false),
+            lastError: undefined,
           });
         }
       }
diff --git a/packages/taler-wallet-core/src/types/dbTypes.ts 
b/packages/taler-wallet-core/src/types/dbTypes.ts
index 62ad01d2..f55dcb2f 100644
--- a/packages/taler-wallet-core/src/types/dbTypes.ts
+++ b/packages/taler-wallet-core/src/types/dbTypes.ts
@@ -36,9 +36,7 @@ import {
 
 import { Index, Store } from "../util/query";
 import { TalerErrorDetails, RefreshReason } from "./walletTypes";
-import {
-  ReserveTransaction,
-} from "./ReserveTransaction";
+import { ReserveTransaction } from "./ReserveTransaction";
 import { Timestamp, Duration } from "../util/time";
 import { IDBKeyPath } from "idb-bridge";
 import { RetryInfo } from "../util/retries";
@@ -1444,7 +1442,7 @@ export interface BackupProviderRecord {
   terms?: {
     supportedProtocolVersion: string;
     annualFee: AmountString;
-    storageLimitInMegabytes: number;  
+    storageLimitInMegabytes: number;
   };
 
   active: boolean;
@@ -1466,6 +1464,21 @@ export interface BackupProviderRecord {
   currentPaymentProposalId?: string;
 
   paymentProposalIds: string[];
+
+  /**
+   * Next scheduled backup.
+   */
+  nextBackupTimestamp?: Timestamp;
+
+  /**
+   * Retry info.
+   */
+  retryInfo: RetryInfo;
+
+  /**
+   * Last error that occured, if any.
+   */
+  lastError: TalerErrorDetails | undefined;
 }
 
 class ExchangesStore extends Store<"exchanges", ExchangeRecord> {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a81089d8..9c3dcaac 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -34,7 +34,7 @@ importers:
   packages/taler-integrationtests:
     dependencies:
       axios: 0.21.0
-      taler-wallet-core: 'link:../taler-wallet-core'
+      taler-wallet-core: link:../taler-wallet-core
       tslib: 2.0.3
     devDependencies:
       esm: 3.2.25
@@ -49,13 +49,13 @@ importers:
       nyc: ^15.1.0
       prettier: ^2.1.2
       source-map-support: ^0.5.19
-      taler-wallet-core: 'workspace:*'
+      taler-wallet-core: workspace:*
       ts-node: ^9.0.0
       tslib: ^2.0.3
       typescript: ^4.0.5
   packages/taler-wallet-android:
     dependencies:
-      taler-wallet-core: 'link:../taler-wallet-core'
+      taler-wallet-core: link:../taler-wallet-core
       tslib: 2.0.3
     devDependencies:
       '@rollup/plugin-commonjs': 16.0.0_rollup@2.33.2
@@ -80,14 +80,16 @@ importers:
       rollup: ^2.33.2
       rollup-plugin-sourcemaps: ^0.6.3
       rollup-plugin-terser: ^7.0.2
-      taler-wallet-core: 'workspace:*'
+      taler-wallet-core: workspace:*
       tslib: ^2.0.3
       typescript: ^4.0.5
   packages/taler-wallet-cli:
     dependencies:
+      '@types/minimatch': 3.0.3
       axios: 0.21.0
+      minimatch: 3.0.4
       source-map-support: 0.5.19
-      taler-wallet-core: 'link:../taler-wallet-core'
+      taler-wallet-core: link:../taler-wallet-core
       tslib: 2.0.3
     devDependencies:
       '@rollup/plugin-commonjs': 16.0.0_rollup@2.33.2
@@ -107,15 +109,17 @@ importers:
       '@rollup/plugin-json': ^4.1.0
       '@rollup/plugin-node-resolve': ^10.0.0
       '@rollup/plugin-replace': ^2.3.4
+      '@types/minimatch': ^3.0.3
       '@types/node': ^14.14.7
       axios: ^0.21.0
+      minimatch: ^3.0.4
       prettier: ^2.1.2
       rimraf: ^3.0.2
       rollup: ^2.33.2
       rollup-plugin-sourcemaps: ^0.6.3
       rollup-plugin-terser: ^7.0.2
       source-map-support: ^0.5.19
-      taler-wallet-core: 'workspace:*'
+      taler-wallet-core: workspace:*
       tslib: ^2.0.3
       typedoc: ^0.19.2
       typescript: ^4.0.5
@@ -125,7 +129,7 @@ importers:
       axios: 0.21.0
       big-integer: 1.6.48
       fflate: 0.3.10
-      idb-bridge: 'link:../idb-bridge'
+      idb-bridge: link:../idb-bridge
       source-map-support: 0.5.19
       tslib: 2.0.3
     devDependencies:
@@ -144,7 +148,7 @@ importers:
       jed: 1.1.1
       nyc: 15.1.0
       po2json: 0.4.5
-      pogen: 'link:../pogen'
+      pogen: link:../pogen
       prettier: 2.1.2
       rimraf: 3.0.2
       rollup: 2.33.2
@@ -169,11 +173,11 @@ importers:
       eslint-plugin-react-hooks: ^4.2.0
       esm: ^3.2.25
       fflate: ^0.3.10
-      idb-bridge: 'workspace:*'
+      idb-bridge: workspace:*
       jed: ^1.1.1
       nyc: ^15.1.0
       po2json: ^0.4.5
-      pogen: 'workspace:*'
+      pogen: workspace:*
       prettier: ^2.1.2
       rimraf: ^3.0.2
       rollup: ^2.33.2
@@ -186,7 +190,7 @@ importers:
   packages/taler-wallet-webextension:
     dependencies:
       moment: 2.29.1
-      taler-wallet-core: 'link:../taler-wallet-core'
+      taler-wallet-core: link:../taler-wallet-core
       tslib: 2.0.3
     devDependencies:
       '@rollup/plugin-commonjs': 16.0.0_rollup@2.33.2
@@ -232,7 +236,7 @@ importers:
       rollup-plugin-ignore: ^1.0.9
       rollup-plugin-sourcemaps: ^0.6.3
       rollup-plugin-terser: ^7.0.2
-      taler-wallet-core: 'workspace:*'
+      taler-wallet-core: workspace:*
       tslib: ^2.0.3
       typescript: ^4.0.5
 lockfileVersion: 5.2
@@ -684,6 +688,10 @@ packages:
     dev: true
     resolution:
       integrity: sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
+  /@types/minimatch/3.0.3:
+    dev: false
+    resolution:
+      integrity: 
sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
   /@types/node/10.17.13:
     dev: true
     resolution:
@@ -1222,7 +1230,6 @@ packages:
     resolution:
       integrity: 
sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==
   /balanced-match/1.0.0:
-    dev: true
     resolution:
       integrity: sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
   /big-integer/1.6.48:
@@ -1264,7 +1271,6 @@ packages:
     dependencies:
       balanced-match: 1.0.0
       concat-map: 0.0.1
-    dev: true
     resolution:
       integrity: 
sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
   /braces/3.0.2:
@@ -1525,7 +1531,6 @@ packages:
     resolution:
       integrity: sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
   /concat-map/0.0.1:
-    dev: true
     resolution:
       integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
   /concordance/5.0.1:
@@ -3431,7 +3436,6 @@ packages:
   /minimatch/3.0.4:
     dependencies:
       brace-expansion: 1.1.11
-    dev: true
     resolution:
       integrity: 
sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
   /minimist/1.2.5:
diff --git a/tsconfig.build.json b/tsconfig.build.json
index 6755b8e8..6db804a3 100644
--- a/tsconfig.build.json
+++ b/tsconfig.build.json
@@ -1,7 +1,7 @@
 {
   "compileOnSave": true,
   "compilerOptions": {
-    "composite": true,
+    "composite": true
   },
   "references": [
     {
@@ -10,9 +10,6 @@
     {
       "path": "packages/taler-wallet-core/"
     },
-    {
-      "path": "packages/taler-integrationtests"
-    },
     {
       "path": "packages/taler-wallet-cli"
     }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]