git » sdk » commit 50d17c2

Cleanup playwright tests with helpers

author Eric Roberts
2026-08-26 18:14:55 UTC
committer Stephen Paul Weber
2026-08-26 18:16:17 UTC
parent 3e7119c5551eb27b8e079f19b6c1030f3ca259fb

Cleanup playwright tests with helpers

Basically the same thing we did with TestSqlite.hx already

The page helper functions have to happen inside the page so they had to be
implemented this way.

test/browser-test.ts +46 -2
test/persistence-tests.ts +70 -70

diff --git a/test/browser-test.ts b/test/browser-test.ts
index 8f49cdd..1e28d50 100644
--- a/test/browser-test.ts
+++ b/test/browser-test.ts
@@ -1,10 +1,30 @@
-import { test as base, expect, type JSHandle } from "@playwright/test";
+import { test as base, expect, type JSHandle, type Page } from "@playwright/test";
+import type { borogove_Persistence } from "../npm/borogove-browser";
 import type { borogove_persistence_Sqlite } from "../npm/sqlite-wasm";
 
+type PageKeyPair = {
+	privKey: number[];
+	pubKey: number[];
+};
+
+type PageHelpers = {
+	keyToBuffer(key: number[]): ArrayBuffer;
+	bufferToKey(key: ArrayBuffer): number[];
+	keyPairToBuffers(keyPair: PageKeyPair): {
+		privKey: ArrayBuffer;
+		pubKey: ArrayBuffer;
+	};
+	buffersToKeyPair(keyPair: {
+		privKey: ArrayBuffer;
+		pubKey: ArrayBuffer;
+	}): PageKeyPair;
+};
+
 type BrowserFixtures = {
 	borogove: JSHandle<any>;
 	createChannel: JSHandle<any>;
-	persistence: JSHandle<any>;
+	pageHelpers: JSHandle<PageHelpers>;
+	persistence: JSHandle<borogove_Persistence>;
 	storeIncompleteMember: JSHandle<any>;
 };
 
@@ -20,6 +40,28 @@ declare global {
 	}
 }
 
+const pageHelpers = async (
+	{ page }: { page: Page },
+	use: (helpers: JSHandle<PageHelpers>) => Promise<void>,
+) => {
+	const helpers = await page.evaluateHandle(() => ({
+		keyToBuffer: (key: number[]) => new Uint8Array(key).buffer,
+		bufferToKey: (key: ArrayBuffer) => [...new Uint8Array(key)],
+		keyPairToBuffers: (keyPair: PageKeyPair) => ({
+			privKey: new Uint8Array(keyPair.privKey).buffer,
+			pubKey: new Uint8Array(keyPair.pubKey).buffer,
+		}),
+		buffersToKeyPair: (keyPair: {
+			privKey: ArrayBuffer;
+			pubKey: ArrayBuffer;
+		}) => ({
+			privKey: [...new Uint8Array(keyPair.privKey)],
+			pubKey: [...new Uint8Array(keyPair.pubKey)],
+		}),
+	}));
+	await use(helpers);
+};
+
 export const idbTest = base.extend<BrowserFixtures>({
 	page: async ({ page }, use) => {
 		await page.goto("/idb");
@@ -29,6 +71,7 @@ export const idbTest = base.extend<BrowserFixtures>({
 		const borogove = await page.evaluateHandle(() => window.borogove);
 		await use(borogove);
 	},
+	pageHelpers,
 	createChannel: async ({ page, borogove }, use) => {
 		const createChannel = await page.evaluateHandle(
 			(borogove) => (persistence, chatId) =>
@@ -84,6 +127,7 @@ export const sqliteTest = base.extend<SqliteFixtures>({
 		const borogove = await page.evaluateHandle(() => window.borogove);
 		await use(borogove);
 	},
+	pageHelpers,
 	sqlite: async ({ page }, use) => {
 		const sqlite = await page.evaluateHandle(() => window.sqlite);
 		await use(sqlite);
diff --git a/test/persistence-tests.ts b/test/persistence-tests.ts
index 3cac885..7c8257f 100644
--- a/test/persistence-tests.ts
+++ b/test/persistence-tests.ts
@@ -1,4 +1,5 @@
 import { idbTest, sqliteTest, expect } from "./browser-test";
+import { randomBytes } from "node:crypto";
 
 type PersistenceTest = typeof idbTest | typeof sqliteTest;
 
@@ -1511,36 +1512,26 @@ export function sharedPersistenceTests(test: PersistenceTest) {
 
 	test("storeOmemoIdentityKey stores the key pair", async ({
 		page,
+		pageHelpers,
 		persistence,
 	}) => {
-		const keyPair = {
-			privKey: [0, 1, 2, 127, 128, 255],
-			pubKey: [255, 128, 127, 2, 1, 0],
-		};
+		const account = "omemo-identity-existing@example.com";
+		const keyPair = makeKeyPair();
 
 		const result = await page.evaluate(
-			async ({ persistence, keyPair }) => {
+			async ({ persistence, account, keyPair, pageHelpers }) => {
 				await persistence.storeOmemoIdentityKey(
-					"omemo-identity-existing@example.com",
-					{
-						privKey: new Uint8Array(keyPair.privKey).buffer,
-						pubKey: new Uint8Array(keyPair.pubKey).buffer,
-					},
-				);
-				const loadedKeyPair = await persistence.getOmemoIdentityKey(
-					"omemo-identity-existing@example.com",
+					account,
+					pageHelpers.keyPairToBuffers(keyPair),
 				);
+				const loadedKeyPair = await persistence.getOmemoIdentityKey(account);
 
-				return {
-					loadedPrivKey: [...new Uint8Array(loadedKeyPair.privKey)],
-					loadedPubKey: [...new Uint8Array(loadedKeyPair.pubKey)],
-				};
+				return pageHelpers.buffersToKeyPair(loadedKeyPair);
 			},
-			{ persistence, keyPair },
+			{ persistence, account, keyPair, pageHelpers },
 		);
 
-		expect(result.loadedPrivKey).toEqual([0, 1, 2, 127, 128, 255]);
-		expect(result.loadedPubKey).toEqual([255, 128, 127, 2, 1, 0]);
+		expectKeyPair(result, keyPair);
 	});
 
 	test("getOmemoDeviceList returns an empty list when none is stored", async ({
@@ -1614,19 +1605,16 @@ export function sharedPersistenceTests(test: PersistenceTest) {
 
 	test("storeOmemoPreKey stores a removable pre-key", async ({
 		page,
+		pageHelpers,
 		persistence,
 	}) => {
 		const identifier = "omemo-prekey-existing@example.com";
 		const keyId = 42;
-		const keyPair = {
-			privKey: [0, 1, 2, 127, 128, 255],
-			pubKey: [255, 128, 127, 2, 1, 0],
-		};
+		const keyPair = makeKeyPair();
 		const result = await page.evaluate(
-			async ({ persistence, identifier, keyId, keyPair }) => {
+			async ({ persistence, identifier, keyId, keyPair, pageHelpers }) => {
 				await persistence.storeOmemoPreKey(identifier, keyId, {
-					privKey: new Uint8Array(keyPair.privKey).buffer,
-					pubKey: new Uint8Array(keyPair.pubKey).buffer,
+					...pageHelpers.keyPairToBuffers(keyPair),
 				});
 				const loadedKeyPair = await persistence.getOmemoPreKey(
 					identifier,
@@ -1635,53 +1623,47 @@ export function sharedPersistenceTests(test: PersistenceTest) {
 				await persistence.removeOmemoPreKey(identifier, keyId);
 				const afterRemove = await persistence.getOmemoPreKey(identifier, keyId);
 
-				return {
-					loadedPrivKey: [...new Uint8Array(loadedKeyPair.privKey)],
-					loadedPubKey: [...new Uint8Array(loadedKeyPair.pubKey)],
-					afterRemove,
-				};
+				return { loadedKeyPair: pageHelpers.buffersToKeyPair(loadedKeyPair), afterRemove };
 			},
-			{ persistence, identifier, keyId, keyPair },
+			{ persistence, identifier, keyId, keyPair, pageHelpers },
 		);
 
-		expect(result.loadedPrivKey).toEqual(keyPair.privKey);
-		expect(result.loadedPubKey).toEqual(keyPair.pubKey);
+		expectKeyPair(result.loadedKeyPair, keyPair);
 		expect(result.afterRemove).toBeNull();
 	});
 
 	test("getOmemoPreKeys lists stored pre-keys", async ({
 		page,
+		pageHelpers,
 		persistence,
 	}) => {
 		const identifier = "omemo-prekeys-existing@example.com";
 		const preKeys = [
 			{
 				keyId: 2,
-				privKey: [0, 1, 2],
-				pubKey: [3, 4, 5],
+				keyPair: makeKeyPair(),
 			},
 			{
 				keyId: 3,
-				privKey: [6, 7, 8],
-				pubKey: [9, 10, 11],
+				keyPair: makeKeyPair(),
 			},
 		];
 		const result = await page.evaluate(
-			async ({ persistence, identifier, preKeys }) => {
+			async ({ persistence, identifier, preKeys, pageHelpers }) => {
 				for (const preKey of preKeys) {
-					await persistence.storeOmemoPreKey(identifier, preKey.keyId, {
-						privKey: new Uint8Array(preKey.privKey).buffer,
-						pubKey: new Uint8Array(preKey.pubKey).buffer,
-					});
+					await persistence.storeOmemoPreKey(
+						identifier,
+						preKey.keyId,
+						pageHelpers.keyPairToBuffers(preKey.keyPair),
+					);
 				}
 				const loaded = await persistence.getOmemoPreKeys(identifier);
 				return loaded.map((preKey) => ({
 					keyId: preKey.keyId,
-					privKey: [...new Uint8Array(preKey.keyPair.privKey)],
-					pubKey: [...new Uint8Array(preKey.keyPair.pubKey)],
+					keyPair: pageHelpers.buffersToKeyPair(preKey.keyPair),
 				}));
 			},
-			{ persistence, identifier, preKeys },
+			{ persistence, identifier, preKeys, pageHelpers },
 		);
 
 		expect(result).toEqual(preKeys);
@@ -1689,27 +1671,22 @@ export function sharedPersistenceTests(test: PersistenceTest) {
 
 	test("storeOmemoSignedPreKey and getOmemoSignedPreKey", async ({
 		page,
+		pageHelpers,
 		persistence,
 	}) => {
 		const identifier = "omemo-signed-prekey-existing@example.com";
 		const keyId = 42;
 		const signedPreKey = {
 			keyId,
-			keyPair: {
-				privKey: [0, 1, 2, 127, 128, 255],
-				pubKey: [255, 128, 127, 2, 1, 0],
-			},
-			signature: [9, 8, 7, 6, 5, 4],
+			keyPair: makeKeyPair(),
+			signature: makeKey(),
 		};
 		const result = await page.evaluate(
-			async ({ persistence, identifier, signedPreKey }) => {
+			async ({ persistence, identifier, signedPreKey, pageHelpers }) => {
 				await persistence.storeOmemoSignedPreKey(identifier, {
 					keyId: signedPreKey.keyId,
-					keyPair: {
-						privKey: new Uint8Array(signedPreKey.keyPair.privKey).buffer,
-						pubKey: new Uint8Array(signedPreKey.keyPair.pubKey).buffer,
-					},
-					signature: new Uint8Array(signedPreKey.signature).buffer,
+					keyPair: pageHelpers.keyPairToBuffers(signedPreKey.keyPair),
+					signature: pageHelpers.keyToBuffer(signedPreKey.signature),
 				});
 				const loaded = await persistence.getOmemoSignedPreKey(
 					identifier,
@@ -1718,18 +1695,16 @@ export function sharedPersistenceTests(test: PersistenceTest) {
 
 				return {
 					keyId: loaded.keyId,
-					loadedPrivKey: [...new Uint8Array(loaded.keyPair.privKey)],
-					loadedPubKey: [...new Uint8Array(loaded.keyPair.pubKey)],
-					loadedSignature: [...new Uint8Array(loaded.signature)],
+					keyPair: pageHelpers.buffersToKeyPair(loaded.keyPair),
+					signature: pageHelpers.bufferToKey(loaded.signature),
 				};
 			},
-			{ persistence, identifier, signedPreKey },
+			{ persistence, identifier, signedPreKey, pageHelpers },
 		);
 
 		expect(result.keyId).toBe(keyId);
-		expect(result.loadedPrivKey).toEqual(signedPreKey.keyPair.privKey);
-		expect(result.loadedPubKey).toEqual(signedPreKey.keyPair.pubKey);
-		expect(result.loadedSignature).toEqual(signedPreKey.signature);
+		expectKeyPair(result.keyPair, signedPreKey.keyPair);
+		expectKey(result.signature, signedPreKey.signature);
 	});
 
 	test("getOmemoSignedPreKey returns null when none is stored", async ({
@@ -1766,25 +1741,26 @@ export function sharedPersistenceTests(test: PersistenceTest) {
 
 	test("storeOmemoContactIdentityKey and getOmemoContactIdentityKey", async ({
 		page,
+		pageHelpers,
 		persistence,
 	}) => {
 		const account = "omemo-contact-existing@example.com";
 		const address = "contact@example.com/1";
-		const identityKey = [0, 1, 2, 127, 128, 255];
+		const identityKey = makeKey();
 		const result = await page.evaluate(
-			async ({ persistence, account, address, identityKey }) => {
+			async ({ persistence, account, address, identityKey, pageHelpers }) => {
 				await persistence.storeOmemoContactIdentityKey(
 					account,
 					address,
-					new Uint8Array(identityKey).buffer,
+					pageHelpers.keyToBuffer(identityKey),
 				);
 				const loaded = await persistence.getOmemoContactIdentityKey(
 					account,
 					address,
 				);
-				return [...new Uint8Array(loaded)];
+				return pageHelpers.bufferToKey(loaded);
 			},
-			{ persistence, account, address, identityKey },
+			{ persistence, account, address, identityKey, pageHelpers },
 		);
 
 		expect(result).toEqual(identityKey);
@@ -1832,3 +1808,27 @@ export function sharedPersistenceTests(test: PersistenceTest) {
 		expect(result.afterRemove).toBeNull();
 	});
 }
+
+type TestKeyPair = {
+	privKey: number[];
+	pubKey: number[];
+};
+
+const makeKey = (): number[] => [...randomBytes(32)];
+
+const makeKeyPair = (): TestKeyPair => ({
+	privKey: makeKey(),
+	pubKey: makeKey().reverse(),
+});
+
+function expectKeyPair(
+	actual: TestKeyPair,
+	expected: TestKeyPair,
+) {
+	expectKey(actual.privKey, expected.privKey);
+	expectKey(actual.pubKey, expected.pubKey);
+}
+
+function expectKey(actual: number[], expected: number[]) {
+	expect(actual).toEqual(expected);
+}