From 890958ef58b20db69b02c90a29ab9ed4edac7700 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 29 Nov 2023 22:46:51 +0000 Subject: [PATCH] Migrate complete-security.spec.ts from Cypress to Playwright (#11952) Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- cypress/e2e/crypto/complete-security.spec.ts | 47 ---------------- .../e2e/crypto/complete-security.spec.ts | 35 ++++++++++++ playwright/e2e/crypto/utils.ts | 54 +++++++++++++++++++ playwright/element-web-test.ts | 15 +++++- 4 files changed, 102 insertions(+), 49 deletions(-) delete mode 100644 cypress/e2e/crypto/complete-security.spec.ts create mode 100644 playwright/e2e/crypto/complete-security.spec.ts create mode 100644 playwright/e2e/crypto/utils.ts diff --git a/cypress/e2e/crypto/complete-security.spec.ts b/cypress/e2e/crypto/complete-security.spec.ts deleted file mode 100644 index eab7fe26e2..0000000000 --- a/cypress/e2e/crypto/complete-security.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright 2023 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import { HomeserverInstance } from "../../plugins/utils/homeserver"; -import { logIntoElement } from "./utils"; - -describe("Complete security", () => { - let homeserver: HomeserverInstance; - - beforeEach(() => { - cy.startHomeserver("default").then((data) => { - homeserver = data; - }); - // visit the login page of the app, to load the matrix sdk - cy.visit("/#/login"); - - // wait for the page to load - cy.window({ log: false }).should("have.property", "matrixcs"); - }); - - afterEach(() => { - cy.stopHomeserver(homeserver); - }); - - it("should go straight to the welcome screen if we have no signed device", () => { - const username = Cypress._.uniqueId("user_"); - const password = "supersecret"; - cy.registerUser(homeserver, username, password, "Jeff"); - logIntoElement(homeserver.baseUrl, username, password); - cy.findByText("Welcome Jeff"); - }); - - // see also "Verify device during login with SAS" in `verifiction.spec.ts`. -}); diff --git a/playwright/e2e/crypto/complete-security.spec.ts b/playwright/e2e/crypto/complete-security.spec.ts new file mode 100644 index 0000000000..f6d58e2fc5 --- /dev/null +++ b/playwright/e2e/crypto/complete-security.spec.ts @@ -0,0 +1,35 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { test, expect } from "../../element-web-test"; +import { logIntoElement } from "./utils"; + +test.describe("Complete security", () => { + test.use({ + displayName: "Jeff", + }); + + test("should go straight to the welcome screen if we have no signed device", async ({ + page, + homeserver, + credentials, + }) => { + await logIntoElement(page, homeserver, credentials); + await expect(page.getByText("Welcome Jeff", { exact: true })).toBeVisible(); + }); + + // see also "Verify device during login with SAS" in `verifiction.spec.ts`. +}); diff --git a/playwright/e2e/crypto/utils.ts b/playwright/e2e/crypto/utils.ts new file mode 100644 index 0000000000..c0120f3957 --- /dev/null +++ b/playwright/e2e/crypto/utils.ts @@ -0,0 +1,54 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { type Page, expect } from "@playwright/test"; + +import { Credentials, HomeserverInstance } from "../../plugins/homeserver"; + +/** + * Fill in the login form in element with the given creds. + * + * If a `securityKey` is given, verifies the new device using the key. + */ +export async function logIntoElement( + page: Page, + homeserver: HomeserverInstance, + credentials: Credentials, + securityKey?: string, +) { + await page.goto("/#/login"); + + // select homeserver + await page.getByRole("button", { name: "Edit" }).click(); + await page.getByRole("textbox", { name: "Other homeserver" }).fill(homeserver.config.baseUrl); + await page.getByRole("button", { name: "Continue" }).click(); + + // wait for the dialog to go away + await expect(page.locator(".mx_ServerPickerDialog")).not.toBeVisible(); + + await page.getByRole("textbox", { name: "Username" }).fill(credentials.userId); + await page.getByPlaceholder("Password").fill(credentials.password); + await page.getByRole("button", { name: "Sign in" }).click(); + + // if a securityKey was given, verify the new device + if (securityKey !== undefined) { + await page.locator(".mx_AuthPage").getByRole("button", { name: "Verify with Security Key" }).click(); + // Fill in the security key + await page.locator(".mx_Dialog").locator('input[type="password"]').fill(securityKey); + await page.locator(".mx_Dialog_primary:not([disabled])", { hasText: "Continue" }).click(); + await page.getByRole("button", { name: "Done" }).click(); + } +} diff --git a/playwright/element-web-test.ts b/playwright/element-web-test.ts index dcc4367b97..2110ad7d10 100644 --- a/playwright/element-web-test.ts +++ b/playwright/element-web-test.ts @@ -50,6 +50,10 @@ export type TestOptions = { cryptoBackend: "legacy" | "rust"; }; +interface CredentialsWithDisplayName extends Credentials { + displayName: string; +} + export const test = base.extend< TestOptions & { axe: AxeBuilder; @@ -60,7 +64,8 @@ export const test = base.extend< startHomeserverOpts: StartHomeserverOpts | string; homeserver: HomeserverInstance; oAuthServer: { port: number }; - user: Credentials; + credentials: CredentialsWithDisplayName; + user: CredentialsWithDisplayName; displayName?: string; app: ElementAppPage; mailhog?: { api: mailhog.API; instance: Instance }; @@ -120,7 +125,7 @@ export const test = base.extend< }, displayName: undefined, - user: async ({ page, homeserver, displayName: testDisplayName }, use) => { + credentials: async ({ homeserver, displayName: testDisplayName }, use) => { const names = ["Alice", "Bob", "Charlie", "Daniel", "Eve", "Frank", "Grace", "Hannah", "Isaac", "Judy"]; const username = _.uniqueId("user_"); const password = _.uniqueId("password_"); @@ -129,6 +134,12 @@ export const test = base.extend< const credentials = await homeserver.registerUser(username, password, displayName); console.log(`Registered test user ${username} with displayname ${displayName}`); + await use({ + ...credentials, + displayName, + }); + }, + user: async ({ page, homeserver, credentials }, use) => { await page.addInitScript( ({ baseUrl, credentials }) => { // Seed the localStorage with the required credentials