Use rejectToast in playwright tests to reject toasts

This commit is contained in:
Andy Balaam 2026-04-01 15:30:40 +01:00
parent 03902d2453
commit a3a59d38aa
27 changed files with 236 additions and 226 deletions

View File

@ -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();

View File

@ -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");

View File

@ -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

View File

@ -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();

View File

@ -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" })

View File

@ -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}` });
}

View File

@ -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 }) => {

View File

@ -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 }) => {

View File

@ -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++) {

View File

@ -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 }) => {

View File

@ -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();

View File

@ -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();

View File

@ -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 }) => {

View File

@ -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");

View File

@ -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();

View File

@ -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" })

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -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
});

View File

@ -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 ({

View File

@ -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"]')

View File

@ -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");

View File

@ -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");

View File

@ -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 }) => {

View File

@ -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<void> {
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

View File

@ -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();
}
}