Screenshot and snapshot tests for event list summaries (#32788)
* Playwright tests for the event list summary * Add snapshots for event summary tests
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* Copyright 2026 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { type Page } from "playwright-core";
|
||||
import { type StartedHomeserverContainer } from "@element-hq/element-web-playwright-common/lib/testcontainers";
|
||||
|
||||
import { test, expect } from "../../element-web-test";
|
||||
import { Bot } from "../../pages/bot";
|
||||
import { type ElementAppPage } from "../../pages/ElementAppPage";
|
||||
import { type Credentials } from "../../plugins/homeserver";
|
||||
|
||||
test.describe("Event List Summary", () => {
|
||||
test.use({
|
||||
displayName: "Finch",
|
||||
});
|
||||
|
||||
test(
|
||||
"should display a single join message on its own",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ app, homeserver, page, user }) => {
|
||||
const { bot, roomId } = await setupRoom(app, homeserver, page, user);
|
||||
|
||||
// When the bot joins the room
|
||||
await bot.joinRoom(roomId);
|
||||
|
||||
// Then we say that in a generic event list summary
|
||||
await expect(
|
||||
page.locator(".mx_RoomView_body .mx_GenericEventListSummary[data-layout='group']", {
|
||||
hasText: "MyBot joined the room",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
await replaceBotIds(page, bot);
|
||||
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot("bot_joined_the_room.png", ignoreTimestamps);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
"should display a single ban message on its own",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ app, homeserver, page, user }) => {
|
||||
const { bot, roomId } = await setupRoom(app, homeserver, page, user);
|
||||
|
||||
// Given the bot is in the room
|
||||
await bot.joinRoom(roomId);
|
||||
await expect(
|
||||
page.locator(".mx_RoomView_body .mx_GenericEventListSummary[data-layout='group']", {
|
||||
hasText: "MyBot joined the room",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
// And we said something to separate out the messages
|
||||
await app.client.sendMessage(roomId, "Saying something");
|
||||
|
||||
// When we ban the bot
|
||||
await app.client.ban(roomId, bot.credentials.userId);
|
||||
|
||||
// Then we say that
|
||||
await expect(
|
||||
page.locator(".mx_RoomView_body .mx_GenericEventListSummary[data-layout='group']", {
|
||||
hasText: "banned",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
await replaceBotIds(page, bot);
|
||||
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot("bot_was_banned.png", ignoreTimestamps);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
"should display multiple join/leave messages as a group",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ app, homeserver, page, user }) => {
|
||||
const { bot, roomId } = await setupRoom(app, homeserver, page, user);
|
||||
|
||||
// Given the bot is in the room
|
||||
await bot.joinRoom(roomId);
|
||||
await expect(
|
||||
page.locator(".mx_RoomView_body .mx_GenericEventListSummary[data-layout='group']", {
|
||||
hasText: "MyBot joined the room",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
// When we perform multiple actions on it
|
||||
await app.client.kick(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
|
||||
// Then those actions are gathered into a single summary
|
||||
await expect(
|
||||
page.locator(".mx_RoomView_body .mx_GenericEventListSummary[data-layout='group']", {
|
||||
hasText: "and joined",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
await replaceBotIds(page, bot);
|
||||
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot(
|
||||
"multiple_join_leave_messages.png",
|
||||
ignoreTimestamps,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
"should display multiple messages as a group",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ app, homeserver, page, user }) => {
|
||||
const { bot, roomId } = await setupRoom(app, homeserver, page, user);
|
||||
|
||||
// Given the bot is in the room
|
||||
await bot.joinRoom(roomId);
|
||||
await expect(
|
||||
page.locator(".mx_RoomView_body .mx_GenericEventListSummary[data-layout='group']", {
|
||||
hasText: "MyBot joined the room",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
// When we perform multiple actions on it, including a ban
|
||||
await app.client.ban(roomId, bot.credentials.userId);
|
||||
await app.client.unban(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
|
||||
// Then those actions are gathered into a single summary
|
||||
await expect(
|
||||
page.locator(".mx_RoomView_body .mx_GenericEventListSummary[data-layout='group']", {
|
||||
hasText: "and joined",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
await replaceBotIds(page, bot);
|
||||
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot(
|
||||
"multiple_join_ban_messages.png",
|
||||
ignoreTimestamps,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
"should display join/leave messages for multiple people as a group",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ app, homeserver, page, user }) => {
|
||||
const { bot, roomId } = await setupRoom(app, homeserver, page, user);
|
||||
|
||||
// Given the bot is in the room
|
||||
const bot2 = new Bot(page, homeserver, {
|
||||
displayName: "MyBot2",
|
||||
autoAcceptInvites: false,
|
||||
});
|
||||
await bot2.prepareClient();
|
||||
await app.client.inviteUser(roomId, bot2.credentials.userId);
|
||||
await app.client.sendMessage(roomId, "I invited MyBot2...");
|
||||
await bot.joinRoom(roomId);
|
||||
await bot2.joinRoom(roomId);
|
||||
await expect(
|
||||
page.locator(".mx_RoomView_body .mx_GenericEventListSummary[data-layout='group']", {
|
||||
hasText: "MyBot2 joined the room",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
// When we perform multiple actions on both bots
|
||||
await app.client.kick(roomId, bot.credentials.userId);
|
||||
await app.client.kick(roomId, bot2.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot2.credentials.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
await bot2.joinRoom(roomId);
|
||||
|
||||
// Then those actions are gathered into a single summary
|
||||
await expect(
|
||||
page.locator(".mx_RoomView_body .mx_GenericEventListSummary[data-layout='group']", {
|
||||
hasText: "joined, were removed, were invited, and joined",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
await expect(page.locator('div[aria-label="3 members"]')).toBeVisible();
|
||||
|
||||
await replaceBotIds(page, bot, bot2);
|
||||
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot(
|
||||
"multiple_people_join_leave_messages.png",
|
||||
ignoreTimestampsRightColumnAndHeader,
|
||||
);
|
||||
|
||||
// And when we expand the summary
|
||||
// Note: we can't include "expand" in the screenshot because it
|
||||
// moves around, but at least we know it exists because we click it
|
||||
// here.
|
||||
await page.getByRole("button", { name: "expand" }).nth(3).click();
|
||||
|
||||
// Then we see all the individual actions
|
||||
await expect(
|
||||
page.locator(".mx_RoomView_body .mx_GenericEventListSummary[data-layout='group']", {
|
||||
hasText: "removed MyBot2",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
await replaceBotIds(page, bot, bot2);
|
||||
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot(
|
||||
"multiple_people_join_leave_messages_expanded.png",
|
||||
ignoreTimestampsRightColumnAndHeader,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
"should display join/ban messages for multiple people as a group",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ app, homeserver, page, user }) => {
|
||||
const { bot, roomId } = await setupRoom(app, homeserver, page, user);
|
||||
|
||||
// Given the bot is in the room
|
||||
const bot2 = new Bot(page, homeserver, {
|
||||
displayName: "MyBot2 with very long display name causing wrapping",
|
||||
autoAcceptInvites: false,
|
||||
});
|
||||
await bot2.prepareClient();
|
||||
await app.client.inviteUser(roomId, bot2.credentials.userId);
|
||||
await app.client.sendMessage(roomId, "I invited MyBot2...");
|
||||
await bot.joinRoom(roomId);
|
||||
await bot2.joinRoom(roomId);
|
||||
await expect(
|
||||
page.locator(".mx_RoomView_body .mx_GenericEventListSummary[data-layout='group']", {
|
||||
hasText: "MyBot2 with very long display name causing wrapping joined the room",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
// When we ban bot1 but not bot2
|
||||
await app.client.ban(roomId, bot.credentials.userId);
|
||||
await app.client.unban(roomId, bot.credentials.userId);
|
||||
await app.client.kick(roomId, bot2.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.inviteUser(roomId, bot2.credentials.userId);
|
||||
await bot.joinRoom(roomId);
|
||||
await bot2.joinRoom(roomId);
|
||||
|
||||
// Then those actions are gathered into a single summary
|
||||
await expect(
|
||||
page.locator(".mx_RoomView_body .mx_GenericEventListSummary[data-layout='group']", {
|
||||
hasText: "was removed, was invited, and joined",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
await expect(page.locator('div[aria-label="3 members"]')).toBeVisible();
|
||||
|
||||
await replaceBotIds(page, bot, bot2);
|
||||
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot(
|
||||
"multiple_people_ban_messages.png",
|
||||
ignoreTimestampsRightColumnAndHeader,
|
||||
);
|
||||
|
||||
// And when we expand the summary
|
||||
// Note: we can't include "expand" in the screenshot because it
|
||||
// moves around, but at least we know it exists because we click it
|
||||
// here.
|
||||
await page.getByRole("button", { name: "expand" }).nth(3).click();
|
||||
|
||||
// Then we see all the individual actions
|
||||
await expect(
|
||||
page.locator(".mx_RoomView_body .mx_GenericEventListSummary[data-layout='group']", {
|
||||
hasText: "removed MyBot2",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
await replaceBotIds(page, bot, bot2);
|
||||
await expect(page.locator(".mx_MainSplit")).toMatchScreenshot(
|
||||
"multiple_people_ban_messages_expanded.png",
|
||||
ignoreTimestampsRightColumnAndHeader,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
const ignoreTimestamps = {
|
||||
css: ".mx_MessageTimestamp,.mx_TopUnreadMessagesBar { visibility: hidden; },",
|
||||
};
|
||||
|
||||
const ignoreTimestampsRightColumnAndHeader = {
|
||||
css:
|
||||
".mx_MessageTimestamp," +
|
||||
".mx_GenericEventListSummary_toggle," +
|
||||
".mx_ReadReceiptGroup," +
|
||||
".mx_RoomHeader, " +
|
||||
".mx_TopUnreadMessagesBar " +
|
||||
"{ visibility: hidden; }",
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a room, join it, create a bot and invite it to the room.
|
||||
*/
|
||||
async function setupRoom(app: ElementAppPage, homeserver: StartedHomeserverContainer, page: Page, user: Credentials) {
|
||||
const roomId = await app.client.createRoom({ name: "My room" });
|
||||
await page.goto(`/#/room/${roomId}`);
|
||||
|
||||
await expect(
|
||||
page.locator(".mx_RoomView_body .mx_GenericEventListSummary[data-layout='group']", {
|
||||
hasText: `${user.displayName} created and configured the room.`,
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
const bot = new Bot(page, homeserver, {
|
||||
displayName: "MyBot",
|
||||
autoAcceptInvites: false,
|
||||
});
|
||||
await bot.prepareClient();
|
||||
await app.client.inviteUser(roomId, bot.credentials.userId);
|
||||
await app.client.sendMessage(roomId, "I invited MyBot...");
|
||||
|
||||
return { bot, roomId };
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the ID of the supplied bot in the page and replace it with a known string.
|
||||
*
|
||||
* This allows us to create consistent screenshots.
|
||||
*/
|
||||
async function replaceBotIds(page: Page, bot: Bot, bot2?: Bot) {
|
||||
await page.evaluate(
|
||||
([bot1UserId, bot2UserId]) => {
|
||||
for (const el of document.querySelectorAll("div.mx_TextualEvent")) {
|
||||
if ("innerText" in el) {
|
||||
el.innerText = (el.innerText as any as string).replaceAll(bot1UserId, "<<replaced_bot1_id>>");
|
||||
el.innerText = (el.innerText as any as string).replaceAll(bot2UserId, "<<replaced_bot2_id>>");
|
||||
}
|
||||
}
|
||||
},
|
||||
[bot.credentials.userId, bot2?.credentials?.userId ?? "no_bot_2_to_replace"],
|
||||
);
|
||||
}
|
||||
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 43 KiB |
@@ -154,6 +154,7 @@ describe("EventListSummary", function () {
|
||||
const children = container.querySelector(".mx_GenericEventListSummary_unstyledList")!.children;
|
||||
expect(children).toHaveLength(1);
|
||||
expect(children[0]).toHaveTextContent("Expanded membership");
|
||||
expect(children).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders expanded events if there are less than props.threshold for join and leave", function () {
|
||||
@@ -175,6 +176,7 @@ describe("EventListSummary", function () {
|
||||
expect(children).toHaveLength(2);
|
||||
expect(children[0]).toHaveTextContent("Expanded membership");
|
||||
expect(children[1]).toHaveTextContent("Expanded membership");
|
||||
expect(children).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders collapsed events if events.length = props.threshold", function () {
|
||||
@@ -194,6 +196,7 @@ describe("EventListSummary", function () {
|
||||
const { container } = renderComponent(props);
|
||||
const summary = container.querySelector(".mx_GenericEventListSummary_summary");
|
||||
expect(summary).toHaveTextContent("user_1 joined and left and joined");
|
||||
expect(summary).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("truncates long join,leave repetitions", function () {
|
||||
@@ -224,6 +227,7 @@ describe("EventListSummary", function () {
|
||||
const { container } = renderComponent(props);
|
||||
const summary = container.querySelector(".mx_GenericEventListSummary_summary");
|
||||
expect(summary).toHaveTextContent("user_1 joined and left 7 times");
|
||||
expect(summary).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("truncates long join,leave repetitions between other events", function () {
|
||||
@@ -266,6 +270,7 @@ describe("EventListSummary", function () {
|
||||
const { container } = renderComponent(props);
|
||||
const summary = container.querySelector(".mx_GenericEventListSummary_summary");
|
||||
expect(summary).toHaveTextContent("user_1 was unbanned, joined and left 7 times and was invited");
|
||||
expect(summary).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("truncates multiple sequences of repetitions with other events between", function () {
|
||||
@@ -312,6 +317,7 @@ describe("EventListSummary", function () {
|
||||
expect(summary).toHaveTextContent(
|
||||
"user_1 was unbanned, joined and left 2 times, was banned, " + "joined and left 3 times and was invited",
|
||||
);
|
||||
expect(summary).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("handles multiple users following the same sequence of memberships", function () {
|
||||
@@ -364,6 +370,7 @@ describe("EventListSummary", function () {
|
||||
expect(summary).toHaveTextContent(
|
||||
"user_1 and one other were unbanned, joined and left 2 times and were banned",
|
||||
);
|
||||
expect(summary).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("handles many users following the same sequence of memberships", function () {
|
||||
@@ -396,6 +403,7 @@ describe("EventListSummary", function () {
|
||||
expect(summary).toHaveTextContent(
|
||||
"user_0 and 19 others were unbanned, joined and left 2 times and were banned",
|
||||
);
|
||||
expect(summary).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("correctly orders sequences of transitions by the order of their first event", function () {
|
||||
@@ -441,6 +449,7 @@ describe("EventListSummary", function () {
|
||||
"user_2 was unbanned and joined and left 2 times, user_1 was unbanned, " +
|
||||
"joined and left 2 times and was banned",
|
||||
);
|
||||
expect(summary).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("correctly identifies transitions", function () {
|
||||
@@ -509,6 +518,7 @@ describe("EventListSummary", function () {
|
||||
"user_1 was invited, was banned, joined, rejected their invitation, left, " +
|
||||
"had their invitation withdrawn, was unbanned, was removed, left and was removed",
|
||||
);
|
||||
expect(summary).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("handles invitation plurals correctly when there are multiple users", function () {
|
||||
@@ -549,6 +559,7 @@ describe("EventListSummary", function () {
|
||||
expect(summary).toHaveTextContent(
|
||||
"user_1 and one other rejected their invitations and had their invitations withdrawn",
|
||||
);
|
||||
expect(summary).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("handles invitation plurals correctly when there are multiple invites", function () {
|
||||
@@ -575,6 +586,7 @@ describe("EventListSummary", function () {
|
||||
const { container } = renderComponent(props);
|
||||
const summary = container.querySelector(".mx_GenericEventListSummary_summary");
|
||||
expect(summary).toHaveTextContent("user_1 rejected their invitation 2 times");
|
||||
expect(summary).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('handles a summary length = 2, with no "others"', function () {
|
||||
@@ -595,6 +607,7 @@ describe("EventListSummary", function () {
|
||||
const { container } = renderComponent(props);
|
||||
const summary = container.querySelector(".mx_GenericEventListSummary_summary");
|
||||
expect(summary).toHaveTextContent("user_1 and user_2 joined 2 times");
|
||||
expect(summary).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('handles a summary length = 2, with 1 "other"', function () {
|
||||
@@ -614,6 +627,7 @@ describe("EventListSummary", function () {
|
||||
const { container } = renderComponent(props);
|
||||
const summary = container.querySelector(".mx_GenericEventListSummary_summary");
|
||||
expect(summary).toHaveTextContent("user_1, user_2 and one other joined");
|
||||
expect(summary).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('handles a summary length = 2, with many "others"', function () {
|
||||
@@ -629,6 +643,7 @@ describe("EventListSummary", function () {
|
||||
const { container } = renderComponent(props);
|
||||
const summary = container.querySelector(".mx_GenericEventListSummary_summary");
|
||||
expect(summary).toHaveTextContent("user_0, user_1 and 18 others joined");
|
||||
expect(summary).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should not blindly group 3pid invites and treat them as distinct users instead", () => {
|
||||
@@ -679,5 +694,6 @@ describe("EventListSummary", function () {
|
||||
const { container } = renderComponent(props);
|
||||
const summary = container.querySelector(".mx_GenericEventListSummary_summary");
|
||||
expect(summary).toHaveTextContent("n...@d... was invited 2 times, d...@w... was invited");
|
||||
expect(summary).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`EventListSummary correctly identifies transitions 1`] = `
|
||||
<span
|
||||
class="mx_TextualEvent mx_GenericEventListSummary_summary"
|
||||
>
|
||||
user_1 was invited, was banned, joined, rejected their invitation, left, had their invitation withdrawn, was unbanned, was removed, left and was removed
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`EventListSummary correctly orders sequences of transitions by the order of their first event 1`] = `
|
||||
<span
|
||||
class="mx_TextualEvent mx_GenericEventListSummary_summary"
|
||||
>
|
||||
user_2 was unbanned and joined and left 2 times
|
||||
,
|
||||
user_1 was unbanned, joined and left 2 times and was banned
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`EventListSummary handles a summary length = 2, with 1 "other" 1`] = `
|
||||
<span
|
||||
class="mx_TextualEvent mx_GenericEventListSummary_summary"
|
||||
>
|
||||
user_1, user_2 and one other joined
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`EventListSummary handles a summary length = 2, with many "others" 1`] = `
|
||||
<span
|
||||
class="mx_TextualEvent mx_GenericEventListSummary_summary"
|
||||
>
|
||||
user_0, user_1 and 18 others joined
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`EventListSummary handles a summary length = 2, with no "others" 1`] = `
|
||||
<span
|
||||
class="mx_TextualEvent mx_GenericEventListSummary_summary"
|
||||
>
|
||||
user_1 and user_2 joined 2 times
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`EventListSummary handles invitation plurals correctly when there are multiple invites 1`] = `
|
||||
<span
|
||||
class="mx_TextualEvent mx_GenericEventListSummary_summary"
|
||||
>
|
||||
user_1 rejected their invitation 2 times
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`EventListSummary handles invitation plurals correctly when there are multiple users 1`] = `
|
||||
<span
|
||||
class="mx_TextualEvent mx_GenericEventListSummary_summary"
|
||||
>
|
||||
user_1 and one other rejected their invitations and had their invitations withdrawn
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`EventListSummary handles many users following the same sequence of memberships 1`] = `
|
||||
<span
|
||||
class="mx_TextualEvent mx_GenericEventListSummary_summary"
|
||||
>
|
||||
user_0 and 19 others were unbanned, joined and left 2 times and were banned
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`EventListSummary handles multiple users following the same sequence of memberships 1`] = `
|
||||
<span
|
||||
class="mx_TextualEvent mx_GenericEventListSummary_summary"
|
||||
>
|
||||
user_1 and one other were unbanned, joined and left 2 times and were banned
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`EventListSummary renders collapsed events if events.length = props.threshold 1`] = `
|
||||
<span
|
||||
class="mx_TextualEvent mx_GenericEventListSummary_summary"
|
||||
>
|
||||
user_1 joined and left and joined
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`EventListSummary renders expanded events if there are less than props.threshold 1`] = `
|
||||
HTMLCollection [
|
||||
<div
|
||||
class="event_tile"
|
||||
>
|
||||
Expanded membership
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`EventListSummary renders expanded events if there are less than props.threshold for join and leave 1`] = `
|
||||
HTMLCollection [
|
||||
<div
|
||||
class="event_tile"
|
||||
>
|
||||
Expanded membership
|
||||
</div>,
|
||||
<div
|
||||
class="event_tile"
|
||||
>
|
||||
Expanded membership
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`EventListSummary should not blindly group 3pid invites and treat them as distinct users instead 1`] = `
|
||||
<span
|
||||
class="mx_TextualEvent mx_GenericEventListSummary_summary"
|
||||
>
|
||||
n...@d... was invited 2 times
|
||||
,
|
||||
d...@w... was invited
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`EventListSummary truncates long join,leave repetitions 1`] = `
|
||||
<span
|
||||
class="mx_TextualEvent mx_GenericEventListSummary_summary"
|
||||
>
|
||||
user_1 joined and left 7 times
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`EventListSummary truncates long join,leave repetitions between other events 1`] = `
|
||||
<span
|
||||
class="mx_TextualEvent mx_GenericEventListSummary_summary"
|
||||
>
|
||||
user_1 was unbanned, joined and left 7 times and was invited
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`EventListSummary truncates multiple sequences of repetitions with other events between 1`] = `
|
||||
<span
|
||||
class="mx_TextualEvent mx_GenericEventListSummary_summary"
|
||||
>
|
||||
user_1 was unbanned, joined and left 2 times, was banned, joined and left 3 times and was invited
|
||||
</span>
|
||||
`;
|
||||