Files
ThreadNet-Web/playwright/e2e/room/room-status-bar.spec.ts
T
Will HuntandGitHub 2e6cf8734b Refactor RoomStatusBar into MVVM (#31523)
* Refactor RoomStatusBar into MVVM

* cleanup

* updated snaps

* More cleanup

* fix loop

* fixup

* drop comment

* lint

* cleanup console statements

* Starting to move to a MVVM v2 component.

* extra

* Refactor as a shared-componend / MVVM v2

* some cleanup

* i18n for banner

* remove removed css

* Update playwright tests to have a two stage on the consent bar.

* Update snaps

* Update snapshots

* cleanup

* update snaps

* refactor to use enum

* fix slight differences in pw snaps

* Add unit tests

* fix snaps

* snaps updated

* more test cleanups

* fix snaps

* fixed now?

* Disable animationsq

* lint lint lint

* remove console

* lint

* fix snap

* Refactor based on review comments.

* update view model test

* oops!

* fix snap

* Update snaps

* snap snap snap

* switch to a const map of strings

* Use this.disposables

* Update translations to be inside shared-components

* fix the tac

* Also retry

* Cleanup

* update snaps

* update other snaps

* snap updates
2026-01-12 21:13:15 +00:00

182 lines
8.0 KiB
TypeScript

/*
Copyright 2025 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 { test, expect } from "../../element-web-test";
test.describe("Room Status Bar", () => {
test.use({
displayName: "Jim",
page: async ({ page }, use) => {
// Increase width as these components look horrible at lower
// widths.
await page.setViewportSize({ width: 1400, height: 768 });
await use(page);
},
room: async ({ app, user }, use) => {
const roomId = await app.client.createRoom({
name: "A room",
});
await app.closeNotificationToast();
await app.viewRoomById(roomId);
await use({ roomId });
},
});
test("should show an error when sync stops", { tag: "@screenshot" }, async ({ page, user, app, room, axe }) => {
await page.route("**/_matrix/client/*/sync*", async (route, req) => {
await route.fulfill({
status: 500,
contentType: "application/json",
body: '{"error": "Test fail", "errcode": "M_UNKNOWN"}',
});
});
await app.client.sendMessage(room.roomId, "forcing sync to run");
const banner = page.getByRole("region", { name: "Room status bar" });
await expect(banner).toBeVisible({ timeout: 15000 });
await expect(banner).toMatchScreenshot("connectivity_lost.png");
});
test("should NOT an error when a resource limit is hit", async ({ page, user, app, room, axe, toasts }) => {
await app.viewRoomById(room.roomId);
await page.route("**/_matrix/client/*/sync*", async (route, req) => {
await route.fulfill({
status: 400,
contentType: "application/json",
body: JSON.stringify({
error: "Test fail",
errcode: "M_RESOURCE_LIMIT_EXCEEDED",
limit_type: "monthly_active_user",
admin_contact: "https://example.org",
}),
});
});
await app.client.sendMessage(room.roomId, "forcing sync to run");
// Wait for the MAU warning toast to appear so we know this status bar would have appeared.
await toasts.getToast("Warning", 15000);
await expect(page.getByRole("region", { name: "Room status bar" })).not.toBeVisible();
});
test(
"should show an error when the user needs to consent",
{ tag: "@screenshot" },
async ({ page, user, app, room, axe }) => {
await app.viewRoomById(room.roomId);
await page.route("**/_matrix/client/**/send**", async (route) => {
await route.fulfill({
status: 400,
contentType: "application/json",
body: JSON.stringify({
error: "Test fail",
errcode: "M_CONSENT_NOT_GIVEN",
consent_uri: "https://example.org",
}),
});
});
const composer = app.getComposerField();
await composer.fill("Hello!");
await composer.press("Enter");
await page
.getByRole("dialog", { name: "Terms and Conditions" })
.getByRole("button", { name: "Dismiss" })
.click();
const banner = page.getByRole("region", { name: "Room status bar" });
await expect(banner).toBeVisible({ timeout: 15000 });
await expect(banner).toMatchScreenshot("consent.png");
// Click consent
await banner.getByRole("link", { name: "View Terms and Conditions" }).click();
await page.unroute("**/_matrix/client/**/send**");
// Should now be allowed to retry.
await banner.getByRole("button", { name: "Retry all" }).click();
await expect(banner).not.toBeVisible();
},
);
test.describe("Message fails to send", () => {
test.beforeEach(async ({ page, user, app, room, axe }) => {
await app.viewRoomById(room.roomId);
await page.route("**/_matrix/client/**/send**", async (route) => {
await route.fulfill({
status: 400,
contentType: "application/json",
body: JSON.stringify({ error: "Test fail", errcode: "M_UNKNOWN" }),
});
});
const composer = app.getComposerField();
await composer.fill("Hello!");
await composer.press("Enter");
const banner = page.getByRole("region", { name: "Room status bar" });
await expect(banner).toBeVisible();
});
test(
"should show an error when a message fails to send",
{ tag: "@screenshot" },
async ({ page, user, app, room, axe }) => {
const banner = page.getByRole("region", { name: "Room status bar" });
await expect(banner).toMatchScreenshot("message_failed.png");
},
);
test("should be able to 'Delete all' messages", async ({ page, user, app, room, axe }) => {
const banner = page.getByRole("region", { name: "Room status bar" });
await banner.getByRole("button", { name: "Delete all" }).click();
await expect(banner).not.toBeVisible();
});
test("should be able to 'Retry all' messages", async ({ page, user, app, room, axe }) => {
const banner = page.getByRole("region", { name: "Room status bar" });
await page.unroute("**/_matrix/client/**/send**");
await banner.getByRole("button", { name: "Retry all" }).click();
await expect(banner).not.toBeVisible();
});
});
test.describe("Local rooms", () => {
test.use({
botCreateOpts: {
displayName: "Alice",
},
});
test(
"should show an error when creating a local room fails",
{ tag: "@screenshot" },
async ({ page, app, user, bot }) => {
await page
.getByRole("navigation", { name: "Room list" })
.getByRole("button", { name: "New conversation" })
.click();
await page.getByRole("menuitem", { name: "Start chat" }).click();
await page.route("**/_matrix/client/*/createRoom*", async (route, req) => {
await route.fulfill({
status: 400,
contentType: "application/json",
body: JSON.stringify({
error: "Test fail",
errcode: "M_UNKNOWN",
}),
});
});
const other = page.locator(".mx_InviteDialog_other");
await other.getByTestId("invite-dialog-input").fill(bot.credentials.userId);
await expect(
other.getByRole("option", { name: "Alice" }).getByText(bot.credentials.userId),
).toBeVisible();
await other.getByRole("option", { name: "Alice" }).click();
await other.getByRole("button", { name: "Go" }).click();
// Send a message to invite the bots
const composer = app.getComposerField();
await composer.fill("Hello");
await composer.press("Enter");
const banner = page.getByRole("status", { name: "Could not start a chat with this user" });
await expect(banner).toBeVisible();
await expect(banner).toMatchScreenshot("local_room_create_failed.png");
await page.unroute("**/_matrix/client/*/createRoom*");
await banner.getByRole("button", { name: "Retry" }).click();
await expect(banner).not.toBeVisible();
},
);
});
});