diff --git a/apps/desktop/__tests__/auto-updates.test.ts b/apps/desktop/__tests__/auto-updates.test.ts
index cab7a2ca0..e70e0bb2a 100644
--- a/apps/desktop/__tests__/auto-updates.test.ts
+++ b/apps/desktop/__tests__/auto-updates.test.ts
@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import { test, testCleanup } from "./utils.js";
+import { testCleanup, test } from "./test-override.js";
import { writeFile } from "fs/promises";
import { Page } from "playwright";
import { gt, lt } from "semver";
diff --git a/apps/desktop/__tests__/global-setup.ts b/apps/desktop/__tests__/global-setup.ts
new file mode 100644
index 000000000..28337fce0
--- /dev/null
+++ b/apps/desktop/__tests__/global-setup.ts
@@ -0,0 +1,24 @@
+/*
+This file is part of the Notesnook project (https://notesnook.com/)
+
+Copyright (C) 2023 Streetwriters (Private) Limited
+
+This program 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 of the License, or
+(at your option) any later version.
+
+This program 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 this program. If not, see .
+*/
+
+import { buildApp } from "./utils";
+
+export default async function setup() {
+ await buildApp();
+}
diff --git a/apps/desktop/__tests__/launch.test.ts b/apps/desktop/__tests__/launch.test.ts
index 0617be6df..fd576a86f 100644
--- a/apps/desktop/__tests__/launch.test.ts
+++ b/apps/desktop/__tests__/launch.test.ts
@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import { testCleanup, test } from "./utils.js";
+import { testCleanup, test } from "./test-override.js";
test("make sure app loads", async ({
ctx: { page },
diff --git a/apps/desktop/__tests__/test-override.ts b/apps/desktop/__tests__/test-override.ts
new file mode 100644
index 000000000..92fe56612
--- /dev/null
+++ b/apps/desktop/__tests__/test-override.ts
@@ -0,0 +1,50 @@
+/*
+This file is part of the Notesnook project (https://notesnook.com/)
+
+Copyright (C) 2023 Streetwriters (Private) Limited
+
+This program 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 of the License, or
+(at your option) any later version.
+
+This program 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 this program. If not, see .
+*/
+
+import { test as vitestTest, TestContext } from "vitest";
+import { buildAndLaunchApp, Fixtures, TestOptions } from "./utils";
+import { mkdir, rm } from "fs/promises";
+import path from "path";
+import slugify from "slugify";
+
+export const test = vitestTest.extend({
+ options: { version: "3.0.0" } as TestOptions,
+ ctx: async ({ options }, use) => {
+ const ctx = await buildAndLaunchApp(options);
+ await use(ctx);
+ }
+});
+
+export async function testCleanup(context: TestContext) {
+ const ctx = (context.task.context as unknown as Fixtures).ctx;
+ if (context.task.result?.state === "fail") {
+ await mkdir("test-results", { recursive: true });
+ await ctx.page.screenshot({
+ path: path.join(
+ "test-results",
+ `${slugify(context.task.name)}-${process.platform}-${
+ process.arch
+ }-error.png`
+ )
+ });
+ }
+ await ctx.app.close();
+ await rm(ctx.userDataDir, { force: true, recursive: true });
+ await rm(ctx.outputDir, { force: true, recursive: true });
+}
diff --git a/apps/desktop/__tests__/utils.ts b/apps/desktop/__tests__/utils.ts
index 90d0d33ac..b4ecaf155 100644
--- a/apps/desktop/__tests__/utils.ts
+++ b/apps/desktop/__tests__/utils.ts
@@ -18,19 +18,19 @@ along with this program. If not, see .
*/
import { execSync } from "child_process";
-import { cp, mkdir, readFile, rm, writeFile } from "fs/promises";
+import { cp, readFile, writeFile } from "fs/promises";
import { fileURLToPath } from "node:url";
import path, { join, resolve } from "path";
import { _electron as electron } from "playwright";
-import slugify from "slugify";
-import { test as vitestTest, TestContext } from "vitest";
import { existsSync } from "fs";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const IS_DEBUG = process.env.NN_DEBUG === "true" || process.env.CI === "true";
+const productName = `NotesnookTestHarness`;
+const SOURCE_DIR = resolve("output", productName);
-interface AppContext {
+export interface AppContext {
app: import("playwright").ElectronApplication;
page: import("playwright").Page;
configPath: string;
@@ -39,45 +39,21 @@ interface AppContext {
relaunch: () => Promise;
}
-interface TestOptions {
+export interface TestOptions {
version: string;
}
-interface Fixtures {
+export interface Fixtures {
options: TestOptions;
ctx: AppContext;
}
-export const test = vitestTest.extend({
- options: { version: "3.0.0" } as TestOptions,
- ctx: async ({ options }, use) => {
- const ctx = await buildAndLaunchApp(options);
- await use(ctx);
- }
-});
-
-export async function testCleanup(context: TestContext) {
- const ctx = (context.task.context as unknown as Fixtures).ctx;
- if (context.task.result?.state === "fail") {
- await mkdir("test-results", { recursive: true });
- await ctx.page.screenshot({
- path: path.join(
- "test-results",
- `${slugify(context.task.name)}-${process.platform}-${
- process.arch
- }-error.png`
- )
- });
- }
- await ctx.app.close();
- await rm(ctx.userDataDir, { force: true, recursive: true });
- await rm(ctx.outputDir, { force: true, recursive: true });
-}
-
-async function buildAndLaunchApp(options?: TestOptions): Promise {
+export async function buildAndLaunchApp(
+ options?: TestOptions
+): Promise {
const productName = `notesnooktest${makeid(10)}`;
const outputDir = path.join("test-artifacts", `${productName}-output`);
- const executablePath = await buildApp({
+ const executablePath = await copyBuild({
...options,
outputDir
});
@@ -139,16 +115,8 @@ async function launchApp(executablePath: string, packageName: string) {
}
let MAX_RETRIES = 3;
-async function buildApp({
- version,
- outputDir
-}: {
- version?: string;
- outputDir: string;
-}) {
- const productName = `NotesnookTestHarness`;
- const sourceDir = resolve("output", productName);
- if (!existsSync(sourceDir)) {
+export async function buildApp(version?: string) {
+ if (!existsSync(SOURCE_DIR)) {
const args = [
"electron-builder",
"--dir",
@@ -167,33 +135,40 @@ async function buildApp({
NOTESNOOK_STAGING: "true",
NN_PRODUCT_NAME: productName,
NN_APP_ID: `com.notesnook.test.${productName}`,
- NN_OUTPUT_DIR: sourceDir
+ NN_OUTPUT_DIR: SOURCE_DIR
}
});
} catch (e) {
if (--MAX_RETRIES) {
console.log("retrying...");
- return await buildApp({ outputDir, version });
+ return await buildApp(version);
} else throw e;
}
}
- return process.platform === "win32"
- ? await copyBuildWindows(sourceDir, outputDir, productName, version)
- : process.platform === "darwin"
- ? await copyBuildMacOS(sourceDir, outputDir, productName, version)
- : await copyBuildLinux(sourceDir, outputDir, productName, version);
}
-async function copyBuildLinux(
- sourceDir: string,
+async function copyBuild({
+ version,
+ outputDir
+}: {
+ version?: string;
+ outputDir: string;
+}) {
+ return process.platform === "win32"
+ ? await makeBuildCopyWindows(outputDir, productName, version)
+ : process.platform === "darwin"
+ ? await makeBuildCopyMacOS(outputDir, productName, version)
+ : await makeBuildCopyLinux(outputDir, productName, version);
+}
+
+async function makeBuildCopyLinux(
outputDir: string,
productName: string,
version?: string
) {
const platformDir =
process.arch === "arm64" ? "linux-arm64-unpacked" : "linux-unpacked";
- const appDir = await copyBuild(
- sourceDir,
+ const appDir = await makeBuildCopy(
outputDir,
platformDir,
"resources",
@@ -207,16 +182,14 @@ async function copyBuildLinux(
);
}
-async function copyBuildWindows(
- sourceDir: string,
+async function makeBuildCopyWindows(
outputDir: string,
productName: string,
version?: string
) {
const platformDir =
process.arch === "arm64" ? "win-arm64-unpacked" : "win-unpacked";
- const appDir = await copyBuild(
- sourceDir,
+ const appDir = await makeBuildCopy(
outputDir,
platformDir,
"resources",
@@ -225,15 +198,13 @@ async function copyBuildWindows(
return resolve(__dirname, "..", appDir, `${productName}.exe`);
}
-async function copyBuildMacOS(
- sourceDir: string,
+async function makeBuildCopyMacOS(
outputDir: string,
productName: string,
version?: string
) {
const platformDir = process.arch === "arm64" ? "mac-arm64" : "mac";
- const appDir = await copyBuild(
- sourceDir,
+ const appDir = await makeBuildCopy(
outputDir,
platformDir,
join(`${productName}.app`, "Contents", "Resources"),
@@ -250,15 +221,14 @@ async function copyBuildMacOS(
);
}
-async function copyBuild(
- sourceDir: string,
+async function makeBuildCopy(
outputDir: string,
platformDir: string,
resourcesDir: string,
version?: string
) {
const appDir = outputDir;
- await cp(join(sourceDir, platformDir), outputDir, {
+ await cp(join(SOURCE_DIR, platformDir), outputDir, {
recursive: true,
preserveTimestamps: true,
verbatimSymlinks: true,
diff --git a/apps/desktop/vitest.config.ts b/apps/desktop/vitest.config.ts
index eacce4391..0541e15bf 100644
--- a/apps/desktop/vitest.config.ts
+++ b/apps/desktop/vitest.config.ts
@@ -26,6 +26,7 @@ export default defineConfig({
concurrent: true,
shuffle: true
},
+ globalSetup: "./__tests__/global-setup.ts",
dir: "./__tests__/",
exclude: [
"**/node_modules/**",