diff --git a/apps/web/playwright/e2e/accessibility/keyboard-navigation.spec.ts b/apps/web/playwright/e2e/accessibility/keyboard-navigation.spec.ts index b2eadb1b6a..8c7f04ccf2 100644 --- a/apps/web/playwright/e2e/accessibility/keyboard-navigation.spec.ts +++ b/apps/web/playwright/e2e/accessibility/keyboard-navigation.spec.ts @@ -14,8 +14,8 @@ test.describe("Landmark navigation tests", () => { displayName: "Alice", }); - test("without any rooms", async ({ page, homeserver, app, user }) => { - await app.closeVerifyToast(); + test("without any rooms", async ({ page, homeserver, app, user, toasts }) => { + await toasts.rejectToast("Verify this device"); // sometimes the space button doesn't appear right away await expect(page.locator(".mx_SpaceButton_active")).toBeVisible(); diff --git a/apps/web/playwright/e2e/audio-player/audio-player.spec.ts b/apps/web/playwright/e2e/audio-player/audio-player.spec.ts index a87e7c0a88..3e899b135e 100644 --- a/apps/web/playwright/e2e/audio-player/audio-player.spec.ts +++ b/apps/web/playwright/e2e/audio-player/audio-player.spec.ts @@ -143,8 +143,8 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => { await expect(page).toMatchScreenshot(`${detail.replaceAll(" ", "-")}-bubble-layout.png`, screenshotOptions); }; - test.beforeEach(async ({ page, app, user }) => { - await app.closeVerifyToast(); + test.beforeEach(async ({ page, app, user, toasts }) => { + await toasts.rejectToast("Verify this device"); await app.client.createRoom({ name: "Test Room" }); await app.viewRoomByName("Test Room"); diff --git a/apps/web/playwright/e2e/crypto/crypto.spec.ts b/apps/web/playwright/e2e/crypto/crypto.spec.ts index 05f400cfd9..e9716d72c7 100644 --- a/apps/web/playwright/e2e/crypto/crypto.spec.ts +++ b/apps/web/playwright/e2e/crypto/crypto.spec.ts @@ -168,8 +168,8 @@ test.describe("Cryptography", function () { test( "creating a DM should work, being e2e-encrypted / user verification", { tag: "@screenshot" }, - async ({ page, app, bot: bob, user: aliceCredentials }) => { - await app.closeVerifyToast(); + async ({ page, app, bot: bob, user: aliceCredentials, toasts }) => { + await toasts.rejectToast("Verify this device"); await app.client.bootstrapCrossSigning(aliceCredentials); await startDMWithBob(page, bob); // send first message diff --git a/apps/web/playwright/e2e/crypto/history-sharing.spec.ts b/apps/web/playwright/e2e/crypto/history-sharing.spec.ts index 336b4df567..77f3d9f0d4 100644 --- a/apps/web/playwright/e2e/crypto/history-sharing.spec.ts +++ b/apps/web/playwright/e2e/crypto/history-sharing.spec.ts @@ -29,16 +29,16 @@ test.describe("History sharing", function () { // we then invite Bob, and ensure Bob can see the content. await aliceElementApp.client.bootstrapCrossSigning(aliceCredentials); - await aliceElementApp.closeKeyStorageToast(); + await aliceElementApp.toasts.rejectKeyStorageToast(); // Register a second user, and open it in a second instance of the app const bobCredentials = await homeserver.registerUser(`user_${testInfo.testId}_bob`, "password", "Bob"); const bobPage = await createNewInstance(browser, bobCredentials, {}, labsFlags); const bobElementApp = new ElementAppPage(bobPage); await bobElementApp.client.bootstrapCrossSigning(bobCredentials); - await bobElementApp.closeKeyStorageToast(); + await bobElementApp.toasts.rejectKeyStorageToast(); - await aliceElementApp.closeNotificationToast(); + await aliceElementApp.toasts.rejectToast("Notifications"); // Create the room and send a message await createRoom(alicePage, "TestRoom", true); @@ -89,7 +89,7 @@ test.describe("History sharing", function () { // 5. Charlie can't see the message. await aliceElementApp.client.bootstrapCrossSigning(aliceCredentials); - await aliceElementApp.closeKeyStorageToast(); + await aliceElementApp.toasts.rejectKeyStorageToast(); await createRoom(alicePage, "TestRoom", true); // Register a second user, and open it in a second instance of the app @@ -97,7 +97,7 @@ test.describe("History sharing", function () { const bobPage = await createNewInstance(browser, bobCredentials, {}, labsFlags); const bobElementApp = new ElementAppPage(bobPage); await bobElementApp.client.bootstrapCrossSigning(bobCredentials); - await bobElementApp.closeKeyStorageToast(); + await bobElementApp.toasts.rejectKeyStorageToast(); // ... and a third const charlieCredentials = await homeserver.registerUser( @@ -108,7 +108,7 @@ test.describe("History sharing", function () { const charliePage = await createNewInstance(browser, charlieCredentials, {}, labsFlags); const charlieElementApp = new ElementAppPage(charliePage); await charlieElementApp.client.bootstrapCrossSigning(charlieCredentials); - await charlieElementApp.closeKeyStorageToast(); + await charlieElementApp.toasts.rejectKeyStorageToast(); // Alice invites Bob, and Bob accepts const roomId = await aliceElementApp.getCurrentRoomIdFromUrl(); diff --git a/apps/web/playwright/e2e/invite/invite-dialog.spec.ts b/apps/web/playwright/e2e/invite/invite-dialog.spec.ts index 93873587f5..a7e5c373ca 100644 --- a/apps/web/playwright/e2e/invite/invite-dialog.spec.ts +++ b/apps/web/playwright/e2e/invite/invite-dialog.spec.ts @@ -72,8 +72,8 @@ test.describe("Invite dialog", function () { test( "should support inviting a user to Direct Messages", { tag: "@screenshot" }, - async ({ page, app, user, bot }) => { - await app.closeVerifyToast(); + async ({ page, app, user, bot, toasts }) => { + await toasts.rejectToast("Verify this device"); await page .getByRole("navigation", { name: "Room list" }) .getByRole("button", { name: "New conversation" }) diff --git a/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-collapse.spec.ts b/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-collapse.spec.ts index 73a670ee9f..2800111c42 100644 --- a/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-collapse.spec.ts +++ b/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-collapse.spec.ts @@ -13,9 +13,9 @@ test.describe("Collapsible Room list", () => { displayName: "Alice", }); - test.beforeEach(async ({ page, app, user }) => { - await app.closeVerifyToast(); - await app.closeNotificationToast(); + test.beforeEach(async ({ page, app, user, toasts }) => { + await toasts.rejectToast("Verify this device"); + await toasts.rejectToast("Notifications"); for (let i = 0; i < 10; i++) { await app.client.createRoom({ name: `room${i}` }); } diff --git a/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-filter-sort.spec.ts b/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-filter-sort.spec.ts index 94a41baa03..d7536ad2fa 100644 --- a/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-filter-sort.spec.ts +++ b/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-filter-sort.spec.ts @@ -45,10 +45,10 @@ test.describe("Room list filters and sort", () => { return page.getByTestId("room-list"); } - test.beforeEach(async ({ page, app, bot, user }) => { + test.beforeEach(async ({ page, app, bot, user, toasts }) => { // The toasts are displayed above the search section - await app.closeVerifyToast(); - await app.closeNotificationToast(); + await toasts.rejectToast("Verify this device"); + await toasts.rejectToast("Notifications"); }); test("Tombstoned rooms are not shown even when they receive updates", async ({ page, app, bot }) => { diff --git a/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-header.spec.ts b/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-header.spec.ts index 8a29839ad2..880953e6c9 100644 --- a/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-header.spec.ts +++ b/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-header.spec.ts @@ -21,10 +21,10 @@ test.describe("Header section of the room list", () => { return page.getByTestId("room-list-header"); } - test.beforeEach(async ({ page, app, user }) => { + test.beforeEach(async ({ page, app, user, toasts }) => { // The toasts are displayed above the search section - await app.closeVerifyToast(); - await app.closeNotificationToast(); + await toasts.rejectToast("Verify this device"); + await toasts.rejectToast("Notifications"); }); test("should render the header section", { tag: "@screenshot" }, async ({ page, app, user }) => { diff --git a/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-panel.spec.ts b/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-panel.spec.ts index 5da11b7167..031aaf51e2 100644 --- a/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-panel.spec.ts +++ b/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-panel.spec.ts @@ -22,10 +22,10 @@ test.describe("Room list panel", () => { return page.getByRole("navigation", { name: "Room list" }); } - test.beforeEach(async ({ page, app, user }) => { + test.beforeEach(async ({ page, app, user, toasts }) => { // The toasts are displayed above the search section - await app.closeVerifyToast(); - await app.closeNotificationToast(); + await toasts.rejectToast("Verify this device"); + await toasts.rejectToast("Notifications"); // Populate the room list for (let i = 0; i < 20; i++) { diff --git a/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-search.spec.ts b/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-search.spec.ts index c6a5824924..8944bdb70b 100644 --- a/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-search.spec.ts +++ b/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-search.spec.ts @@ -22,10 +22,10 @@ test.describe("Search section of the room list", () => { return page.getByRole("search"); } - test.beforeEach(async ({ page, app, user }) => { + test.beforeEach(async ({ page, app, user, toasts }) => { // The toasts are displayed above the search section - await app.closeVerifyToast(); - await app.closeNotificationToast(); + await toasts.rejectToast("Verify this device"); + await toasts.rejectToast("Notifications"); }); test("should render the search section", { tag: "@screenshot" }, async ({ page, app, user }) => { diff --git a/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-sections.spec.ts b/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-sections.spec.ts index f997a99c71..123f1bba91 100644 --- a/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-sections.spec.ts +++ b/apps/web/playwright/e2e/left-panel/room-list-panel/room-list-sections.spec.ts @@ -44,10 +44,10 @@ test.describe("Room list sections", () => { return getRoomList(page).getByRole("gridcell", { name: `Toggle ${sectionName} section` }); } - test.beforeEach(async ({ page, app, user }) => { + test.beforeEach(async ({ page, app, user, toasts }) => { // The toasts are displayed above the search section - await app.closeVerifyToast(); - await app.closeNotificationToast(); + await toasts.rejectToast("Verify this device"); + await toasts.rejectToast("Notifications"); // focus the user menu to avoid to have hover decoration await page.getByRole("button", { name: "User menu" }).focus(); diff --git a/apps/web/playwright/e2e/left-panel/room-list-panel/room-list.spec.ts b/apps/web/playwright/e2e/left-panel/room-list-panel/room-list.spec.ts index 84d9039b4f..54a9eeacb8 100644 --- a/apps/web/playwright/e2e/left-panel/room-list-panel/room-list.spec.ts +++ b/apps/web/playwright/e2e/left-panel/room-list-panel/room-list.spec.ts @@ -28,10 +28,10 @@ test.describe("Room list", () => { return page.getByTestId("room-list"); } - test.beforeEach(async ({ page, app, user }) => { + test.beforeEach(async ({ page, app, user, toasts }) => { // The toasts are displayed above the search section - await app.closeVerifyToast(); - await app.closeNotificationToast(); + await toasts.rejectToast("Verify this device"); + await toasts.rejectToast("Notifications"); // focus the user menu to avoid to have hover decoration await page.getByRole("button", { name: "User menu" }).focus(); diff --git a/apps/web/playwright/e2e/messages/messages.spec.ts b/apps/web/playwright/e2e/messages/messages.spec.ts index 6dc45b8e65..9402a1fdc5 100644 --- a/apps/web/playwright/e2e/messages/messages.spec.ts +++ b/apps/web/playwright/e2e/messages/messages.spec.ts @@ -85,10 +85,10 @@ test.describe("Message rendering", () => { test.describe(`with ${direction} display name`, { tag: "@screenshot" }, () => { test.use({ displayName, - room: async ({ user, app }, use) => { + room: async ({ user, app, toasts }, use) => { const roomId = await app.client.createRoom({ name: "Test room" }); await use({ roomId }); - await app.closeVerifyToast(); + await toasts.rejectToast("Verify this device"); }, }); @@ -216,10 +216,10 @@ test.describe("Message rendering", () => { test.describe("Message url previews", () => { test.use({ displayName: "Alice", - room: async ({ user, app }, use) => { + room: async ({ user, app, toasts }, use) => { const roomId = await app.client.createRoom({ name: "Test room" }); await use({ roomId }); - await app.closeVerifyToast(); + await toasts.rejectToast("Verify this device"); }, }); test("should render a basic preview", { tag: "@screenshot" }, async ({ page, user, app, room, axe }) => { diff --git a/apps/web/playwright/e2e/room-directory/room-directory.spec.ts b/apps/web/playwright/e2e/room-directory/room-directory.spec.ts index 8725533e38..be5508d500 100644 --- a/apps/web/playwright/e2e/room-directory/room-directory.spec.ts +++ b/apps/web/playwright/e2e/room-directory/room-directory.spec.ts @@ -57,7 +57,7 @@ test.describe("Room Directory", () => { test( "should allow finding published rooms in directory", { tag: "@screenshot" }, - async ({ page, app, user, bot }) => { + async ({ page, app, user, bot, toasts }) => { const name = "This is a public room"; await bot.createRoom({ visibility: "public" as Visibility, @@ -65,7 +65,7 @@ test.describe("Room Directory", () => { room_alias_name: "test1234", }); - await app.closeVerifyToast(); + await toasts.rejectToast("Verify this device"); await page.getByRole("button", { name: "Explore rooms" }).click(); const dialog = page.locator(".mx_SpotlightDialog"); diff --git a/apps/web/playwright/e2e/room/create-room.spec.ts b/apps/web/playwright/e2e/room/create-room.spec.ts index f3d7f9425d..89282e5c04 100644 --- a/apps/web/playwright/e2e/room/create-room.spec.ts +++ b/apps/web/playwright/e2e/room/create-room.spec.ts @@ -21,8 +21,8 @@ test.describe("Create Room", () => { test( "should create a public room with name, topic & address set", { tag: "@screenshot" }, - async ({ page, user, app, axe }) => { - await app.closeVerifyToast(); + async ({ page, user, app, axe, toasts }) => { + await toasts.rejectToast("Verify this device"); const dialog = await app.openCreateRoomDialog(); // Fill name & topic await dialog.getByRole("textbox", { name: "Name" }).fill(name); @@ -50,8 +50,8 @@ test.describe("Create Room", () => { }, ); - test("should allow us to start a chat and show encryption state", async ({ page, user, app }) => { - await app.closeVerifyToast(); + test("should allow us to start a chat and show encryption state", async ({ page, user, app, toasts }) => { + await toasts.rejectToast("Verify this device"); await page.getByRole("button", { name: "New conversation", exact: true }).click(); await page.getByRole("menuitem", { name: "Start chat" }).click(); @@ -67,9 +67,9 @@ test.describe("Create Room", () => { await expect(composer.getByRole("textbox", { name: "Send a message…" })).toBeVisible(); }); - test("should create a video room", { tag: "@screenshot" }, async ({ page, user, app }) => { + test("should create a video room", { tag: "@screenshot" }, async ({ page, user, app, toasts }) => { await app.settings.setValue("feature_video_rooms", null, SettingLevel.DEVICE, true); - await app.closeVerifyToast(); + await toasts.rejectToast("Verify this device"); const dialog = await app.openCreateRoomDialog("New video room"); // Fill name & topic @@ -103,56 +103,64 @@ test.describe("Create Room", () => { }, }); - test("should disallow creating public rooms", { tag: "@screenshot" }, async ({ page, user, app, axe }) => { - await app.closeVerifyToast(); - const dialog = await app.openCreateRoomDialog(); - // Fill name & topic - await dialog.getByRole("textbox", { name: "Name" }).fill(name); - await dialog.getByRole("textbox", { name: "Topic" }).fill(topic); + test( + "should disallow creating public rooms", + { tag: "@screenshot" }, + async ({ page, user, app, axe, toasts }) => { + await toasts.rejectToast("Verify this device"); + const dialog = await app.openCreateRoomDialog(); + // Fill name & topic + await dialog.getByRole("textbox", { name: "Name" }).fill(name); + await dialog.getByRole("textbox", { name: "Topic" }).fill(topic); - axe.disableRules("color-contrast"); // XXX: Inheriting colour contrast issues from room view. - await expect(axe).toHaveNoViolations(); - // Snapshot it - // Mask topic to avoid flakiness with top border - await expect(dialog).toMatchScreenshot("create-room-no-public.png", { - mask: [dialog.locator(".mx_CreateRoomDialog_topic")], - }); + axe.disableRules("color-contrast"); // XXX: Inheriting colour contrast issues from room view. + await expect(axe).toHaveNoViolations(); + // Snapshot it + // Mask topic to avoid flakiness with top border + await expect(dialog).toMatchScreenshot("create-room-no-public.png", { + mask: [dialog.locator(".mx_CreateRoomDialog_topic")], + }); - // Submit - await dialog.getByRole("button", { name: "Create room" }).click(); + // Submit + await dialog.getByRole("button", { name: "Create room" }).click(); - await expect(page).toHaveURL(new RegExp(`/#/room/!.+`)); - const header = page.locator(".mx_RoomHeader"); - await expect(header).toContainText(name); - }); + await expect(page).toHaveURL(new RegExp(`/#/room/!.+`)); + const header = page.locator(".mx_RoomHeader"); + await expect(header).toContainText(name); + }, + ); }); test.describe("when the encrypted state labs flag is turned off", () => { test.use({ labsFlags: [] }); - test("creates a room without encrypted state", { tag: "@screenshot" }, async ({ page, user: _user, app }) => { - await app.closeVerifyToast(); + test( + "creates a room without encrypted state", + { tag: "@screenshot" }, + async ({ page, user: _user, app, toasts }) => { + await toasts.rejectToast("Verify this device"); - // When we start to create a room - await page.getByRole("button", { name: "New conversation", exact: true }).click(); - await page.getByRole("menuitem", { name: "New room" }).click(); - await page.getByRole("textbox", { name: "Name" }).fill(name); + // When we start to create a room + await page.getByRole("button", { name: "New conversation", exact: true }).click(); + await page.getByRole("menuitem", { name: "New room" }).click(); + await page.getByRole("textbox", { name: "Name" }).fill(name); - // Then there is no Encrypt state events button - await expect(page.getByRole("checkbox", { name: "Encrypt state events" })).not.toBeVisible(); + // Then there is no Encrypt state events button + await expect(page.getByRole("checkbox", { name: "Encrypt state events" })).not.toBeVisible(); - // And when we create the room - await page.getByRole("button", { name: "Create room" }).click(); + // And when we create the room + await page.getByRole("button", { name: "Create room" }).click(); - // Then we created a normal encrypted room, without encrypted state - await expect(page.getByText("Encryption enabled")).toBeVisible(); - await expect(page.getByText("State encryption enabled")).not.toBeVisible(); + // Then we created a normal encrypted room, without encrypted state + await expect(page.getByText("Encryption enabled")).toBeVisible(); + await expect(page.getByText("State encryption enabled")).not.toBeVisible(); - // And the room name state event is not encrypted - await viewSourceOnRoomNameEvent(page); - await expect(page.getByText("Original event source")).toBeVisible(); - await expect(page.getByText("Decrypted event source")).not.toBeVisible(); - }); + // And the room name state event is not encrypted + await viewSourceOnRoomNameEvent(page); + await expect(page.getByText("Original event source")).toBeVisible(); + await expect(page.getByText("Decrypted event source")).not.toBeVisible(); + }, + ); }); test.describe("when the encrypted state labs flag is turned on", () => { @@ -161,8 +169,8 @@ test.describe("Create Room", () => { test( "creates a room with encrypted state if we check the box", { tag: "@screenshot" }, - async ({ page, user: _user, app }) => { - await app.closeVerifyToast(); + async ({ page, user: _user, app, toasts }) => { + await toasts.rejectToast("Verify this device"); // Given we check the Encrypted State checkbox await page.getByRole("button", { name: "New conversation", exact: true }).click(); @@ -190,8 +198,8 @@ test.describe("Create Room", () => { test( "creates a room without encrypted state if we don't check the box", { tag: "@screenshot" }, - async ({ page, user: _user, app }) => { - await app.closeVerifyToast(); + async ({ page, user: _user, app, toasts }) => { + await toasts.rejectToast("Verify this device"); // Given we did not check the Encrypted State checkbox await page.getByRole("button", { name: "New conversation", exact: true }).click(); diff --git a/apps/web/playwright/e2e/room/room-status-bar.spec.ts b/apps/web/playwright/e2e/room/room-status-bar.spec.ts index 070feeffe2..faef08b1d8 100644 --- a/apps/web/playwright/e2e/room/room-status-bar.spec.ts +++ b/apps/web/playwright/e2e/room/room-status-bar.spec.ts @@ -15,12 +15,12 @@ test.describe("Room Status Bar", () => { await page.setViewportSize({ width: 1400, height: 768 }); await use(page); }, - room: async ({ app, user }, use) => { + room: async ({ app, user, toasts }, use) => { const roomId = await app.client.createRoom({ name: "A room", }); - await app.closeVerifyToast(); - await app.closeNotificationToast(); + await toasts.rejectToast("Verify this device"); + await toasts.rejectToast("Notifications"); await app.viewRoomById(roomId); await use({ roomId }); }, @@ -139,8 +139,8 @@ test.describe("Room Status Bar", () => { test( "should show an error when creating a local room fails", { tag: "@screenshot" }, - async ({ page, app, user, bot }) => { - await app.closeVerifyToast(); + async ({ page, app, user, bot, toasts }) => { + await toasts.rejectToast("Verify this device"); await page .getByRole("navigation", { name: "Room list" }) .getByRole("button", { name: "New conversation" }) diff --git a/apps/web/playwright/e2e/settings/appearance-user-settings-tab/appearance-user-settings-tab.spec.ts b/apps/web/playwright/e2e/settings/appearance-user-settings-tab/appearance-user-settings-tab.spec.ts index b742d003d9..360cdea9e7 100644 --- a/apps/web/playwright/e2e/settings/appearance-user-settings-tab/appearance-user-settings-tab.spec.ts +++ b/apps/web/playwright/e2e/settings/appearance-user-settings-tab/appearance-user-settings-tab.spec.ts @@ -13,8 +13,8 @@ test.describe("Appearance user settings tab", () => { displayName: "Hanako", }); - test("should be rendered properly", { tag: "@screenshot" }, async ({ page, user, app }) => { - await app.closeVerifyToast(); + test("should be rendered properly", { tag: "@screenshot" }, async ({ page, user, app, toasts }) => { + await toasts.rejectToast("Verify this device"); const tab = await app.settings.openUserSettings("Appearance"); // Click "Show advanced" link button @@ -29,8 +29,8 @@ test.describe("Appearance user settings tab", () => { test( "should support changing font size by using the font size dropdown", { tag: "@screenshot" }, - async ({ page, app, user }) => { - await app.closeVerifyToast(); + async ({ page, app, user, toasts }) => { + await toasts.rejectToast("Verify this device"); await app.settings.openUserSettings("Appearance"); const tab = page.getByTestId("mx_AppearanceUserSettingsTab"); @@ -45,8 +45,8 @@ test.describe("Appearance user settings tab", () => { }, ); - test("should support enabling system font", async ({ page, app, user }) => { - await app.closeVerifyToast(); + test("should support enabling system font", async ({ page, app, user, toasts }) => { + await toasts.rejectToast("Verify this device"); await app.settings.openUserSettings("Appearance"); const tab = page.getByTestId("mx_AppearanceUserSettingsTab"); @@ -63,8 +63,8 @@ test.describe("Appearance user settings tab", () => { test( "should keep same font and emoji when switching theme", { tag: "@screenshot" }, - async ({ page, app, user, util }) => { - await app.closeVerifyToast(); + async ({ page, app, user, util, toasts }) => { + await toasts.rejectToast("Verify this device"); const roomId = await util.createAndDisplayRoom(); diff --git a/apps/web/playwright/e2e/settings/appearance-user-settings-tab/theme-choice-panel.spec.ts b/apps/web/playwright/e2e/settings/appearance-user-settings-tab/theme-choice-panel.spec.ts index 7b48f63acb..255b193907 100644 --- a/apps/web/playwright/e2e/settings/appearance-user-settings-tab/theme-choice-panel.spec.ts +++ b/apps/web/playwright/e2e/settings/appearance-user-settings-tab/theme-choice-panel.spec.ts @@ -14,10 +14,10 @@ test.describe("Appearance user settings tab", () => { }); test.describe("Theme Choice Panel", () => { - test.beforeEach(async ({ app, user, util }) => { + test.beforeEach(async ({ app, user, util, toasts }) => { // Disable the default theme for consistency in case ThemeWatcher automatically chooses it await util.disableSystemTheme(); - await app.closeVerifyToast(); + await toasts.rejectToast("Verify this device"); await util.openAppearanceTab(); }); @@ -94,7 +94,7 @@ test.describe("Appearance user settings tab", () => { test( "should keep custom theme when reloading the page", { tag: "@screenshot" }, - async ({ page, app, user, util }) => { + async ({ page, app, user, util, toasts }) => { await util.addCustomTheme(); await util.getCustomTheme().click(); await util.closeAppearanceTab(); @@ -102,7 +102,7 @@ test.describe("Appearance user settings tab", () => { await expect(page).toMatchScreenshot("window-custom-theme.png"); await page.reload(); - await app.closeVerifyToast(); + await toasts.rejectToast("Verify this device"); await util.openAppearanceTab(); // Assert that the custom theme is still selected after reloading the page diff --git a/apps/web/playwright/e2e/settings/encryption-user-tab/other-devices.spec.ts b/apps/web/playwright/e2e/settings/encryption-user-tab/other-devices.spec.ts index ea921f2225..ebce9c864e 100644 --- a/apps/web/playwright/e2e/settings/encryption-user-tab/other-devices.spec.ts +++ b/apps/web/playwright/e2e/settings/encryption-user-tab/other-devices.spec.ts @@ -24,14 +24,14 @@ test.describe("Other people's devices section in Encryption tab", () => { user: aliceCredentials, }, testInfo) => { await aliceElementApp.client.bootstrapCrossSigning(aliceCredentials); - await aliceElementApp.closeKeyStorageToast(); + await aliceElementApp.toasts.rejectKeyStorageToast(); // Create a second browser instance. const bobCredentials = await homeserver.registerUser(`user_${testInfo.testId}_bob`, "password", "bob"); const bobPage = await createNewInstance(browser, bobCredentials, {}); const bobElementApp = new ElementAppPage(bobPage); await bobElementApp.client.bootstrapCrossSigning(bobCredentials); - await bobElementApp.closeKeyStorageToast(); + await bobElementApp.toasts.rejectKeyStorageToast(); // Create the room and invite bob await createRoom(alicePage, "TestRoom", true); @@ -55,7 +55,7 @@ test.describe("Other people's devices section in Encryption tab", () => { util, }, testInfo) => { await aliceElementApp.client.bootstrapCrossSigning(aliceCredentials); - await aliceElementApp.closeKeyStorageToast(); + await aliceElementApp.toasts.rejectKeyStorageToast(); // Enable blacklist toggle. const dialog = await util.openEncryptionTab(); @@ -72,7 +72,7 @@ test.describe("Other people's devices section in Encryption tab", () => { const bobPage = await createNewInstance(browser, bobCredentials, {}); const bobElementApp = new ElementAppPage(bobPage); await bobElementApp.client.bootstrapCrossSigning(bobCredentials); - await bobElementApp.closeKeyStorageToast(); + await bobElementApp.toasts.rejectKeyStorageToast(); // Create the room and invite bob await createRoom(alicePage, "TestRoom", true); @@ -100,7 +100,7 @@ test.describe("Other people's devices section in Encryption tab", () => { util, }, testInfo) => { await aliceElementApp.client.bootstrapCrossSigning(aliceCredentials); - await aliceElementApp.closeKeyStorageToast(); + await aliceElementApp.toasts.rejectKeyStorageToast(); // Enable blacklist toggle. const dialog = await util.openEncryptionTab(); @@ -117,7 +117,7 @@ test.describe("Other people's devices section in Encryption tab", () => { const bobPage = await createNewInstance(browser, bobCredentials, {}); const bobElementApp = new ElementAppPage(bobPage); await bobElementApp.client.bootstrapCrossSigning(bobCredentials); - await bobElementApp.closeKeyStorageToast(); + await bobElementApp.toasts.rejectKeyStorageToast(); // Create the room and invite bob await createRoom(alicePage, "TestRoom", true); @@ -126,7 +126,7 @@ test.describe("Other people's devices section in Encryption tab", () => { // Bob accepts the invite and dismisses the warnings. await bobPage.getByRole("option", { name: "TestRoom" }).click(); await bobPage.getByRole("button", { name: "Accept" }).click(); - await bobElementApp.closeNotificationToast(); + await bobElementApp.toasts.rejectToast("Notifications"); // Perform verification. await verifyApp("alice", aliceElementApp, "bob", bobElementApp); @@ -144,14 +144,14 @@ test.describe("Other people's devices section in Encryption tab", () => { user: aliceCredentials, }, testInfo) => { await aliceElementApp.client.bootstrapCrossSigning(aliceCredentials); - await aliceElementApp.closeKeyStorageToast(); + await aliceElementApp.toasts.rejectKeyStorageToast(); // Create a second browser instance. const bobCredentials = await homeserver.registerUser(`user_${testInfo.testId}_bob`, "password", "bob"); const bobPage = await createNewInstance(browser, bobCredentials, {}); const bobElementApp = new ElementAppPage(bobPage); await bobElementApp.client.bootstrapCrossSigning(bobCredentials); - await bobElementApp.closeKeyStorageToast(); + await bobElementApp.toasts.rejectKeyStorageToast(); // Alice creates the room and invite Bob. await createRoom(alicePage, "TestRoom", true); @@ -197,7 +197,7 @@ test.describe("Other people's devices section in Encryption tab", () => { util, }, testInfo) => { await aliceElementApp.client.bootstrapCrossSigning(aliceCredentials); - await aliceElementApp.closeKeyStorageToast(); + await aliceElementApp.toasts.rejectKeyStorageToast(); // Enable blacklist toggle. let dialog = await util.openEncryptionTab(); @@ -214,7 +214,7 @@ test.describe("Other people's devices section in Encryption tab", () => { const bobPage = await createNewInstance(browser, bobCredentials, {}); const bobElementApp = new ElementAppPage(bobPage); await bobElementApp.client.bootstrapCrossSigning(bobCredentials); - await bobElementApp.closeKeyStorageToast(); + await bobElementApp.toasts.rejectKeyStorageToast(); // Alice creates the room and invite Bob. await createRoom(alicePage, "TestRoom", true); diff --git a/apps/web/playwright/e2e/settings/security-user-settings-tab.spec.ts b/apps/web/playwright/e2e/settings/security-user-settings-tab.spec.ts index 7506ac9e14..c004185588 100644 --- a/apps/web/playwright/e2e/settings/security-user-settings-tab.spec.ts +++ b/apps/web/playwright/e2e/settings/security-user-settings-tab.spec.ts @@ -25,10 +25,10 @@ test.describe("Security user settings tab", () => { }, }); - test.beforeEach(async ({ page, app, user }) => { + test.beforeEach(async ({ page, app, user, toasts }) => { // Dismiss toasts - await app.closeVerifyToast(); - await app.closeNotificationToast(); + await toasts.rejectToast("Verify this device"); + await toasts.rejectToast("Notifications"); await page.locator(".mx_Toast_buttons").getByRole("button", { name: "Yes" }).click(); // Allow analytics }); diff --git a/apps/web/playwright/e2e/sliding-sync/sliding-sync.spec.ts b/apps/web/playwright/e2e/sliding-sync/sliding-sync.spec.ts index 108f0520b3..e70a7d3767 100644 --- a/apps/web/playwright/e2e/sliding-sync/sliding-sync.spec.ts +++ b/apps/web/playwright/e2e/sliding-sync/sliding-sync.spec.ts @@ -71,9 +71,9 @@ test.describe("Sliding Sync", () => { }); // Load the user fixture for all tests - test.beforeEach(async ({ app, user }) => { - await app.closeVerifyToast(); - await app.closeNotificationToast(); + test.beforeEach(async ({ app, user, toasts }) => { + await toasts.rejectToast("Verify this device"); + await toasts.rejectToast("Notifications"); }); test("should render the Rooms list in reverse chronological order by default and allowing sorting A-Z", async ({ diff --git a/apps/web/playwright/e2e/spaces/spaces.spec.ts b/apps/web/playwright/e2e/spaces/spaces.spec.ts index 173130fd29..a5e1e06db3 100644 --- a/apps/web/playwright/e2e/spaces/spaces.spec.ts +++ b/apps/web/playwright/e2e/spaces/spaces.spec.ts @@ -67,8 +67,8 @@ test.describe("Spaces", () => { test( "should allow user to create public space", { tag: ["@screenshot", "@no-webkit"] }, - async ({ page, app, user }) => { - await app.closeVerifyToast(); + async ({ page, app, user, toasts }) => { + await toasts.rejectToast("Verify this device"); const contextMenu = await openSpaceCreateMenu(page); await expect(contextMenu).toMatchScreenshot("space-create-menu.png"); @@ -104,8 +104,8 @@ test.describe("Spaces", () => { }, ); - test("should allow user to create private space", { tag: "@screenshot" }, async ({ page, app, user }) => { - await app.closeVerifyToast(); + test("should allow user to create private space", { tag: "@screenshot" }, async ({ page, app, user, toasts }) => { + await toasts.rejectToast("Verify this device"); const menu = await openSpaceCreateMenu(page); await menu.getByRole("button", { name: "Private" }).click(); @@ -147,12 +147,12 @@ test.describe("Spaces", () => { ).toBeVisible(); }); - test("should allow user to create just-me space", async ({ page, app, user }) => { + test("should allow user to create just-me space", async ({ page, app, user, toasts }) => { await app.client.createRoom({ name: "Sample Room", }); - await app.closeVerifyToast(); + await toasts.rejectToast("Verify this device"); const menu = await openSpaceCreateMenu(page); await menu.getByRole("button", { name: "Private" }).click(); @@ -179,7 +179,7 @@ test.describe("Spaces", () => { test( "should allow user to add an existing room to a space after creation", { tag: "@screenshot" }, - async ({ page, app, user }) => { + async ({ page, app, user, toasts }) => { await app.client.createRoom({ name: "Sample Room", }); @@ -187,7 +187,7 @@ test.describe("Spaces", () => { name: "A Room that will not be selected", }); - await app.closeVerifyToast(); + await toasts.rejectToast("Verify this device"); const menu = await openSpaceCreateMenu(page); await menu.getByRole("button", { name: "Private" }).click(); @@ -286,8 +286,8 @@ test.describe("Spaces", () => { test( "should render subspaces in the space panel only when expanded", { tag: "@screenshot" }, - async ({ page, app, user, axe }) => { - await app.closeVerifyToast(); + async ({ page, app, user, axe, toasts }) => { + await toasts.rejectToast("Verify this device"); axe.disableRules([ // Disable this check as it triggers on nested roving tab index elements which are in practice fine @@ -409,8 +409,8 @@ test.describe("Spaces", () => { }, }); - test("should disallow creating public rooms", { tag: "@screenshot" }, async ({ page, user, app }) => { - await app.closeVerifyToast(); + test("should disallow creating public rooms", { tag: "@screenshot" }, async ({ page, user, app, toasts }) => { + await toasts.rejectToast("Verify this device"); const menu = await openSpaceCreateMenu(page); await menu .locator('.mx_SpaceBasicSettings_avatarContainer input[type="file"]') diff --git a/apps/web/playwright/e2e/spaces/threads-activity-centre/threadsActivityCentre.spec.ts b/apps/web/playwright/e2e/spaces/threads-activity-centre/threadsActivityCentre.spec.ts index 00ed8a8df1..68ea8a2e6c 100644 --- a/apps/web/playwright/e2e/spaces/threads-activity-centre/threadsActivityCentre.spec.ts +++ b/apps/web/playwright/e2e/spaces/threads-activity-centre/threadsActivityCentre.spec.ts @@ -24,8 +24,8 @@ test.describe("Threads Activity Centre", { tag: "@no-firefox" }, () => { test( "should have the button correctly aligned and displayed in the space panel when expanded", { tag: "@screenshot" }, - async ({ util, app }) => { - await app.closeVerifyToast(); + async ({ util, app, toasts }) => { + await toasts.rejectToast("Verify this device"); // Open the space panel await util.expandSpacePanel(); @@ -146,8 +146,8 @@ test.describe("Threads Activity Centre", { tag: "@no-firefox" }, () => { await expect(page.locator(".mx_SpotlightDialog")).not.toBeVisible(); }); - test("should have the correct hover state", { tag: "@screenshot" }, async ({ util, page, app }) => { - await app.closeVerifyToast(); + test("should have the correct hover state", { tag: "@screenshot" }, async ({ util, page, app, toasts }) => { + await toasts.rejectToast("Verify this device"); await util.hoverTacButton(); await expect(util.getSpacePanel()).toMatchScreenshot("tac-hovered.png"); diff --git a/apps/web/playwright/e2e/timeline/media-preview-settings.spec.ts b/apps/web/playwright/e2e/timeline/media-preview-settings.spec.ts index 026c74d926..de9c4e19a8 100644 --- a/apps/web/playwright/e2e/timeline/media-preview-settings.spec.ts +++ b/apps/web/playwright/e2e/timeline/media-preview-settings.spec.ts @@ -35,48 +35,52 @@ test.describe("Media preview settings", () => { }, }); - test("should be able to hide avatars of inviters", { tag: "@screenshot" }, async ({ page, app, room, user }) => { - await app.closeVerifyToast(); + test( + "should be able to hide avatars of inviters", + { tag: "@screenshot" }, + async ({ page, app, room, user, toasts }) => { + await toasts.rejectToast("Verify this device"); - let settings = await app.settings.openUserSettings("Preferences"); - await settings.getByLabel("Hide avatars of room and inviter").click(); - await app.closeDialog(); - await app.viewRoomById(room.roomId); - await expect( - page.getByRole("complementary").filter({ hasText: "Do you want to join Test room" }), - ).toMatchScreenshot("invite-no-avatar.png", { - // Hide the mxid, which is not stable. - css: ` + let settings = await app.settings.openUserSettings("Preferences"); + await settings.getByLabel("Hide avatars of room and inviter").click(); + await app.closeDialog(); + await app.viewRoomById(room.roomId); + await expect( + page.getByRole("complementary").filter({ hasText: "Do you want to join Test room" }), + ).toMatchScreenshot("invite-no-avatar.png", { + // Hide the mxid, which is not stable. + css: ` .mx_RoomPreviewBar_inviter_mxid { display: none !important; } `, - }); + }); - const testRoomTile = page - .getByRole("listbox", { name: "Room list" }) - .getByRole("option", { name: "Test room" }); - await expect(testRoomTile).toBeVisible(); - await expect(testRoomTile).toMatchScreenshot("invite-room-tree-no-avatar.png"); + const testRoomTile = page + .getByRole("listbox", { name: "Room list" }) + .getByRole("option", { name: "Test room" }); + await expect(testRoomTile).toBeVisible(); + await expect(testRoomTile).toMatchScreenshot("invite-room-tree-no-avatar.png"); - // And then go back to being visible - settings = await app.settings.openUserSettings("Preferences"); - await settings.getByLabel("Hide avatars of room and inviter").click(); - await app.closeDialog(); - await page.goto("#/home"); - await app.viewRoomById(room.roomId); - await expect( - page.getByRole("complementary").filter({ hasText: "Do you want to join Test room" }), - ).toMatchScreenshot("invite-with-avatar.png", { - // Hide the mxid, which is not stable. - css: ` + // And then go back to being visible + settings = await app.settings.openUserSettings("Preferences"); + await settings.getByLabel("Hide avatars of room and inviter").click(); + await app.closeDialog(); + await page.goto("#/home"); + await app.viewRoomById(room.roomId); + await expect( + page.getByRole("complementary").filter({ hasText: "Do you want to join Test room" }), + ).toMatchScreenshot("invite-with-avatar.png", { + // Hide the mxid, which is not stable. + css: ` .mx_RoomPreviewBar_inviter_mxid { display: none !important; } `, - }); - await expect(testRoomTile).toMatchScreenshot("invite-room-tree-with-avatar.png"); - }); + }); + await expect(testRoomTile).toMatchScreenshot("invite-room-tree-with-avatar.png"); + }, + ); test("should be able to hide media in rooms globally", async ({ page, app, room, user }) => { const settings = await app.settings.openUserSettings("Preferences"); diff --git a/apps/web/playwright/e2e/timeline/timeline.spec.ts b/apps/web/playwright/e2e/timeline/timeline.spec.ts index 81fa8da9c3..7b88831bdc 100644 --- a/apps/web/playwright/e2e/timeline/timeline.spec.ts +++ b/apps/web/playwright/e2e/timeline/timeline.spec.ts @@ -786,11 +786,11 @@ test.describe("Timeline", () => { test( "should highlight search result words regardless of formatting", { tag: "@screenshot" }, - async ({ page, app, room }) => { + async ({ page, app, room, toasts }) => { await sendEvent(app.client, room.roomId); await sendEvent(app.client, room.roomId, true); await page.goto(`/#/room/${room.roomId}`); - await app.closeVerifyToast(); + await toasts.rejectToast("Verify this device"); await app.toggleRoomInfoPanel(); @@ -810,48 +810,54 @@ test.describe("Timeline", () => { }, ); - test("should render a fully opaque textual event", { tag: "@screenshot" }, async ({ page, app, room }) => { - const stringToSearch = "Message"; // Same with string sent with sendEvent() + test( + "should render a fully opaque textual event", + { tag: "@screenshot" }, + async ({ page, app, room, toasts }) => { + const stringToSearch = "Message"; // Same with string sent with sendEvent() - await sendEvent(app.client, room.roomId); + await sendEvent(app.client, room.roomId); - await page.goto(`/#/room/${room.roomId}`); - await app.closeVerifyToast(); + await page.goto(`/#/room/${room.roomId}`); + await toasts.rejectToast("Verify this device"); - // Open a room setting dialog - await app.toggleRoomInfoPanel(); - await page.getByRole("menuitem", { name: "Settings" }).click(); + // Open a room setting dialog + await app.toggleRoomInfoPanel(); + await page.getByRole("menuitem", { name: "Settings" }).click(); - // Set a room topic to render a TextualEvent - await page.getByRole("textbox", { name: "Room Topic" }).type(`This is a room for ${stringToSearch}.`); - await page.getByRole("button", { name: "Save" }).click(); + // Set a room topic to render a TextualEvent + await page + .getByRole("textbox", { name: "Room Topic" }) + .type(`This is a room for ${stringToSearch}.`); + await page.getByRole("button", { name: "Save" }).click(); - await app.closeDialog(); + await app.closeDialog(); - // Assert that the TextualEvent is rendered - await expect( - page.getByText(`${OLD_NAME} changed the topic to "This is a room for ${stringToSearch}.".`), - ).toHaveClass(/mx_TextualEvent/); + // Assert that the TextualEvent is rendered + await expect( + page.getByText(`${OLD_NAME} changed the topic to "This is a room for ${stringToSearch}.".`), + ).toHaveClass(/mx_TextualEvent/); - // Search the string to display both the message and TextualEvent on search results panel - await page.locator(".mx_RoomSummaryCard_search").getByRole("searchbox").fill(stringToSearch); - await page.locator(".mx_RoomSummaryCard_search").getByRole("searchbox").press("Enter"); + // Search the string to display both the message and TextualEvent on search results panel + await page.locator(".mx_RoomSummaryCard_search").getByRole("searchbox").fill(stringToSearch); + await page.locator(".mx_RoomSummaryCard_search").getByRole("searchbox").press("Enter"); - // On search results panel - const resultsPanel = page.locator(".mx_RoomView_searchResultsPanel"); - // Assert that contextual event tiles are translucent - for (const locator of await resultsPanel.locator(".mx_EventTile.mx_EventTile_contextual").all()) { - await expect(locator).toHaveCSS("opacity", "0.4"); - } - // Assert that the TextualEvent is fully opaque (visually solid). - for (const locator of await resultsPanel.locator(".mx_EventTile .mx_TextualEvent").all()) { - await expect(locator).toHaveCSS("opacity", "1"); - } + // On search results panel + const resultsPanel = page.locator(".mx_RoomView_searchResultsPanel"); + // Assert that contextual event tiles are translucent + for (const locator of await resultsPanel.locator(".mx_EventTile.mx_EventTile_contextual").all()) { + await expect(locator).toHaveCSS("opacity", "0.4"); + } + // Assert that the TextualEvent is fully opaque (visually solid). + for (const locator of await resultsPanel.locator(".mx_EventTile .mx_TextualEvent").all()) { + await expect(locator).toHaveCSS("opacity", "1"); + } - await expect(page.locator(".mx_RoomView_searchResultsPanel")).toMatchScreenshot( - "search-results-with-TextualEvent.png", - ); - }); + await expect(page.locator(".mx_RoomView_searchResultsPanel")).toMatchScreenshot( + "search-results-with-TextualEvent.png", + ); + }, + ); }); test("should render a code block", { tag: "@screenshot" }, async ({ page, app, room }) => { diff --git a/apps/web/playwright/pages/ElementAppPage.ts b/apps/web/playwright/pages/ElementAppPage.ts index 8c059524b6..e47a18ddc5 100644 --- a/apps/web/playwright/pages/ElementAppPage.ts +++ b/apps/web/playwright/pages/ElementAppPage.ts @@ -12,6 +12,7 @@ import { Settings } from "./settings"; import { Client } from "./client"; import { Timeline } from "./timeline"; import { Spotlight } from "./Spotlight"; +import { Toasts } from "./toasts"; /** * A set of utility methods for interacting with the Element-Web UI. @@ -36,6 +37,11 @@ export class ElementAppPage { if (!this._timeline) this._timeline = new Timeline(this.page); return this._timeline; } + private _toasts?: Toasts; + public get toasts(): Toasts { + if (!this._toasts) this._toasts = new Toasts(this.page); + return this._toasts; + } public async cleanup() { await this._client?.cleanup(); @@ -248,28 +254,6 @@ export class ElementAppPage { await this.page.locator(".mx_Toast_toast", { hasText: title }).getByRole("button", { name: button }).click(); } - /** - * Dismiss the "Notifications" toast. - */ - public async closeNotificationToast(): Promise { - await this.closeToast("Notifications", "Dismiss"); - } - - /** - * Dismiss the "Turn on key storage" toast. - */ - public async closeKeyStorageToast() { - await this.closeToast("Turn on key storage", "Dismiss"); - await this.page.getByRole("button", { name: "Yes, dismiss" }).click(); - } - - /** - * Dismiss the "Verify this device" toast by clicking "Later". - */ - public async closeVerifyToast() { - await this.closeToast("Verify this device", "Later"); - } - /** * Scroll an infinite list to the bottom. * @param list The element to scroll diff --git a/apps/web/playwright/pages/toasts.ts b/apps/web/playwright/pages/toasts.ts index 80ee3c9f26..f82b5ae5ce 100644 --- a/apps/web/playwright/pages/toasts.ts +++ b/apps/web/playwright/pages/toasts.ts @@ -50,4 +50,12 @@ export class Toasts { const toast = await this.getToast(expectedTitle); await toast.locator('.mx_Toast_buttons button[data-kind="secondary"]').click(); } + + /** + * Reject the "Turn on key storage" toast. + */ + public async rejectKeyStorageToast() { + await this.rejectToast("Turn on key storage"); + await this.page.getByRole("button", { name: "Yes, dismiss" }).click(); + } }