From 44c6d1d3f27ae65910f86459c2bd5dc4671c334b Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Wed, 22 Jan 2025 12:14:10 +0100 Subject: [PATCH] test(e2e): `checkDeviceIsConnectedKeyBackup` is checking the key backup with the matrix client and the crypto api instead of relying of the `Security & Privacy` tab. --- .../e2e/crypto/device-verification.spec.ts | 12 ++--- playwright/e2e/crypto/utils.ts | 46 +++++++++++++------ .../encryption-user-tab/recovery.spec.ts | 9 ++-- 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/playwright/e2e/crypto/device-verification.spec.ts b/playwright/e2e/crypto/device-verification.spec.ts index 4091b1e6761..ffa269a0c51 100644 --- a/playwright/e2e/crypto/device-verification.spec.ts +++ b/playwright/e2e/crypto/device-verification.spec.ts @@ -68,8 +68,8 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => { // Check that the current device is connected to key backup // For now we don't check that the backup key is in cache because it's a bit flaky, - // as we need to wait for the secret gossiping to happen and the settings dialog doesn't refresh automatically. - await checkDeviceIsConnectedKeyBackup(page, expectedBackupVersion, false); + // as we need to wait for the secret gossiping to happen. + await checkDeviceIsConnectedKeyBackup(app, expectedBackupVersion, false); }); test("Verify device with QR code during login", async ({ page, app, credentials, homeserver }) => { @@ -112,9 +112,7 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => { await checkDeviceIsCrossSigned(app); // Check that the current device is connected to key backup - // For now we don't check that the backup key is in cache because it's a bit flaky, - // as we need to wait for the secret gossiping to happen and the settings dialog doesn't refresh automatically. - await checkDeviceIsConnectedKeyBackup(page, expectedBackupVersion, false); + await checkDeviceIsConnectedKeyBackup(app, expectedBackupVersion, true); }); test("Verify device with Security Phrase during login", async ({ page, app, credentials, homeserver }) => { @@ -135,7 +133,7 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => { // Check that the current device is connected to key backup // The backup decryption key should be in cache also, as we got it directly from the 4S - await checkDeviceIsConnectedKeyBackup(page, expectedBackupVersion, true); + await checkDeviceIsConnectedKeyBackup(app, expectedBackupVersion, true); }); test("Verify device with Security Key during login", async ({ page, app, credentials, homeserver }) => { @@ -158,7 +156,7 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => { // Check that the current device is connected to key backup // The backup decryption key should be in cache also, as we got it directly from the 4S - await checkDeviceIsConnectedKeyBackup(page, expectedBackupVersion, true); + await checkDeviceIsConnectedKeyBackup(app, expectedBackupVersion, true); }); test("Handle incoming verification request with SAS", async ({ page, credentials, homeserver, toasts }) => { diff --git a/playwright/e2e/crypto/utils.ts b/playwright/e2e/crypto/utils.ts index 7474c5a4354..c1afa49570f 100644 --- a/playwright/e2e/crypto/utils.ts +++ b/playwright/e2e/crypto/utils.ts @@ -139,12 +139,12 @@ export async function checkDeviceIsCrossSigned(app: ElementAppPage): Promise { @@ -155,23 +155,41 @@ export async function checkDeviceIsConnectedKeyBackup( ); } - await page.getByRole("button", { name: "User menu" }).click(); - await page.locator(".mx_UserMenu_contextMenu").getByRole("menuitem", { name: "Security & Privacy" }).click(); - await expect(page.locator(".mx_Dialog").getByRole("button", { name: "Restore from Backup" })).toBeVisible(); + const backupData = await app.client.evaluate(async (client: MatrixClient) => { + const crypto = client.getCrypto(); + if (!crypto) return; - // expand the advanced section to see the active version in the reports - await page.locator(".mx_SecureBackupPanel_advanced").locator("..").click(); + const backupInfo = await crypto.getKeyBackupInfo(); + const backupKeyStored = Boolean(await client.isKeyBackupKeyStored()); + const backupKeyFromCache = await crypto.getSessionBackupPrivateKey(); + const backupKeyCached = Boolean(backupKeyFromCache); + const backupKeyWellFormed = backupKeyFromCache instanceof Uint8Array; + const activeBackupVersion = await crypto.getActiveSessionBackupVersion(); - if (checkBackupKeyInCache) { - const cacheDecryptionKeyStatusElement = page.locator(".mx_SecureBackupPanel_statusList tr:nth-child(2) td"); - await expect(cacheDecryptionKeyStatusElement).toHaveText("cached locally, well formed"); + return { backupInfo, backupKeyStored, backupKeyCached, backupKeyWellFormed, activeBackupVersion }; + }); + + if (!backupData) { + throw new Error("Crypo module is not available"); } - await expect(page.locator(".mx_SecureBackupPanel_statusList tr:nth-child(5) td")).toHaveText( - expectedBackupVersion + " (Algorithm: m.megolm_backup.v1.curve25519-aes-sha2)", - ); + const { backupInfo, backupKeyStored, backupKeyCached, backupKeyWellFormed, activeBackupVersion } = backupData; + + // We have a key backup + expect(backupInfo).toBeDefined(); + // The key backup version is as expected + expect(backupInfo.version).toBe(expectedBackupVersion); + // The active backup version is as expected + expect(activeBackupVersion).toBe(expectedBackupVersion); + // The backup key is stored in 4S + expect(backupKeyStored).toBe(true); - await expect(page.locator(".mx_SecureBackupPanel_statusList tr:nth-child(6) td")).toHaveText(expectedBackupVersion); + if (checkBackupKeyInCache) { + // The backup key is available locally + expect(backupKeyCached).toBe(true); + // The backup key is well-formed + expect(backupKeyWellFormed).toBe(true); + } } /** diff --git a/playwright/e2e/settings/encryption-user-tab/recovery.spec.ts b/playwright/e2e/settings/encryption-user-tab/recovery.spec.ts index 7ce769059a1..b4ed8f6921f 100644 --- a/playwright/e2e/settings/encryption-user-tab/recovery.spec.ts +++ b/playwright/e2e/settings/encryption-user-tab/recovery.spec.ts @@ -47,8 +47,7 @@ test.describe("Recovery section in Encryption tab", () => { // Check that the current device is connected to key backup // The backup decryption key should be in cache also, as we got it directly from the 4S - await app.closeDialog(); - await checkDeviceIsConnectedKeyBackup(page, expectedBackupVersion, true); + await checkDeviceIsConnectedKeyBackup(app, expectedBackupVersion, true); }); test( @@ -115,9 +114,8 @@ test.describe("Recovery section in Encryption tab", () => { // The recovery key is now set up and the user can change it await expect(dialog.getByRole("button", { name: "Change recovery key" })).toBeVisible(); - await app.closeDialog(); // Check that the current device is connected to key backup and the backup version is the expected one - await checkDeviceIsConnectedKeyBackup(page, "1", true); + await checkDeviceIsConnectedKeyBackup(app, "1", true); }); // Test what happens if the cross-signing secrets are in secret storage but are not cached in the local DB. @@ -149,8 +147,7 @@ test.describe("Recovery section in Encryption tab", () => { // Check that the current device is connected to key backup // The backup decryption key should be in cache also, as we got it directly from the 4S - await app.closeDialog(); - await checkDeviceIsConnectedKeyBackup(page, expectedBackupVersion, true); + await checkDeviceIsConnectedKeyBackup(app, expectedBackupVersion, true); }, ); });