Tag screenshot tests to speed up test:playwright:screenshot (#28623)
* Tag screenshot tests to speed up test:playwright:screenshot Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Add more tags Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
d0e19d3e03
commit
d0d0b8212d
38 changed files with 1441 additions and 1301 deletions
|
@ -64,7 +64,7 @@
|
|||
"test:playwright:open": "yarn test:playwright --ui",
|
||||
"test:playwright:screenshots": "yarn test:playwright:screenshots:build && yarn test:playwright:screenshots:run",
|
||||
"test:playwright:screenshots:build": "docker build playwright -t element-web-playwright",
|
||||
"test:playwright:screenshots:run": "docker run --rm --network host -e BASE_URL -e CI -v $(pwd):/work/ -v $(node -e 'console.log(require(`path`).dirname(require.resolve(`matrix-js-sdk/package.json`)))'):/work/node_modules/matrix-js-sdk -v /var/run/docker.sock:/var/run/docker.sock -v /tmp/:/tmp/ -it element-web-playwright",
|
||||
"test:playwright:screenshots:run": "docker run --rm --network host -e BASE_URL -e CI -v $(pwd):/work/ -v $(node -e 'console.log(require(`path`).dirname(require.resolve(`matrix-js-sdk/package.json`)))'):/work/node_modules/matrix-js-sdk -v /var/run/docker.sock:/var/run/docker.sock -v /tmp/:/tmp/ -it element-web-playwright --grep @screenshot",
|
||||
"coverage": "yarn test --coverage",
|
||||
"analyse:unused-exports": "ts-node ./scripts/analyse_unused_exports.ts",
|
||||
"analyse:webpack-bundles": "webpack-bundle-analyzer webpack-stats.json webapp",
|
||||
|
|
|
@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
|
||||
import { test, expect } from "../../element-web-test";
|
||||
|
||||
test(`shows error page if browser lacks Intl support`, async ({ page }) => {
|
||||
test(`shows error page if browser lacks Intl support`, { tag: "@screenshot" }, async ({ page }) => {
|
||||
await page.addInitScript({ content: `delete window.Intl;` });
|
||||
await page.goto("/");
|
||||
|
||||
|
@ -21,7 +21,7 @@ test(`shows error page if browser lacks Intl support`, async ({ page }) => {
|
|||
await expect(page).toMatchScreenshot("unsupported-browser.png");
|
||||
});
|
||||
|
||||
test(`shows error page if browser lacks WebAssembly support`, async ({ page }) => {
|
||||
test(`shows error page if browser lacks WebAssembly support`, { tag: "@screenshot" }, async ({ page }) => {
|
||||
await page.addInitScript({ content: `delete window.WebAssembly;` });
|
||||
await page.goto("/");
|
||||
|
||||
|
|
|
@ -134,18 +134,22 @@ test.describe("Audio player", () => {
|
|||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("should be correctly rendered - light theme", async ({ page, app }) => {
|
||||
test("should be correctly rendered - light theme", { tag: "@screenshot" }, async ({ page, app }) => {
|
||||
await uploadFile(page, "playwright/sample-files/1sec-long-name-audio-file.ogg");
|
||||
await takeSnapshots(page, app, "Selected EventTile of audio player (light theme)");
|
||||
});
|
||||
|
||||
test("should be correctly rendered - light theme with monospace font", async ({ page, app }) => {
|
||||
test(
|
||||
"should be correctly rendered - light theme with monospace font",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app }) => {
|
||||
await uploadFile(page, "playwright/sample-files/1sec-long-name-audio-file.ogg");
|
||||
|
||||
await takeSnapshots(page, app, "Selected EventTile of audio player (light theme, monospace font)", true); // Enable monospace
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should be correctly rendered - high contrast theme", async ({ page, app }) => {
|
||||
test("should be correctly rendered - high contrast theme", { tag: "@screenshot" }, async ({ page, app }) => {
|
||||
// Disable system theme in case ThemeWatcher enables the theme automatically,
|
||||
// so that the high contrast theme can be enabled
|
||||
await app.settings.setValue("use_system_theme", null, SettingLevel.DEVICE, false);
|
||||
|
@ -161,7 +165,7 @@ test.describe("Audio player", () => {
|
|||
await takeSnapshots(page, app, "Selected EventTile of audio player (high contrast)");
|
||||
});
|
||||
|
||||
test("should be correctly rendered - dark theme", async ({ page, app }) => {
|
||||
test("should be correctly rendered - dark theme", { tag: "@screenshot" }, async ({ page, app }) => {
|
||||
// Enable dark theme
|
||||
await app.settings.setValue("theme", null, SettingLevel.ACCOUNT, "dark");
|
||||
|
||||
|
@ -207,7 +211,10 @@ test.describe("Audio player", () => {
|
|||
expect(download.suggestedFilename()).toBe("1sec.ogg");
|
||||
});
|
||||
|
||||
test("should support replying to audio file with another audio file", async ({ page, app }) => {
|
||||
test(
|
||||
"should support replying to audio file with another audio file",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app }) => {
|
||||
await uploadFile(page, "playwright/sample-files/1sec.ogg");
|
||||
|
||||
// Assert the audio player is rendered
|
||||
|
@ -230,9 +237,13 @@ test.describe("Audio player", () => {
|
|||
await expect(button.locator(".mx_MFileBody_info_filename")).toBeVisible();
|
||||
|
||||
await takeSnapshots(page, app, "Selected EventTile of audio player with a reply");
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should support creating a reply chain with multiple audio files", async ({ page, app, user }) => {
|
||||
test(
|
||||
"should support creating a reply chain with multiple audio files",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, user }) => {
|
||||
// Note: "mx_ReplyChain" element is used not only for replies which
|
||||
// create a reply chain, but also for a single reply without a replied
|
||||
// message. This test checks whether a reply chain which consists of
|
||||
|
@ -293,7 +304,8 @@ test.describe("Audio player", () => {
|
|||
|
||||
// Take snapshots
|
||||
await takeSnapshots(page, app, "Selected EventTile of audio player with a reply chain");
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should be rendered, play, and support replying on a thread", async ({ page, app }) => {
|
||||
await uploadFile(page, "playwright/sample-files/1sec-long-name-audio-file.ogg");
|
||||
|
|
|
@ -89,7 +89,10 @@ test.describe("HTML Export", () => {
|
|||
},
|
||||
});
|
||||
|
||||
test("should export html successfully and match screenshot", async ({ page, app, room }) => {
|
||||
test(
|
||||
"should export html successfully and match screenshot",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room }) => {
|
||||
// Set a fixed time rather than masking off the line with the time in it: we don't need to worry
|
||||
// about the width changing and we can actually test this line looks correct.
|
||||
page.clock.setSystemTime(new Date("2024-01-01T00:00:00Z"));
|
||||
|
@ -127,5 +130,6 @@ test.describe("HTML Export", () => {
|
|||
page.locator(".mx_MessageTimestamp"),
|
||||
],
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
|
|
@ -204,12 +204,10 @@ test.describe("Cryptography", function () {
|
|||
await expect(page.locator(".mx_Dialog")).toHaveCount(1);
|
||||
});
|
||||
|
||||
test("creating a DM should work, being e2e-encrypted / user verification", async ({
|
||||
page,
|
||||
app,
|
||||
bot: bob,
|
||||
user: aliceCredentials,
|
||||
}) => {
|
||||
test(
|
||||
"creating a DM should work, being e2e-encrypted / user verification",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, bot: bob, user: aliceCredentials }) => {
|
||||
await app.client.bootstrapCrossSigning(aliceCredentials);
|
||||
await startDMWithBob(page, bob);
|
||||
// send first message
|
||||
|
@ -227,7 +225,8 @@ test.describe("Cryptography", function () {
|
|||
|
||||
// Take a snapshot of RoomSummaryCard with a verified E2EE icon
|
||||
await expect(page.locator(".mx_RightPanel")).toMatchScreenshot("RoomSummaryCard-with-verified-e2ee.png");
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should allow verification when there is no existing DM", async ({
|
||||
page,
|
||||
|
|
|
@ -66,7 +66,10 @@ test.describe("Editing", () => {
|
|||
botCreateOpts: { displayName: "Bob" },
|
||||
});
|
||||
|
||||
test("should render and interact with the message edit history dialog", async ({ page, user, app, room }) => {
|
||||
test(
|
||||
"should render and interact with the message edit history dialog",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, user, app, room }) => {
|
||||
// Click the "Remove" button on the message edit history dialog
|
||||
const clickButtonRemove = async (locator: Locator) => {
|
||||
const eventTileLine = locator.locator(".mx_EventTile_line");
|
||||
|
@ -185,7 +188,8 @@ test.describe("Editing", () => {
|
|||
.locator(".mx_RoomView_MessageList")
|
||||
.locator(".mx_EventTile_last .mx_RedactedBody", { hasText: "Message deleted" }),
|
||||
).toBeVisible();
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should render 'View Source' button in developer mode on the message edit history dialog", async ({
|
||||
page,
|
||||
|
|
|
@ -25,7 +25,7 @@ test.describe("Image Upload", () => {
|
|||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("should show image preview when uploading an image", async ({ page, app }) => {
|
||||
test("should show image preview when uploading an image", { tag: "@screenshot" }, async ({ page, app }) => {
|
||||
await page
|
||||
.locator(".mx_MessageComposer_actions input[type='file']")
|
||||
.setInputFiles("playwright/sample-files/riot.png");
|
||||
|
|
|
@ -26,7 +26,7 @@ test.describe("Forgot Password", () => {
|
|||
}),
|
||||
});
|
||||
|
||||
test("renders properly", async ({ page, homeserver }) => {
|
||||
test("renders properly", { tag: "@screenshot" }, async ({ page, homeserver }) => {
|
||||
await page.goto("/");
|
||||
|
||||
await page.getByRole("link", { name: "Sign in" }).click();
|
||||
|
@ -39,7 +39,7 @@ test.describe("Forgot Password", () => {
|
|||
await expect(page.getByRole("main")).toMatchScreenshot("forgot-password.png");
|
||||
});
|
||||
|
||||
test("renders email verification dialog properly", async ({ page, homeserver }) => {
|
||||
test("renders email verification dialog properly", { tag: "@screenshot" }, async ({ page, homeserver }) => {
|
||||
const user = await homeserver.registerUser(username, password);
|
||||
|
||||
await homeserver.setThreepid(user.userId, "email", email);
|
||||
|
|
|
@ -19,7 +19,7 @@ test.describe("Invite dialog", function () {
|
|||
|
||||
const botName = "BotAlice";
|
||||
|
||||
test("should support inviting a user to a room", async ({ page, app, user, bot }) => {
|
||||
test("should support inviting a user to a room", { tag: "@screenshot" }, async ({ page, app, user, bot }) => {
|
||||
// Create and view a room
|
||||
await app.client.createRoom({ name: "Test Room" });
|
||||
await app.viewRoomByName("Test Room");
|
||||
|
@ -73,12 +73,17 @@ test.describe("Invite dialog", function () {
|
|||
await expect(page.getByText(`${botName} joined the room`)).toBeVisible();
|
||||
});
|
||||
|
||||
test("should support inviting a user to Direct Messages", async ({ page, app, user, bot }) => {
|
||||
test(
|
||||
"should support inviting a user to Direct Messages",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, user, bot }) => {
|
||||
await page.locator(".mx_RoomList").getByRole("button", { name: "Start chat" }).click();
|
||||
|
||||
const other = page.locator(".mx_InviteDialog_other");
|
||||
// Assert that the header is rendered
|
||||
await expect(other.locator(".mx_Dialog_header .mx_Dialog_title").getByText("Direct Messages")).toBeVisible();
|
||||
await expect(
|
||||
other.locator(".mx_Dialog_header .mx_Dialog_title").getByText("Direct Messages"),
|
||||
).toBeVisible();
|
||||
|
||||
// Assert that the bar is rendered
|
||||
await expect(other.locator(".mx_InviteDialog_addressBar")).toBeVisible();
|
||||
|
@ -88,7 +93,9 @@ test.describe("Invite dialog", function () {
|
|||
|
||||
await other.getByTestId("invite-dialog-input").fill(bot.credentials.userId);
|
||||
|
||||
await expect(other.locator(".mx_InviteDialog_tile_nameStack").getByText(bot.credentials.userId)).toBeVisible();
|
||||
await expect(
|
||||
other.locator(".mx_InviteDialog_tile_nameStack").getByText(bot.credentials.userId),
|
||||
).toBeVisible();
|
||||
await other.locator(".mx_InviteDialog_tile_nameStack").getByText(botName).click();
|
||||
|
||||
await expect(
|
||||
|
@ -108,7 +115,10 @@ test.describe("Invite dialog", function () {
|
|||
// TODO: implement the test on room-header.spec.ts
|
||||
const roomHeader = page.locator(".mx_RoomHeader");
|
||||
await roomHeader.locator(".mx_RoomHeader_heading").hover();
|
||||
await expect(roomHeader.locator(".mx_RoomHeader_heading")).toHaveCSS("background-color", "rgba(0, 0, 0, 0)");
|
||||
await expect(roomHeader.locator(".mx_RoomHeader_heading")).toHaveCSS(
|
||||
"background-color",
|
||||
"rgba(0, 0, 0, 0)",
|
||||
);
|
||||
|
||||
// Send a message to invite the bots
|
||||
const composer = app.getComposer().locator("[contenteditable]");
|
||||
|
@ -120,5 +130,6 @@ test.describe("Invite dialog", function () {
|
|||
|
||||
// Assert that the message is displayed at the bottom
|
||||
await expect(page.locator(".mx_EventTile_last").getByText("Hello")).toBeVisible();
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
|
|
@ -63,7 +63,7 @@ test.describe("Message rendering", () => {
|
|||
{ direction: "ltr", displayName: "Quentin" },
|
||||
{ direction: "rtl", displayName: "كوينتين" },
|
||||
].forEach(({ direction, displayName }) => {
|
||||
test.describe(`with ${direction} display name`, () => {
|
||||
test.describe(`with ${direction} display name`, { tag: "@screenshot" }, () => {
|
||||
test.use({
|
||||
displayName,
|
||||
room: async ({ user, app }, use) => {
|
||||
|
@ -72,14 +72,18 @@ test.describe("Message rendering", () => {
|
|||
},
|
||||
});
|
||||
|
||||
test("should render a basic LTR text message", async ({ page, user, app, room }) => {
|
||||
test(
|
||||
"should render a basic LTR text message",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, user, app, room }) => {
|
||||
await page.goto(`#/room/${room.roomId}`);
|
||||
|
||||
const msgTile = await sendMessage(page, "Hello, world!");
|
||||
await expect(msgTile).toMatchScreenshot(`basic-message-ltr-${direction}displayname.png`, {
|
||||
mask: [page.locator(".mx_MessageTimestamp")],
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should render an LTR emote", async ({ page, user, app, room }) => {
|
||||
await page.goto(`#/room/${room.roomId}`);
|
||||
|
|
|
@ -24,7 +24,7 @@ test.describe("permalinks", () => {
|
|||
displayName: "Alice",
|
||||
});
|
||||
|
||||
test("shoud render permalinks as expected", async ({ page, app, user, homeserver }) => {
|
||||
test("shoud render permalinks as expected", { tag: "@screenshot" }, async ({ page, app, user, homeserver }) => {
|
||||
const bob = new Bot(page, homeserver, { displayName: "Bob" });
|
||||
const charlotte = new Bot(page, homeserver, { displayName: "Charlotte" });
|
||||
await bob.prepareClient();
|
||||
|
|
|
@ -10,20 +10,22 @@ import { test } from "./index";
|
|||
import { expect } from "../../element-web-test";
|
||||
|
||||
test.describe("Pinned messages", () => {
|
||||
test("should show the empty state when there are no pinned messages", async ({ page, app, room1, util }) => {
|
||||
test(
|
||||
"should show the empty state when there are no pinned messages",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room1, util }) => {
|
||||
await util.goTo(room1);
|
||||
await util.openRoomInfo();
|
||||
await util.assertPinnedCountInRoomInfo(0);
|
||||
await util.openPinnedMessagesList();
|
||||
await util.assertEmptyPinnedMessagesList();
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should pin one message and to have the pinned message badge in the timeline", async ({
|
||||
page,
|
||||
app,
|
||||
room1,
|
||||
util,
|
||||
}) => {
|
||||
test(
|
||||
"should pin one message and to have the pinned message badge in the timeline",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room1, util }) => {
|
||||
await util.goTo(room1);
|
||||
await util.receiveMessages(room1, ["Msg1"]);
|
||||
await util.pinMessages(["Msg1"]);
|
||||
|
@ -38,7 +40,8 @@ test.describe("Pinned messages", () => {
|
|||
}
|
||||
`,
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should pin messages and show them in the room info panel", async ({ page, app, room1, util }) => {
|
||||
await util.goTo(room1);
|
||||
|
@ -73,7 +76,7 @@ test.describe("Pinned messages", () => {
|
|||
await util.assertPinnedCountInRoomInfo(2);
|
||||
});
|
||||
|
||||
test("should unpin all messages", async ({ page, app, room1, util }) => {
|
||||
test("should unpin all messages", { tag: "@screenshot" }, async ({ page, app, room1, util }) => {
|
||||
await util.goTo(room1);
|
||||
await util.receiveMessages(room1, ["Msg1", "Msg2", "Msg3", "Msg4"]);
|
||||
await util.pinMessages(["Msg1", "Msg2", "Msg4"]);
|
||||
|
@ -98,7 +101,7 @@ test.describe("Pinned messages", () => {
|
|||
await util.assertPinnedCountInRoomInfo(0);
|
||||
});
|
||||
|
||||
test("should display one message in the banner", async ({ page, app, room1, util }) => {
|
||||
test("should display one message in the banner", { tag: "@screenshot" }, async ({ page, app, room1, util }) => {
|
||||
await util.goTo(room1);
|
||||
await util.receiveMessages(room1, ["Msg1"]);
|
||||
await util.pinMessages(["Msg1"]);
|
||||
|
@ -106,7 +109,7 @@ test.describe("Pinned messages", () => {
|
|||
await expect(util.getBanner()).toMatchScreenshot("pinned-message-banner-1-Msg1.png");
|
||||
});
|
||||
|
||||
test("should display 2 messages in the banner", async ({ page, app, room1, util }) => {
|
||||
test("should display 2 messages in the banner", { tag: "@screenshot" }, async ({ page, app, room1, util }) => {
|
||||
await util.goTo(room1);
|
||||
await util.receiveMessages(room1, ["Msg1", "Msg2"]);
|
||||
await util.pinMessages(["Msg1", "Msg2"]);
|
||||
|
@ -123,7 +126,7 @@ test.describe("Pinned messages", () => {
|
|||
await expect(util.getBanner()).toMatchScreenshot("pinned-message-banner-2-Msg2.png");
|
||||
});
|
||||
|
||||
test("should display 4 messages in the banner", async ({ page, app, room1, util }) => {
|
||||
test("should display 4 messages in the banner", { tag: "@screenshot" }, async ({ page, app, room1, util }) => {
|
||||
await util.goTo(room1);
|
||||
await util.receiveMessages(room1, ["Msg1", "Msg2", "Msg3", "Msg4"]);
|
||||
await util.pinMessages(["Msg1", "Msg2", "Msg3", "Msg4"]);
|
||||
|
|
|
@ -93,7 +93,7 @@ test.describe("Polls", () => {
|
|||
});
|
||||
});
|
||||
|
||||
test("should be creatable and votable", async ({ page, app, bot, user }) => {
|
||||
test("should be creatable and votable", { tag: "@screenshot" }, async ({ page, app, bot, user }) => {
|
||||
const roomId: string = await app.client.createRoom({});
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await page.goto("/#/room/" + roomId);
|
||||
|
@ -219,7 +219,10 @@ test.describe("Polls", () => {
|
|||
await expect(page.locator(".mx_ErrorDialog")).toBeAttached();
|
||||
});
|
||||
|
||||
test("should be displayed correctly in thread panel", async ({ page, app, user, bot, homeserver }) => {
|
||||
test(
|
||||
"should be displayed correctly in thread panel",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, user, bot, homeserver }) => {
|
||||
const botCharlie = new Bot(page, homeserver, { displayName: "BotCharlie" });
|
||||
await botCharlie.prepareClient();
|
||||
|
||||
|
@ -229,7 +232,9 @@ test.describe("Polls", () => {
|
|||
await page.goto("/#/room/" + roomId);
|
||||
|
||||
// wait until the bots joined
|
||||
await expect(page.getByText("BotBob and one other were invited and joined")).toBeAttached({ timeout: 10000 });
|
||||
await expect(page.getByText("BotBob and one other were invited and joined")).toBeAttached({
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
const locator = await app.openMessageComposerOptions();
|
||||
await locator.getByRole("menuitem", { name: "Poll" }).click();
|
||||
|
@ -274,22 +279,30 @@ test.describe("Polls", () => {
|
|||
|
||||
// and thread view
|
||||
await expect(
|
||||
page.locator(".mx_ThreadView .mx_MPollBody_totalVotes").getByText("2 votes cast. Vote to see the results"),
|
||||
page
|
||||
.locator(".mx_ThreadView .mx_MPollBody_totalVotes")
|
||||
.getByText("2 votes cast. Vote to see the results"),
|
||||
).toBeAttached();
|
||||
|
||||
// Take snapshots of poll on ThreadView
|
||||
await app.settings.setValue("layout", null, SettingLevel.DEVICE, Layout.Bubble);
|
||||
await expect(page.locator(".mx_ThreadView .mx_EventTile[data-layout='bubble']").first()).toBeVisible();
|
||||
await expect(page.locator(".mx_ThreadView")).toMatchScreenshot("ThreadView_with_a_poll_on_bubble_layout.png", {
|
||||
await expect(page.locator(".mx_ThreadView")).toMatchScreenshot(
|
||||
"ThreadView_with_a_poll_on_bubble_layout.png",
|
||||
{
|
||||
mask: [page.locator(".mx_MessageTimestamp")],
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
await app.settings.setValue("layout", null, SettingLevel.DEVICE, Layout.Group);
|
||||
await expect(page.locator(".mx_ThreadView .mx_EventTile[data-layout='group']").first()).toBeVisible();
|
||||
|
||||
await expect(page.locator(".mx_ThreadView")).toMatchScreenshot("ThreadView_with_a_poll_on_group_layout.png", {
|
||||
await expect(page.locator(".mx_ThreadView")).toMatchScreenshot(
|
||||
"ThreadView_with_a_poll_on_group_layout.png",
|
||||
{
|
||||
mask: [page.locator(".mx_MessageTimestamp")],
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
const roomViewLocator = page.locator(".mx_RoomView_body");
|
||||
// vote 'Maybe' in the main timeline poll
|
||||
|
@ -321,5 +334,6 @@ test.describe("Polls", () => {
|
|||
|
||||
// and in thread view tile
|
||||
await expectVoteCounts(page.locator(".mx_ThreadView"));
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
|
|
@ -38,12 +38,10 @@ test.describe("Email Registration", async () => {
|
|||
await page.goto("/#/register");
|
||||
});
|
||||
|
||||
test("registers an account and lands on the use case selection screen", async ({
|
||||
page,
|
||||
mailhog,
|
||||
request,
|
||||
checkA11y,
|
||||
}) => {
|
||||
test(
|
||||
"registers an account and lands on the use case selection screen",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, mailhog, request, checkA11y }) => {
|
||||
await expect(page.getByRole("textbox", { name: "Username" })).toBeVisible();
|
||||
// Hide the server text as it contains the randomly allocated Homeserver port
|
||||
const screenshotOptions = { mask: [page.locator(".mx_ServerPicker_server")] };
|
||||
|
@ -67,5 +65,6 @@ test.describe("Email Registration", async () => {
|
|||
await request.get(emailLink); // "Click" the link in the email
|
||||
|
||||
await expect(page.locator(".mx_UseCaseSelection_skip")).toBeVisible();
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
|
|
@ -15,7 +15,10 @@ test.describe("Registration", () => {
|
|||
await page.goto("/#/register");
|
||||
});
|
||||
|
||||
test("registers an account and lands on the home screen", async ({ homeserver, page, checkA11y, crypto }) => {
|
||||
test(
|
||||
"registers an account and lands on the home screen",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ homeserver, page, checkA11y, crypto }) => {
|
||||
await page.getByRole("button", { name: "Edit", exact: true }).click();
|
||||
await expect(page.getByRole("button", { name: "Continue", exact: true })).toBeVisible();
|
||||
|
||||
|
@ -29,7 +32,10 @@ test.describe("Registration", () => {
|
|||
|
||||
await expect(page.getByRole("textbox", { name: "Username", exact: true })).toBeVisible();
|
||||
// Hide the server text as it contains the randomly allocated Homeserver port
|
||||
const screenshotOptions = { mask: [page.locator(".mx_ServerPicker_server")], includeDialogBackground: true };
|
||||
const screenshotOptions = {
|
||||
mask: [page.locator(".mx_ServerPicker_server")],
|
||||
includeDialogBackground: true,
|
||||
};
|
||||
await expect(page).toMatchScreenshot("registration.png", screenshotOptions);
|
||||
await checkA11y();
|
||||
|
||||
|
@ -68,13 +74,14 @@ test.describe("Registration", () => {
|
|||
await page.getByRole("button", { name: "User menu", exact: true }).click();
|
||||
await page.getByRole("menuitem", { name: "All settings", exact: true }).click();
|
||||
await page.getByRole("tab", { name: "Sessions", exact: true }).click();
|
||||
await expect(page.getByTestId("current-session-section").getByTestId("device-metadata-isVerified")).toHaveText(
|
||||
"Verified",
|
||||
);
|
||||
await expect(
|
||||
page.getByTestId("current-session-section").getByTestId("device-metadata-isVerified"),
|
||||
).toHaveText("Verified");
|
||||
|
||||
// check that cross-signing keys have been uploaded.
|
||||
await crypto.assertDeviceIsCrossSigned();
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should require username to fulfil requirements and be available", async ({ homeserver, page }) => {
|
||||
await page.getByRole("button", { name: "Edit", exact: true }).click();
|
||||
|
|
|
@ -18,7 +18,7 @@ test.describe("Release announcement", () => {
|
|||
labsFlags: ["threadsActivityCentre"],
|
||||
});
|
||||
|
||||
test("should display the release announcement process", async ({ page, app, util }) => {
|
||||
test("should display the release announcement process", { tag: "@screenshot" }, async ({ page, app, util }) => {
|
||||
// The TAC release announcement should be displayed
|
||||
await util.assertReleaseAnnouncementIsVisible("Threads Activity Centre");
|
||||
// Hide the release announcement
|
||||
|
|
|
@ -40,7 +40,7 @@ test.describe("FilePanel", () => {
|
|||
});
|
||||
|
||||
test.describe("render", () => {
|
||||
test("should render empty state", async ({ page }) => {
|
||||
test("should render empty state", { tag: "@screenshot" }, async ({ page }) => {
|
||||
// Wait until the information about the empty state is rendered
|
||||
await expect(page.locator(".mx_EmptyState")).toBeVisible();
|
||||
|
||||
|
@ -48,7 +48,7 @@ test.describe("FilePanel", () => {
|
|||
await expect(page.locator(".mx_RightPanel")).toMatchScreenshot("empty.png");
|
||||
});
|
||||
|
||||
test("should list tiles on the panel", async ({ page }) => {
|
||||
test("should list tiles on the panel", { tag: "@screenshot" }, async ({ page }) => {
|
||||
// Upload multiple files
|
||||
await uploadFile(page, "playwright/sample-files/riot.png"); // Image
|
||||
await uploadFile(page, "playwright/sample-files/1sec.ogg"); // Audio
|
||||
|
|
|
@ -21,7 +21,7 @@ test.describe("NotificationPanel", () => {
|
|||
await app.client.createRoom({ name: ROOM_NAME });
|
||||
});
|
||||
|
||||
test("should render empty state", async ({ page, app }) => {
|
||||
test("should render empty state", { tag: "@screenshot" }, async ({ page, app }) => {
|
||||
await app.viewRoomByName(ROOM_NAME);
|
||||
|
||||
await page.getByRole("button", { name: "Notifications" }).click();
|
||||
|
|
|
@ -38,7 +38,7 @@ test.describe("RightPanel", () => {
|
|||
});
|
||||
|
||||
test.describe("in rooms", () => {
|
||||
test("should handle long room address and long room name", async ({ page, app }) => {
|
||||
test("should handle long room address and long room name", { tag: "@screenshot" }, async ({ page, app }) => {
|
||||
await app.client.createRoom({ name: ROOM_NAME_LONG });
|
||||
await viewRoomSummaryByName(page, app, ROOM_NAME_LONG);
|
||||
|
||||
|
|
|
@ -47,7 +47,10 @@ test.describe("Room Directory", () => {
|
|||
expect(resp.chunk[0].room_id).toEqual(roomId);
|
||||
});
|
||||
|
||||
test("should allow finding published rooms in directory", async ({ page, app, user, bot }) => {
|
||||
test(
|
||||
"should allow finding published rooms in directory",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, user, bot }) => {
|
||||
const name = "This is a public room";
|
||||
await bot.createRoom({
|
||||
visibility: "public" as Visibility,
|
||||
|
@ -60,7 +63,9 @@ test.describe("Room Directory", () => {
|
|||
const dialog = page.locator(".mx_SpotlightDialog");
|
||||
await dialog.getByRole("textbox", { name: "Search" }).fill("Unknown Room");
|
||||
await expect(
|
||||
dialog.getByText("If you can't find the room you're looking for, ask for an invite or create a new room."),
|
||||
dialog.getByText(
|
||||
"If you can't find the room you're looking for, ask for an invite or create a new room.",
|
||||
),
|
||||
).toHaveClass("mx_SpotlightDialog_otherSearches_messageSearchText");
|
||||
|
||||
await expect(page.locator(".mx_Dialog")).toMatchScreenshot("filtered-no-results.png");
|
||||
|
@ -76,5 +81,6 @@ test.describe("Room Directory", () => {
|
|||
.click();
|
||||
|
||||
await expect(page).toHaveURL("/#/room/#test1234:localhost");
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
|
|
@ -20,7 +20,7 @@ test.describe("Room Header", () => {
|
|||
test.use({
|
||||
labsFlags: ["feature_notifications"],
|
||||
});
|
||||
test("should render default buttons properly", async ({ page, app, user }) => {
|
||||
test("should render default buttons properly", { tag: "@screenshot" }, async ({ page, app, user }) => {
|
||||
await app.client.createRoom({ name: "Test Room" });
|
||||
await app.viewRoomByName("Test Room");
|
||||
|
||||
|
@ -51,7 +51,10 @@ test.describe("Room Header", () => {
|
|||
await expect(header).toMatchScreenshot("room-header.png");
|
||||
});
|
||||
|
||||
test("should render a very long room name without collapsing the buttons", async ({ page, app, user }) => {
|
||||
test(
|
||||
"should render a very long room name without collapsing the buttons",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, user }) => {
|
||||
const LONG_ROOM_NAME =
|
||||
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore " +
|
||||
"et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " +
|
||||
|
@ -78,7 +81,8 @@ test.describe("Room Header", () => {
|
|||
}
|
||||
|
||||
await expect(header).toMatchScreenshot("room-header-long-name.png");
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test.describe("with a video room", () => {
|
||||
|
@ -99,7 +103,10 @@ test.describe("Room Header", () => {
|
|||
test.describe("and with feature_notifications enabled", () => {
|
||||
test.use({ labsFlags: ["feature_video_rooms", "feature_notifications"] });
|
||||
|
||||
test("should render buttons for chat, room info, threads and facepile", async ({ page, app, user }) => {
|
||||
test(
|
||||
"should render buttons for chat, room info, threads and facepile",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, user }) => {
|
||||
await createVideoRoom(page, app);
|
||||
|
||||
const header = page.locator(".mx_RoomHeader");
|
||||
|
@ -122,7 +129,8 @@ test.describe("Room Header", () => {
|
|||
await expect(header.getByRole("button")).toHaveCount(7);
|
||||
|
||||
await expect(header).toMatchScreenshot("room-header-video-room.png");
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test("should render a working chat button which opens the timeline on a right panel", async ({
|
||||
|
|
|
@ -23,7 +23,7 @@ test.describe("Account user settings tab", () => {
|
|||
},
|
||||
});
|
||||
|
||||
test("should be rendered properly", async ({ uut, user }) => {
|
||||
test("should be rendered properly", { tag: "@screenshot" }, async ({ uut, user }) => {
|
||||
await expect(uut).toMatchScreenshot("account.png");
|
||||
|
||||
// Assert that the top heading is rendered
|
||||
|
@ -71,7 +71,7 @@ test.describe("Account user settings tab", () => {
|
|||
);
|
||||
});
|
||||
|
||||
test("should respond to small screen sizes", async ({ page, uut }) => {
|
||||
test("should respond to small screen sizes", { tag: "@screenshot" }, async ({ page, uut }) => {
|
||||
await page.setViewportSize({ width: 700, height: 600 });
|
||||
await expect(uut).toMatchScreenshot("account-smallscreen.png");
|
||||
});
|
||||
|
|
|
@ -13,7 +13,7 @@ test.describe("Appearance user settings tab", () => {
|
|||
displayName: "Hanako",
|
||||
});
|
||||
|
||||
test("should be rendered properly", async ({ page, user, app }) => {
|
||||
test("should be rendered properly", { tag: "@screenshot" }, async ({ page, user, app }) => {
|
||||
const tab = await app.settings.openUserSettings("Appearance");
|
||||
|
||||
// Click "Show advanced" link button
|
||||
|
@ -25,7 +25,10 @@ test.describe("Appearance user settings tab", () => {
|
|||
await expect(tab).toMatchScreenshot("appearance-tab.png");
|
||||
});
|
||||
|
||||
test("should support changing font size by using the font size dropdown", async ({ page, app, user }) => {
|
||||
test(
|
||||
"should support changing font size by using the font size dropdown",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, user }) => {
|
||||
await app.settings.openUserSettings("Appearance");
|
||||
|
||||
const tab = page.getByTestId("mx_AppearanceUserSettingsTab");
|
||||
|
@ -37,7 +40,8 @@ test.describe("Appearance user settings tab", () => {
|
|||
await fontDropdown.getByLabel("Font size").selectOption({ value: "-4" });
|
||||
|
||||
await expect(page).toMatchScreenshot("window-12px.png", { includeDialogBackground: true });
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should support enabling system font", async ({ page, app, user }) => {
|
||||
await app.settings.openUserSettings("Appearance");
|
||||
|
|
|
@ -20,7 +20,10 @@ test.describe("Appearance user settings tab", () => {
|
|||
await util.openAppearanceTab();
|
||||
});
|
||||
|
||||
test("should change the message layout from modern to bubble", async ({ page, app, user, util }) => {
|
||||
test(
|
||||
"should change the message layout from modern to bubble",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, user, util }) => {
|
||||
await util.assertScreenshot(util.getMessageLayoutPanel(), "message-layout-panel-modern.png");
|
||||
|
||||
await util.getBubbleLayout().click();
|
||||
|
@ -33,7 +36,8 @@ test.describe("Appearance user settings tab", () => {
|
|||
// Assert that the room layout is set to bubble layout
|
||||
await util.assertBubbleLayout();
|
||||
await util.assertScreenshot(util.getMessageLayoutPanel(), "message-layout-panel-bubble.png");
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should enable compact layout when the modern layout is selected", async ({ page, app, user, util }) => {
|
||||
await expect(util.getCompactLayoutCheckbox()).not.toBeChecked();
|
||||
|
|
|
@ -20,7 +20,10 @@ test.describe("Appearance user settings tab", () => {
|
|||
await util.openAppearanceTab();
|
||||
});
|
||||
|
||||
test("should be rendered with the light theme selected", async ({ page, app, util }) => {
|
||||
test(
|
||||
"should be rendered with the light theme selected",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, util }) => {
|
||||
// Assert that 'Match system theme' is not checked
|
||||
await expect(util.getMatchSystemThemeCheckbox()).not.toBeChecked();
|
||||
|
||||
|
@ -31,9 +34,13 @@ test.describe("Appearance user settings tab", () => {
|
|||
await expect(util.getHighContrastTheme()).not.toBeChecked();
|
||||
|
||||
await expect(util.getThemePanel()).toMatchScreenshot("theme-panel-light.png");
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should disable the themes when the system theme is clicked", async ({ page, app, util }) => {
|
||||
test(
|
||||
"should disable the themes when the system theme is clicked",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, util }) => {
|
||||
await util.getMatchSystemThemeCheckbox().click();
|
||||
|
||||
// Assert that the themes are disabled
|
||||
|
@ -42,9 +49,10 @@ test.describe("Appearance user settings tab", () => {
|
|||
await expect(util.getHighContrastTheme()).toBeDisabled();
|
||||
|
||||
await expect(util.getThemePanel()).toMatchScreenshot("theme-panel-match-system-enabled.png");
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should change the theme to dark", async ({ page, app, util }) => {
|
||||
test("should change the theme to dark", { tag: "@screenshot" }, async ({ page, app, util }) => {
|
||||
// Assert that the light theme is selected
|
||||
await expect(util.getLightTheme()).toBeChecked();
|
||||
|
||||
|
@ -63,11 +71,14 @@ test.describe("Appearance user settings tab", () => {
|
|||
labsFlags: ["feature_custom_themes"],
|
||||
});
|
||||
|
||||
test("should render the custom theme section", async ({ page, app, util }) => {
|
||||
test("should render the custom theme section", { tag: "@screenshot" }, async ({ page, app, util }) => {
|
||||
await expect(util.getThemePanel()).toMatchScreenshot("theme-panel-custom-theme.png");
|
||||
});
|
||||
|
||||
test("should be able to add and remove a custom theme", async ({ page, app, util }) => {
|
||||
test(
|
||||
"should be able to add and remove a custom theme",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, util }) => {
|
||||
await util.addCustomTheme();
|
||||
|
||||
await expect(util.getCustomTheme()).not.toBeChecked();
|
||||
|
@ -75,7 +86,8 @@ test.describe("Appearance user settings tab", () => {
|
|||
|
||||
await util.removeCustomTheme();
|
||||
await expect(util.getThemePanel()).toMatchScreenshot("theme-panel-custom-theme-removed.png");
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -20,7 +20,7 @@ test.describe("General room settings tab", () => {
|
|||
await app.viewRoomByName(roomName);
|
||||
});
|
||||
|
||||
test("should be rendered properly", async ({ page, app }) => {
|
||||
test("should be rendered properly", { tag: "@screenshot" }, async ({ page, app }) => {
|
||||
const settings = await app.settings.openRoomSettings("General");
|
||||
|
||||
// Assert that "Show less" details element is rendered
|
||||
|
|
|
@ -23,7 +23,7 @@ test.describe("Preferences user settings tab", () => {
|
|||
},
|
||||
});
|
||||
|
||||
test("should be rendered properly", async ({ app, page, user }) => {
|
||||
test("should be rendered properly", { tag: "@screenshot" }, async ({ app, page, user }) => {
|
||||
page.setViewportSize({ width: 1024, height: 3300 });
|
||||
const tab = await app.settings.openUserSettings("Preferences");
|
||||
// Assert that the top heading is rendered
|
||||
|
|
|
@ -36,7 +36,7 @@ test.describe("Security user settings tab", () => {
|
|||
});
|
||||
|
||||
test.describe("AnalyticsLearnMoreDialog", () => {
|
||||
test("should be rendered properly", async ({ app, page }) => {
|
||||
test("should be rendered properly", { tag: "@screenshot" }, async ({ app, page }) => {
|
||||
const tab = await app.settings.openUserSettings("Security");
|
||||
await tab.getByRole("button", { name: "Learn more" }).click();
|
||||
await expect(page.locator(".mx_AnalyticsLearnMoreDialog_wrapper .mx_Dialog")).toMatchScreenshot(
|
||||
|
|
|
@ -16,7 +16,7 @@ test.describe("Share dialog", () => {
|
|||
},
|
||||
});
|
||||
|
||||
test("should share a room", async ({ page, app, room }) => {
|
||||
test("should share a room", { tag: "@screenshot" }, async ({ page, app, room }) => {
|
||||
await app.viewRoomById(room.roomId);
|
||||
await app.toggleRoomInfoPanel();
|
||||
await page.getByRole("menuitem", { name: "Copy link" }).click();
|
||||
|
@ -29,7 +29,7 @@ test.describe("Share dialog", () => {
|
|||
});
|
||||
});
|
||||
|
||||
test("should share a room member", async ({ page, app, room, user }) => {
|
||||
test("should share a room member", { tag: "@screenshot" }, async ({ page, app, room, user }) => {
|
||||
await app.viewRoomById(room.roomId);
|
||||
await app.client.sendMessage(room.roomId, { body: "hello", msgtype: "m.text" });
|
||||
|
||||
|
@ -46,7 +46,7 @@ test.describe("Share dialog", () => {
|
|||
});
|
||||
});
|
||||
|
||||
test("should share an event", async ({ page, app, room }) => {
|
||||
test("should share an event", { tag: "@screenshot" }, async ({ page, app, room }) => {
|
||||
await app.viewRoomById(room.roomId);
|
||||
await app.client.sendMessage(room.roomId, { body: "hello", msgtype: "m.text" });
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ test.describe("Spaces", () => {
|
|||
botCreateOpts: { displayName: "BotBob" },
|
||||
});
|
||||
|
||||
test("should allow user to create public space", async ({ page, app, user }) => {
|
||||
test("should allow user to create public space", { tag: "@screenshot" }, async ({ page, app, user }) => {
|
||||
const contextMenu = await openSpaceCreateMenu(page);
|
||||
await expect(contextMenu).toMatchScreenshot("space-create-menu.png");
|
||||
|
||||
|
@ -88,7 +88,7 @@ test.describe("Spaces", () => {
|
|||
await expect(page.getByRole("treeitem", { name: "Jokes" })).toBeVisible();
|
||||
});
|
||||
|
||||
test("should allow user to create private space", async ({ page, app, user }) => {
|
||||
test("should allow user to create private space", { tag: "@screenshot" }, async ({ page, app, user }) => {
|
||||
const menu = await openSpaceCreateMenu(page);
|
||||
await menu.getByRole("button", { name: "Private" }).click();
|
||||
|
||||
|
@ -216,13 +216,10 @@ test.describe("Spaces", () => {
|
|||
await expect(hierarchyList.getByRole("treeitem", { name: "Gaming" }).getByRole("button")).toBeVisible();
|
||||
});
|
||||
|
||||
test("should render subspaces in the space panel only when expanded", async ({
|
||||
page,
|
||||
app,
|
||||
user,
|
||||
axe,
|
||||
checkA11y,
|
||||
}) => {
|
||||
test(
|
||||
"should render subspaces in the space panel only when expanded",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, user, axe, checkA11y }) => {
|
||||
axe.disableRules([
|
||||
// Disable this check as it triggers on nested roving tab index elements which are in practice fine
|
||||
"nested-interactive",
|
||||
|
@ -258,7 +255,8 @@ test.describe("Spaces", () => {
|
|||
|
||||
await checkA11y();
|
||||
await expect(page.locator(".mx_SpacePanel")).toMatchScreenshot("space-panel-expanded.png");
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should not soft crash when joining a room from space hierarchy which has a link in its topic", async ({
|
||||
page,
|
||||
|
|
|
@ -16,16 +16,18 @@ test.describe("Threads Activity Centre", () => {
|
|||
labsFlags: ["threadsActivityCentre"],
|
||||
});
|
||||
|
||||
test("should have the button correctly aligned and displayed in the space panel when expanded", async ({
|
||||
util,
|
||||
}) => {
|
||||
test(
|
||||
"should have the button correctly aligned and displayed in the space panel when expanded",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ util }) => {
|
||||
// Open the space panel
|
||||
await util.expandSpacePanel();
|
||||
// The buttons in the space panel should be aligned when expanded
|
||||
await expect(util.getSpacePanel()).toMatchScreenshot("tac-button-expanded.png");
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should not show indicator when there is no thread", async ({ room1, util }) => {
|
||||
test("should not show indicator when there is no thread", { tag: "@screenshot" }, async ({ room1, util }) => {
|
||||
// No indicator should be shown
|
||||
await util.assertNoTacIndicator();
|
||||
|
||||
|
@ -62,7 +64,7 @@ test.describe("Threads Activity Centre", () => {
|
|||
await util.assertHighlightIndicator();
|
||||
});
|
||||
|
||||
test("should show the rooms with unread threads", async ({ room1, room2, util, msg }) => {
|
||||
test("should show the rooms with unread threads", { tag: "@screenshot" }, async ({ room1, room2, util, msg }) => {
|
||||
await util.goTo(room2);
|
||||
await util.populateThreads(room1, room2, msg);
|
||||
// The indicator should be shown
|
||||
|
@ -79,7 +81,7 @@ test.describe("Threads Activity Centre", () => {
|
|||
await expect(util.getTacPanel()).toMatchScreenshot("tac-panel-mix-unread.png");
|
||||
});
|
||||
|
||||
test("should update with a thread is read", async ({ room1, room2, util, msg }) => {
|
||||
test("should update with a thread is read", { tag: "@screenshot" }, async ({ room1, room2, util, msg }) => {
|
||||
await util.goTo(room2);
|
||||
await util.populateThreads(room1, room2, msg);
|
||||
|
||||
|
@ -128,7 +130,7 @@ test.describe("Threads Activity Centre", () => {
|
|||
await expect(page.locator(".mx_SpotlightDialog")).not.toBeVisible();
|
||||
});
|
||||
|
||||
test("should have the correct hover state", async ({ util, page }) => {
|
||||
test("should have the correct hover state", { tag: "@screenshot" }, async ({ util, page }) => {
|
||||
await util.hoverTacButton();
|
||||
await expect(util.getSpacePanel()).toMatchScreenshot("tac-hovered.png");
|
||||
|
||||
|
@ -138,7 +140,7 @@ test.describe("Threads Activity Centre", () => {
|
|||
await expect(util.getSpacePanel()).toMatchScreenshot("tac-hovered-expanded.png");
|
||||
});
|
||||
|
||||
test("should mark all threads as read", async ({ room1, room2, util, msg, page }) => {
|
||||
test("should mark all threads as read", { tag: "@screenshot" }, async ({ room1, room2, util, msg, page }) => {
|
||||
await util.receiveMessages(room1, ["Msg1", msg.threadedOff("Msg1", "Resp1")]);
|
||||
|
||||
await util.assertNotificationTac();
|
||||
|
|
|
@ -25,7 +25,7 @@ test.describe("Threads", () => {
|
|||
});
|
||||
|
||||
// Flaky: https://github.com/vector-im/element-web/issues/26452
|
||||
test.skip("should be usable for a conversation", async ({ page, app, bot }) => {
|
||||
test.skip("should be usable for a conversation", { tag: "@screenshot" }, async ({ page, app, bot }) => {
|
||||
const roomId = await app.client.createRoom({});
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
|
@ -150,7 +150,7 @@ test.describe("Threads", () => {
|
|||
).toHaveCSS("padding-inline-start", ThreadViewGroupSpacingStart);
|
||||
|
||||
// Take snapshot of group layout (IRC layout is not available on ThreadView)
|
||||
expect(page.locator(".mx_ThreadView")).toMatchScreenshot(
|
||||
await expect(page.locator(".mx_ThreadView")).toMatchScreenshot(
|
||||
"ThreadView_with_reaction_and_a_hidden_event_on_group_layout.png",
|
||||
{
|
||||
mask: mask,
|
||||
|
@ -174,7 +174,7 @@ test.describe("Threads", () => {
|
|||
.toHaveCSS("margin-inline-start", "0px");
|
||||
|
||||
// Take snapshot of bubble layout
|
||||
expect(page.locator(".mx_ThreadView")).toMatchScreenshot(
|
||||
await expect(page.locator(".mx_ThreadView")).toMatchScreenshot(
|
||||
"ThreadView_with_reaction_and_a_hidden_event_on_bubble_layout.png",
|
||||
{
|
||||
mask: mask,
|
||||
|
@ -351,7 +351,10 @@ test.describe("Threads", () => {
|
|||
});
|
||||
});
|
||||
|
||||
test("should send location and reply to the location on ThreadView", async ({ page, app, bot }) => {
|
||||
test(
|
||||
"should send location and reply to the location on ThreadView",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, bot }) => {
|
||||
const roomId = await app.client.createRoom({});
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
|
@ -401,7 +404,8 @@ test.describe("Threads", () => {
|
|||
// Take a snapshot of reply to the shared location
|
||||
await page.addStyleTag({ content: css });
|
||||
await expect(page.locator(".mx_ThreadView")).toMatchScreenshot("Reply_to_the_location_on_ThreadView.png");
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("right panel behaves correctly", async ({ page, app, user }) => {
|
||||
// Create room
|
||||
|
|
|
@ -137,7 +137,10 @@ test.describe("Timeline", () => {
|
|||
});
|
||||
|
||||
test.describe("configure room", () => {
|
||||
test("should create and configure a room on IRC layout", async ({ page, app, room }) => {
|
||||
test(
|
||||
"should create and configure a room on IRC layout",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room }) => {
|
||||
await page.goto(`/#/room/${room.roomId}`);
|
||||
await app.settings.setValue("layout", null, SettingLevel.DEVICE, Layout.IRC);
|
||||
await expect(
|
||||
|
@ -151,9 +154,13 @@ test.describe("Timeline", () => {
|
|||
await expect(page.locator(".mx_TimelineSeparator")).toHaveText("today");
|
||||
|
||||
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot("configured-room-irc-layout.png");
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should have an expanded generic event list summary (GELS) on IRC layout", async ({ page, app, room }) => {
|
||||
test(
|
||||
"should have an expanded generic event list summary (GELS) on IRC layout",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room }) => {
|
||||
await page.goto(`/#/room/${room.roomId}`);
|
||||
await app.settings.setValue("layout", null, SettingLevel.DEVICE, Layout.IRC);
|
||||
|
||||
|
@ -179,13 +186,13 @@ test.describe("Timeline", () => {
|
|||
}
|
||||
`,
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should have an expanded generic event list summary (GELS) on compact modern/group layout", async ({
|
||||
page,
|
||||
app,
|
||||
room,
|
||||
}) => {
|
||||
test(
|
||||
"should have an expanded generic event list summary (GELS) on compact modern/group layout",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room }) => {
|
||||
await page.goto(`/#/room/${room.roomId}`);
|
||||
|
||||
// Set compact modern layout
|
||||
|
@ -213,13 +220,13 @@ test.describe("Timeline", () => {
|
|||
}
|
||||
`,
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should click 'collapse' on the first hovered info event line inside GELS on bubble layout", async ({
|
||||
page,
|
||||
app,
|
||||
room,
|
||||
}) => {
|
||||
test(
|
||||
"should click 'collapse' on the first hovered info event line inside GELS on bubble layout",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room }) => {
|
||||
// This test checks clickability of the "Collapse" link button, which had been covered with
|
||||
// MessageActionBar's safe area - https://github.com/vector-im/element-web/issues/22864
|
||||
|
||||
|
@ -250,7 +257,9 @@ test.describe("Timeline", () => {
|
|||
});
|
||||
|
||||
// Click "collapse" link button on the first hovered info event line
|
||||
const firstTile = gels.locator(".mx_GenericEventListSummary_unstyledList .mx_EventTile_info:first-of-type");
|
||||
const firstTile = gels.locator(
|
||||
".mx_GenericEventListSummary_unstyledList .mx_EventTile_info:first-of-type",
|
||||
);
|
||||
await firstTile.hover();
|
||||
await expect(firstTile.getByRole("toolbar", { name: "Message Actions" })).toBeVisible();
|
||||
await gels.getByRole("button", { name: "Collapse" }).click();
|
||||
|
@ -262,15 +271,13 @@ test.describe("Timeline", () => {
|
|||
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot("collapsed-gels-bubble-layout.png", {
|
||||
mask: [page.locator(".mx_MessageTimestamp")],
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should add inline start margin to an event line on IRC layout", async ({
|
||||
page,
|
||||
app,
|
||||
room,
|
||||
axe,
|
||||
checkA11y,
|
||||
}) => {
|
||||
test(
|
||||
"should add inline start margin to an event line on IRC layout",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room, axe, checkA11y }) => {
|
||||
axe.disableRules("color-contrast");
|
||||
|
||||
await page.goto(`/#/room/${room.roomId}`);
|
||||
|
@ -312,7 +319,8 @@ test.describe("Timeline", () => {
|
|||
},
|
||||
);
|
||||
await checkA11y();
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test.describe("message displaying", () => {
|
||||
|
@ -332,11 +340,10 @@ test.describe("Timeline", () => {
|
|||
).toBeVisible();
|
||||
};
|
||||
|
||||
test("should align generic event list summary with messages and emote on IRC layout", async ({
|
||||
page,
|
||||
app,
|
||||
room,
|
||||
}) => {
|
||||
test(
|
||||
"should align generic event list summary with messages and emote on IRC layout",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room }) => {
|
||||
// This test aims to check:
|
||||
// 1. Alignment of collapsed GELS (generic event list summary) and messages
|
||||
// 2. Alignment of expanded GELS and messages
|
||||
|
@ -372,10 +379,9 @@ test.describe("Timeline", () => {
|
|||
// = var(--name-width) + var(--icon-width) + var(--MessageTimestamp-width) + 2 * var(--right-padding)
|
||||
// = 80 + 14 + 46 + 2 * 5
|
||||
// = 150px
|
||||
await expect(page.locator(".mx_GenericEventListSummary[data-layout=irc] > .mx_EventTile_line")).toHaveCSS(
|
||||
"padding-inline-start",
|
||||
"150px",
|
||||
);
|
||||
await expect(
|
||||
page.locator(".mx_GenericEventListSummary[data-layout=irc] > .mx_EventTile_line"),
|
||||
).toHaveCSS("padding-inline-start", "150px");
|
||||
// Check width and spacing values of elements in .mx_EventTile, which should be equal to 150px
|
||||
// --right-padding should be applied
|
||||
for (const locator of await page.locator(".mx_EventTile > a").all()) {
|
||||
|
@ -416,10 +422,13 @@ test.describe("Timeline", () => {
|
|||
page.locator(".mx_EventTile[data-layout=irc].mx_EventTile_info:first-of-type .mx_EventTile_line"),
|
||||
).toHaveCSS("margin-inline-start", "99px");
|
||||
// Record alignment of expanded GELS and messages on messagePanel
|
||||
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot("expanded-gels-and-messages-irc-layout.png", {
|
||||
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot(
|
||||
"expanded-gels-and-messages-irc-layout.png",
|
||||
{
|
||||
// Exclude timestamp from snapshot of mx_MainSplit
|
||||
mask: [page.locator(".mx_MessageTimestamp")],
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
// 3. Alignment of expanded GELS and placeholder of deleted message
|
||||
// Delete the second (last) message
|
||||
|
@ -431,15 +440,20 @@ test.describe("Timeline", () => {
|
|||
await page.locator(".mx_Dialog_buttons").getByRole("button", { name: "Remove" }).click();
|
||||
// Make sure the dialog was closed and the second (last) message was redacted
|
||||
await expect(page.locator(".mx_Dialog")).not.toBeVisible();
|
||||
await expect(page.locator(".mx_GenericEventListSummary .mx_EventTile_last .mx_RedactedBody")).toBeVisible();
|
||||
await expect(
|
||||
page.locator(".mx_GenericEventListSummary .mx_EventTile_last .mx_RedactedBody"),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator(".mx_GenericEventListSummary .mx_EventTile_last .mx_EventTile_receiptSent"),
|
||||
).toBeVisible();
|
||||
// Record alignment of expanded GELS and placeholder of deleted message on messagePanel
|
||||
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot("expanded-gels-redaction-placeholder.png", {
|
||||
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot(
|
||||
"expanded-gels-redaction-placeholder.png",
|
||||
{
|
||||
// Exclude timestamp from snapshot of mx_MainSplit
|
||||
mask: [page.locator(".mx_MessageTimestamp")],
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
// 4. Alignment of expanded GELS, placeholder of deleted message, and emote
|
||||
// Send a emote
|
||||
|
@ -447,7 +461,10 @@ test.describe("Timeline", () => {
|
|||
.locator(".mx_RoomView_body")
|
||||
.getByRole("textbox", { name: "Send a message…" })
|
||||
.fill("/me says hello to Mr. Bot");
|
||||
await page.locator(".mx_RoomView_body").getByRole("textbox", { name: "Send a message…" }).press("Enter");
|
||||
await page
|
||||
.locator(".mx_RoomView_body")
|
||||
.getByRole("textbox", { name: "Send a message…" })
|
||||
.press("Enter");
|
||||
// Check inline start margin of its avatar
|
||||
// Here --right-padding is for the avatar on the message line
|
||||
// See: _IRCLayout.pcss
|
||||
|
@ -456,15 +473,21 @@ test.describe("Timeline", () => {
|
|||
// = 80 + 14 + 1 * 5
|
||||
await expect(page.locator(".mx_EventTile_emote .mx_EventTile_avatar")).toHaveCSS("margin-left", "99px");
|
||||
// Make sure emote was sent
|
||||
await expect(page.locator(".mx_EventTile_last.mx_EventTile_emote .mx_EventTile_receiptSent")).toBeVisible();
|
||||
await expect(
|
||||
page.locator(".mx_EventTile_last.mx_EventTile_emote .mx_EventTile_receiptSent"),
|
||||
).toBeVisible();
|
||||
// Record alignment of expanded GELS, placeholder of deleted message, and emote
|
||||
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot("expanded-gels-emote-irc-layout.png", {
|
||||
// Exclude timestamp from snapshot of mx_MainSplit
|
||||
mask: [page.locator(".mx_MessageTimestamp")],
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should render EventTiles on IRC, modern (group), and bubble layout", async ({ page, app, room }) => {
|
||||
test(
|
||||
"should render EventTiles on IRC, modern (group), and bubble layout",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room }) => {
|
||||
const screenshotOptions = {
|
||||
// Hide because flaky - See https://github.com/vector-im/element-web/issues/24957
|
||||
mask: [page.locator(".mx_MessageTimestamp")],
|
||||
|
@ -491,7 +514,9 @@ test.describe("Timeline", () => {
|
|||
await composer.fill("This message has an inline emoji 👒");
|
||||
await composer.press("Enter");
|
||||
|
||||
await expect(page.locator(".mx_RoomView").getByText("This message has an inline emoji 👒")).toBeVisible();
|
||||
await expect(
|
||||
page.locator(".mx_RoomView").getByText("This message has an inline emoji 👒"),
|
||||
).toBeVisible();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// IRC layout
|
||||
|
@ -558,9 +583,13 @@ test.describe("Timeline", () => {
|
|||
"event-tiles-bubble-layout.png",
|
||||
screenshotOptions,
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should set inline start padding to a hidden event line", async ({ page, app, room }) => {
|
||||
test(
|
||||
"should set inline start padding to a hidden event line",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room }) => {
|
||||
test.skip(
|
||||
true,
|
||||
"Disabled due to screenshot test being flaky - https://github.com/element-hq/element-web/issues/26890",
|
||||
|
@ -612,9 +641,10 @@ test.describe("Timeline", () => {
|
|||
"hidden-event-line-padding-modern-layout.png",
|
||||
screenshotOptions,
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should click view source event toggle", async ({ page, app, room }) => {
|
||||
test("should click view source event toggle", { tag: "@screenshot" }, async ({ page, app, room }) => {
|
||||
// This test checks:
|
||||
// 1. clickability of top left of view source event toggle
|
||||
// 2. clickability of view source toggle on IRC layout
|
||||
|
@ -712,7 +742,10 @@ test.describe("Timeline", () => {
|
|||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("should render url previews", async ({ page, app, room, axe, checkA11y, context }) => {
|
||||
test(
|
||||
"should render url previews",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room, axe, checkA11y, context }) => {
|
||||
axe.disableRules("color-contrast");
|
||||
|
||||
// Element Web uses a Service Worker to rewrite unauthenticated media requests to authenticated ones, but
|
||||
|
@ -769,10 +802,14 @@ test.describe("Timeline", () => {
|
|||
}
|
||||
`,
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test.describe("on search results panel", () => {
|
||||
test("should highlight search result words regardless of formatting", async ({ page, app, room }) => {
|
||||
test(
|
||||
"should highlight search result words regardless of formatting",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room }) => {
|
||||
await sendEvent(app.client, room.roomId);
|
||||
await sendEvent(app.client, room.roomId, true);
|
||||
await page.goto(`/#/room/${room.roomId}`);
|
||||
|
@ -792,9 +829,10 @@ test.describe("Timeline", () => {
|
|||
await expect(page.locator(".mx_RoomView_searchResultsPanel")).toMatchScreenshot(
|
||||
"highlighted-search-results.png",
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("should render a fully opaque textual event", async ({ page, app, room }) => {
|
||||
test("should render a fully opaque textual event", { tag: "@screenshot" }, async ({ page, app, room }) => {
|
||||
const stringToSearch = "Message"; // Same with string sent with sendEvent()
|
||||
|
||||
await sendEvent(app.client, room.roomId);
|
||||
|
@ -918,7 +956,7 @@ test.describe("Timeline", () => {
|
|||
).toHaveCount(4);
|
||||
});
|
||||
|
||||
test("should display a reply chain", async ({ page, app, room, homeserver }) => {
|
||||
test("should display a reply chain", { tag: "@screenshot" }, async ({ page, app, room, homeserver }) => {
|
||||
const reply2 = "Reply again";
|
||||
|
||||
await page.goto(`/#/room/${room.roomId}`);
|
||||
|
@ -1031,12 +1069,10 @@ test.describe("Timeline", () => {
|
|||
);
|
||||
});
|
||||
|
||||
test("should send, reply, and display long strings without overflowing", async ({
|
||||
page,
|
||||
app,
|
||||
room,
|
||||
homeserver,
|
||||
}) => {
|
||||
test(
|
||||
"should send, reply, and display long strings without overflowing",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room, homeserver }) => {
|
||||
// Max 256 characters for display name
|
||||
const LONG_STRING =
|
||||
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut " +
|
||||
|
@ -1146,7 +1182,8 @@ test.describe("Timeline", () => {
|
|||
"long-strings-with-reply-bubble-layout.png",
|
||||
screenshotOptions,
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
async function testImageRendering(page: Page, app: ElementAppPage, room: { roomId: string }) {
|
||||
await app.viewRoomById(room.roomId);
|
||||
|
@ -1176,7 +1213,7 @@ test.describe("Timeline", () => {
|
|||
);
|
||||
}
|
||||
|
||||
test("should render images in the timeline", async ({ page, app, room, context }) => {
|
||||
test("should render images in the timeline", { tag: "@screenshot" }, async ({ page, app, room, context }) => {
|
||||
await testImageRendering(page, app, room);
|
||||
});
|
||||
|
||||
|
@ -1188,7 +1225,10 @@ test.describe("Timeline", () => {
|
|||
// In practice, this means this test will *always* succeed because it ends up relying on fallback behaviour tested
|
||||
// above (unless of course the above tests are also broken).
|
||||
test.describe("MSC3916 - Authenticated Media", () => {
|
||||
test("should render authenticated images in the timeline", async ({ page, app, room, context }) => {
|
||||
test(
|
||||
"should render authenticated images in the timeline",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room, context }) => {
|
||||
// Note: we have to use `context` instead of `page` for routing, otherwise we'll miss Service Worker events.
|
||||
// See https://playwright.dev/docs/service-workers-experimental#network-events-and-routing
|
||||
|
||||
|
@ -1231,7 +1271,8 @@ test.describe("Timeline", () => {
|
|||
|
||||
// We check the same screenshot because there should be no user-visible impact to using authentication.
|
||||
await testImageRendering(page, app, room);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -11,7 +11,7 @@ import { test, expect } from "../../element-web-test";
|
|||
test.describe("User Menu", () => {
|
||||
test.use({ displayName: "Jeff" });
|
||||
|
||||
test("should contain our name & userId", async ({ page, user }) => {
|
||||
test("should contain our name & userId", { tag: "@screenshot" }, async ({ page, user }) => {
|
||||
await page.getByRole("button", { name: "User menu", exact: true }).click();
|
||||
const menu = page.getByRole("menu");
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ test.describe("User Onboarding (new user)", () => {
|
|||
await expect(page.locator(".mx_UserOnboardingList")).toBeVisible();
|
||||
});
|
||||
|
||||
test("page is shown and preference exists", async ({ page, app }) => {
|
||||
test("page is shown and preference exists", { tag: "@screenshot" }, async ({ page, app }) => {
|
||||
await expect(page.locator(".mx_UserOnboardingPage")).toMatchScreenshot(
|
||||
"User-Onboarding-new-user-page-is-shown-and-preference-exists-1.png",
|
||||
);
|
||||
|
@ -34,7 +34,7 @@ test.describe("User Onboarding (new user)", () => {
|
|||
await expect(page.getByText("Show shortcut to welcome checklist above the room list")).toBeVisible();
|
||||
});
|
||||
|
||||
test("app download dialog", async ({ page }) => {
|
||||
test("app download dialog", { tag: "@screenshot" }, async ({ page }) => {
|
||||
await page.getByRole("button", { name: "Download apps" }).click();
|
||||
await expect(
|
||||
page.getByRole("dialog").getByRole("heading", { level: 1, name: "Download Element" }),
|
||||
|
|
|
@ -14,7 +14,7 @@ test.describe("UserView", () => {
|
|||
botCreateOpts: { displayName: "Usman" },
|
||||
});
|
||||
|
||||
test("should render the user view as expected", async ({ page, homeserver, user, bot }) => {
|
||||
test("should render the user view as expected", { tag: "@screenshot" }, async ({ page, homeserver, user, bot }) => {
|
||||
await page.goto(`/#/user/${bot.credentials.userId}`);
|
||||
|
||||
const rightPanel = page.locator("#mx_RightPanel");
|
||||
|
|
|
@ -70,7 +70,7 @@ test.describe("Widget Layout", () => {
|
|||
await app.viewRoomByName(ROOM_NAME);
|
||||
});
|
||||
|
||||
test("should be set properly", async ({ page }) => {
|
||||
test("should be set properly", { tag: "@screenshot" }, async ({ page }) => {
|
||||
await expect(page.locator(".mx_AppsDrawer")).toMatchScreenshot("apps-drawer.png");
|
||||
});
|
||||
|
||||
|
|
|
@ -314,6 +314,10 @@ export const expect = baseExpect.extend({
|
|||
const testInfo = test.info();
|
||||
if (!testInfo) throw new Error(`toMatchScreenshot() must be called during the test`);
|
||||
|
||||
if (!testInfo.tags.includes("@screenshot")) {
|
||||
throw new Error("toMatchScreenshot() must be used in a test tagged with @screenshot");
|
||||
}
|
||||
|
||||
const page = "page" in receiver ? receiver.page() : receiver;
|
||||
|
||||
let css = `
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue