tutanota/test/TestBuilder.js
bed 61fe0304ba
Setup release pipline for crypto-primitives.wasm
In order to make use of the crypto-primitives crate from the web client
we now generate wasm file using wasm-pack and included these steps into
the dev and webapp build process.

In order to test the behavior we also made use of the exported primitives from the Ed255519Facade

Also adds test for the Ed25519 exported functions.

tuta#2102, tuta#2099, tuta#2098

Co-authored-by: hec <hec@tutao.de>
Co-authored-by: bedhub <bedhub@users.noreply.github.com>
2025-08-07 09:51:21 +02:00

174 lines
5.2 KiB
JavaScript

import * as env from "../buildSrc/env.js"
import { preludeEnvPlugin } from "../buildSrc/env.js"
import fs from "fs-extra"
import path, { dirname } from "node:path"
import { renderHtml } from "../buildSrc/LaunchHtml.js"
import { getTutanotaAppVersion, runStep, writeFile } from "../buildSrc/buildUtils.js"
import { buildPackages } from "../buildSrc/packageBuilderFunctions.js"
import { domainConfigs } from "../buildSrc/DomainConfigs.js"
import { sh } from "../buildSrc/sh.js"
import { rolldown } from "rolldown"
import { resolveLibs } from "../buildSrc/RollupConfig.js"
import { nodeGypPlugin } from "../buildSrc/nodeGypPlugin.js"
import { fileURLToPath } from "node:url"
import { copyCryptoPrimitiveCrateIntoWasmDir, WASM_PACK_OUT_DIR } from "../buildSrc/cryptoPrimitivesUtils.js"
const currentDir = dirname(fileURLToPath(import.meta.url))
const projectRoot = path.resolve(path.join(currentDir, ".."))
export async function runTestBuild({ networkDebugging = false, clean, fast = false }) {
if (clean) {
await runStep("Clean", async () => {
await fs.emptyDir("build")
fs.rm(projectRoot + WASM_PACK_OUT_DIR, { recursive: true, force: true })
})
}
if (!fast) {
await runStep("Packages", async () => {
await buildPackages("..")
// we know which wasm need to be included in the project, instead of running branches condition on each and every file of the project we do some
// transformation AOT for our three files (currently only crypto-primitives but argon2 and liboqs will follow
await copyCryptoPrimitiveCrateIntoWasmDir({
wasmOutputDir: "build",
pathSourcePrefix: "../",
})
})
await runStep("Types", async () => {
await sh`npx tsc --incremental true --noEmit true`
})
}
const version = await getTutanotaAppVersion()
const localEnv = env.create({
staticUrl: "http://localhost:9000",
version,
mode: "Test",
dist: false,
domainConfigs,
networkDebugging,
})
await runStep("Assets", async () => {
const pjPath = path.join("..", "package.json")
await fs.mkdir(inBuildDir(), { recursive: true })
await fs.copyFile(pjPath, inBuildDir("package.json"))
await createUnitTestHtml(localEnv)
})
await runStep("Rolldown", async () => {
const { rollupWasmLoader } = await import("@tutao/tuta-wasm-loader")
const bundle = await rolldown({
input: ["tests/testInBrowser.ts", "tests/testInNode.ts", "../src/common/api/common/pow-worker.ts"],
platform: "neutral",
define: {
// See Env.ts for explanation
LOAD_ASSERTIONS: "false",
},
external: [
"electron",
// esbuild can't deal with node imports in ESM output at the moment
// see https://github.com/evanw/esbuild/pull/2067
"xhr2",
"express",
"server-destroy",
"body-parser",
"jsdom",
/node:.*/,
"http",
"stream",
"fs",
"assert",
"net",
"diagnostics_channel",
"zlib",
"console",
"async_hooks",
"util/types",
"perf_hooks",
"worker_threads",
"path",
"tls",
"buffer",
"events",
"util",
"string_decoder",
"crypto", // oxmsg needs it
"memcpy", // optional dep of oxmsg
],
plugins: [
preludeEnvPlugin(localEnv),
resolveLibs(".."),
nodeGypPlugin({
rootDir: projectRoot,
platform: process.platform,
architecture: process.arch,
nodeModule: "@signalapp/sqlcipher",
environment: "node",
targetName: "node_sqlcipher",
}),
rollupWasmLoader({
output: `${process.cwd()}/build`,
webassemblyLibraries: [
{
name: "liboqs.wasm",
command: "make -f Makefile_liboqs build",
workingDir: `${process.cwd()}/../libs/webassembly/`,
outputPath: `${process.cwd()}/build/liboqs.wasm`,
fallback: {
command: "make -f Makefile_liboqs fallback",
workingDir: `${process.cwd()}/../libs/webassembly/`,
outputPath: `${process.cwd()}/build/liboqs.js`,
},
},
{
name: "argon2.wasm",
command: "make -f Makefile_argon2 build",
workingDir: `${process.cwd()}/../libs/webassembly/`,
outputPath: `${process.cwd()}/build/argon2.wasm`,
fallback: {
command: "make -f Makefile_argon2 fallback",
workingDir: `${process.cwd()}/../libs/webassembly/`,
outputPath: `${process.cwd()}/build/argon2.js`,
},
},
],
}),
],
resolve: {
mainFields: ["module", "main"],
alias: {
// Take browser testdouble without funny require() magic
testdouble: path.resolve("../node_modules/testdouble/dist/testdouble.js"),
},
},
onwarn: (warning, defaultHandler) => {
if (warning.code !== "EVAL") {
defaultHandler(warning)
}
},
})
await bundle.write({
dir: "./build",
format: "esm",
sourcemap: true,
// overwrite the files rather than keeping all versions in the build folder
chunkFileNames: "[name]-chunk.js",
})
})
}
async function createUnitTestHtml(localEnv) {
const imports = [{ src: `./testInBrowser.js`, type: "module" }]
const htmlFilePath = inBuildDir("test.html")
console.log(`Generating browser tests at "${htmlFilePath}"`)
const html = await renderHtml(imports, localEnv)
await writeFile(htmlFilePath, html)
}
function inBuildDir(...files) {
return path.join("build", ...files)
}