You've already forked element-web
mirror of
https://github.com/element-hq/element-web.git
synced 2025-08-09 14:42:51 +03:00
e2e test: Check key backup with js-sdk api instead of relying of Security & Privacy
tab (#29066)
* test(e2e): `checkDeviceIsConnectedKeyBackup` is checking the key backup with the matrix client and the crypto api instead of relying of the `Security & Privacy` tab. * test(e2e): renaming and improve documentation
This commit is contained in:
@@ -68,8 +68,8 @@ test.describe("Device verification", { tag: "@no-webkit" }, () => {
|
|||||||
|
|
||||||
// Check that the current device is connected to key backup
|
// 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,
|
// 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.
|
// as we need to wait for the secret gossiping to happen.
|
||||||
await checkDeviceIsConnectedKeyBackup(page, expectedBackupVersion, false);
|
await checkDeviceIsConnectedKeyBackup(app, expectedBackupVersion, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Verify device with QR code during login", async ({ page, app, credentials, homeserver }) => {
|
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);
|
await checkDeviceIsCrossSigned(app);
|
||||||
|
|
||||||
// Check that the current device is connected to key backup
|
// 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,
|
await checkDeviceIsConnectedKeyBackup(app, expectedBackupVersion, true);
|
||||||
// as we need to wait for the secret gossiping to happen and the settings dialog doesn't refresh automatically.
|
|
||||||
await checkDeviceIsConnectedKeyBackup(page, expectedBackupVersion, false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Verify device with Security Phrase during login", async ({ page, app, credentials, homeserver }) => {
|
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
|
// 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
|
// 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 }) => {
|
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
|
// 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
|
// 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 }) => {
|
test("Handle incoming verification request with SAS", async ({ page, credentials, homeserver, toasts }) => {
|
||||||
|
@@ -139,14 +139,14 @@ export async function checkDeviceIsCrossSigned(app: ElementAppPage): Promise<voi
|
|||||||
* Check that the current device is connected to the expected key backup.
|
* Check that the current device is connected to the expected key backup.
|
||||||
* Also checks that the decryption key is known and cached locally.
|
* Also checks that the decryption key is known and cached locally.
|
||||||
*
|
*
|
||||||
* @param page - the page to check
|
* @param app -` ElementAppPage` wrapper for the playwright `Page`.
|
||||||
* @param expectedBackupVersion - the version of the backup we expect to be connected to.
|
* @param expectedBackupVersion - the version of the backup we expect to be connected to.
|
||||||
* @param checkBackupKeyInCache - whether to check that the backup key is cached locally.
|
* @param checkBackupPrivateKeyInCache - whether to check that the backup decryption key is cached locally
|
||||||
*/
|
*/
|
||||||
export async function checkDeviceIsConnectedKeyBackup(
|
export async function checkDeviceIsConnectedKeyBackup(
|
||||||
page: Page,
|
app: ElementAppPage,
|
||||||
expectedBackupVersion: string,
|
expectedBackupVersion: string,
|
||||||
checkBackupKeyInCache: boolean,
|
checkBackupPrivateKeyInCache: boolean,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// Sanity check the given backup version: if it's null, something went wrong earlier in the test.
|
// Sanity check the given backup version: if it's null, something went wrong earlier in the test.
|
||||||
if (!expectedBackupVersion) {
|
if (!expectedBackupVersion) {
|
||||||
@@ -155,23 +155,48 @@ export async function checkDeviceIsConnectedKeyBackup(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await page.getByRole("button", { name: "User menu" }).click();
|
const backupData = await app.client.evaluate(async (client: MatrixClient) => {
|
||||||
await page.locator(".mx_UserMenu_contextMenu").getByRole("menuitem", { name: "Security & Privacy" }).click();
|
const crypto = client.getCrypto();
|
||||||
await expect(page.locator(".mx_Dialog").getByRole("button", { name: "Restore from Backup" })).toBeVisible();
|
if (!crypto) return;
|
||||||
|
|
||||||
// expand the advanced section to see the active version in the reports
|
const backupInfo = await crypto.getKeyBackupInfo();
|
||||||
await page.locator(".mx_SecureBackupPanel_advanced").locator("..").click();
|
const backupKeyIn4S = Boolean(await client.isKeyBackupKeyStored());
|
||||||
|
const backupPrivateKeyFromCache = await crypto.getSessionBackupPrivateKey();
|
||||||
|
const hasBackupPrivateKeyFromCache = Boolean(backupPrivateKeyFromCache);
|
||||||
|
const backupPrivateKeyWellFormed = backupPrivateKeyFromCache instanceof Uint8Array;
|
||||||
|
const activeBackupVersion = await crypto.getActiveSessionBackupVersion();
|
||||||
|
|
||||||
if (checkBackupKeyInCache) {
|
return {
|
||||||
const cacheDecryptionKeyStatusElement = page.locator(".mx_SecureBackupPanel_statusList tr:nth-child(2) td");
|
backupInfo,
|
||||||
await expect(cacheDecryptionKeyStatusElement).toHaveText("cached locally, well formed");
|
hasBackupPrivateKeyFromCache,
|
||||||
|
backupPrivateKeyWellFormed,
|
||||||
|
backupKeyIn4S,
|
||||||
|
activeBackupVersion,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!backupData) {
|
||||||
|
throw new Error("Crypto module is not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
await expect(page.locator(".mx_SecureBackupPanel_statusList tr:nth-child(5) td")).toHaveText(
|
const { backupInfo, backupKeyIn4S, hasBackupPrivateKeyFromCache, backupPrivateKeyWellFormed, activeBackupVersion } =
|
||||||
expectedBackupVersion + " (Algorithm: m.megolm_backup.v1.curve25519-aes-sha2)",
|
backupData;
|
||||||
);
|
|
||||||
|
|
||||||
await expect(page.locator(".mx_SecureBackupPanel_statusList tr:nth-child(6) td")).toHaveText(expectedBackupVersion);
|
// 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(backupKeyIn4S).toBe(true);
|
||||||
|
|
||||||
|
if (checkBackupPrivateKeyInCache) {
|
||||||
|
// The backup key is available locally
|
||||||
|
expect(hasBackupPrivateKeyFromCache).toBe(true);
|
||||||
|
// The backup key is well-formed
|
||||||
|
expect(backupPrivateKeyWellFormed).toBe(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -51,8 +51,7 @@ test.describe("Recovery section in Encryption tab", () => {
|
|||||||
|
|
||||||
// Check that the current device is connected to key backup
|
// 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
|
// The backup decryption key should be in cache also, as we got it directly from the 4S
|
||||||
await app.closeDialog();
|
await checkDeviceIsConnectedKeyBackup(app, expectedBackupVersion, true);
|
||||||
await checkDeviceIsConnectedKeyBackup(page, expectedBackupVersion, true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test(
|
test(
|
||||||
@@ -119,9 +118,8 @@ test.describe("Recovery section in Encryption tab", () => {
|
|||||||
// The recovery key is now set up and the user can change it
|
// The recovery key is now set up and the user can change it
|
||||||
await expect(dialog.getByRole("button", { name: "Change recovery key" })).toBeVisible();
|
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
|
// 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.
|
// Test what happens if the cross-signing secrets are in secret storage but are not cached in the local DB.
|
||||||
@@ -153,8 +151,7 @@ test.describe("Recovery section in Encryption tab", () => {
|
|||||||
|
|
||||||
// Check that the current device is connected to key backup
|
// 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
|
// The backup decryption key should be in cache also, as we got it directly from the 4S
|
||||||
await app.closeDialog();
|
await checkDeviceIsConnectedKeyBackup(app, expectedBackupVersion, true);
|
||||||
await checkDeviceIsConnectedKeyBackup(page, expectedBackupVersion, true);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user