Hubert Chathi 9ad239f87f
"Verify this device" redesign (#30596)
* add variant of ResetIdentityBody for when the user has no verif. methods

* no longer distinguish between the using having a passphrase or not

* use vertical stack of buttons via EncryptionCard

and update wording

* swap logic order to match rendering order

* use the same dialog when no verification options available

* make it agree with the design more

* allow signing out on initial login

* apply styling changes and remove duplicate elements

* fix and add tests

* add missing snapshot

* Apply suggestions from code review

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* use a boolean property to disable blurring instead of adding a class

* change string identifiers

* apply changes from review -- simplify logic

* change class name to avoid confusion

---------

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
2025-09-12 18:37:14 +00:00

114 lines
3.5 KiB
TypeScript

/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
import { type Page } from "@playwright/test";
import { type GeneratedSecretStorageKey } from "matrix-js-sdk/src/crypto-api";
import { type ElementAppPage } from "../../../pages/ElementAppPage";
import { test as base, expect } from "../../../element-web-test";
export { expect };
/**
* Set up for the encryption tab test
*/
export const test = base.extend<{
util: Helpers;
}>({
displayName: "Alice",
util: async ({ page, app, bot }, use) => {
await use(new Helpers(page, app));
},
});
class Helpers {
constructor(
private page: Page,
private app: ElementAppPage,
) {}
/**
* Open the encryption tab
*/
openEncryptionTab() {
return this.app.settings.openUserSettings("Encryption");
}
/**
* Go through the device verification flow using the recovery key.
*/
async verifyDevice(recoveryKey: GeneratedSecretStorageKey) {
// Select the security phrase
await this.page.getByRole("button", { name: "Use recovery key" }).click();
await this.enterRecoveryKey(recoveryKey);
await this.page.getByRole("button", { name: "Done" }).click();
}
/**
* Fill the recovery key in the dialog
* @param recoveryKey
*/
async enterRecoveryKey(recoveryKey: GeneratedSecretStorageKey) {
// Fill the recovery key
const dialog = this.page.locator(".mx_Dialog");
await dialog.getByRole("textbox").fill(recoveryKey.encodedPrivateKey);
await dialog.getByRole("button", { name: "Continue" }).click();
}
/**
* Get the encryption tab content
*/
getEncryptionTabContent() {
return this.page.getByTestId("encryptionTab");
}
/**
* Get the recovery section
*/
getEncryptionRecoverySection() {
return this.page.getByTestId("recoveryPanel");
}
/**
* Get the encryption details section
*/
getEncryptionDetailsSection() {
return this.page.getByTestId("encryptionDetails");
}
/**
* Set the default key id of the secret storage to `null`
*/
async removeSecretStorageDefaultKeyId() {
const client = await this.app.client.prepareClient();
await client.evaluate(async (client) => {
await client.secretStorage.setDefaultKeyId(null);
});
}
/**
* Get the recovery key from the clipboard and fill in the input field
* Then click on the finish button
* @param title - The title of the dialog
* @param confirmButtonLabel - The label of the confirm button
* @param screenshot
*/
async confirmRecoveryKey(title: string, confirmButtonLabel: string, screenshot: `${string}.png`) {
const dialog = this.getEncryptionTabContent();
await expect(dialog.getByText(title, { exact: true })).toBeVisible();
await expect(dialog).toMatchScreenshot(screenshot);
const clipboardContent = await this.app.getClipboard();
await dialog.getByRole("textbox").fill(clipboardContent);
const button = dialog.getByRole("button", { name: confirmButtonLabel });
await button.click();
// Button should disable immediately after clicking.
await expect(button).toBeDisabled();
await expect(this.getEncryptionRecoverySection()).toMatchScreenshot("default-recovery.png");
}
}