Files
ThreadNet-Web/modules/banner/element-web/tests/banner.spec.ts
T

154 lines
6.0 KiB
TypeScript

/*
Copyright 2025 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { test, expect } from "../../../../playwright/element-web-test.ts";
import { ModuleConfig } from "../src/config.ts";
test.describe("Banner", () => {
test.use({
displayName: "Timmy",
page: async ({ context, page, moduleDir }, use) => {
for (const path of ["logo.svg", "app1.png", "app2.png"]) {
await context.route(`/${path}*`, async (route) => {
await route.fulfill({ path: `${moduleDir}/tests/fixture/${path}` });
});
}
await context.route("http://localhost:8080/ics/navigation.json*", async (route) => {
await route.fulfill({
path: `${moduleDir}/tests/fixture/navigation.json`,
contentType: "application/json",
});
});
await context.route("http://localhost:8080/ics/silent", async (route) => {
await route.fulfill({ path: `${moduleDir}/tests/fixture/silent/index.html`, contentType: "text/html" });
});
await page.goto("/");
await use(page);
},
});
test("should error if config is missing", { tag: ["@screenshot"] }, async ({ page }) => {
await expect(page.getByText("Your Element is misconfigured")).toBeVisible();
// We don't take a screenshot as we don't want to assert Element's styling, only our own
});
const configs: ModuleConfig[] = [
{
logo_url: "http://localhost:8080/logo.svg",
logo_link_url: "https://example.com/portal",
menu: {
type: "static",
categories: [
{
name: "Applications",
links: [
{
icon_uri: "http://localhost:8080/app1.png",
name: "App 1",
link_url: "https://example.com/app1",
target: "app1",
},
{
icon_uri: "http://localhost:8080/app2.png",
name: "Riot",
link_url: "https://riot.im/app",
target: "riot-im",
},
],
},
{
name: "Links",
links: [
{
icon_uri: "http://localhost:8080/app1.png",
name: "Link",
link_url: "https://example.com/link1",
},
],
},
],
},
},
{
logo_url: "http://localhost:8080/logo.svg",
logo_link_url: "https://example.com/portal",
menu: {
type: "univention",
ics_url: "http://localhost:8080/ics/",
},
},
];
for (const config of configs) {
const type = config.menu.type;
test.describe(`${type} config`, () => {
test.use({
config: {
"io.element.element-web-modules.banner": config,
},
});
test("should render", { tag: ["@screenshot"] }, async ({ page, axe }) => {
await expect(page.getByRole("heading", { name: "Welcome to Element!" })).toBeVisible();
await expect(page.getByLabel("Show portal")).toHaveAttribute("href", "https://example.com/portal");
const nav = page.locator("nav");
if (type === "univention") {
await expect(nav).toMatchScreenshot(`${type}_nav_loading.png`);
// The stub silent html doesn't seem to work in Playwright so send the postMessage manually
await page.evaluate(() => {
window.postMessage({
loggedIn: true,
});
});
}
const trigger = page.getByLabel("Show menu");
await expect(trigger).toBeVisible();
// Assert the banner looks as we expect
await expect(nav).toMatchAriaSnapshot();
await expect(nav).toMatchScreenshot(`${type}_nav.png`);
// Check hover styles
await trigger.hover();
await expect(nav).toMatchScreenshot(`${type}_nav_hover.png`);
await test.step("open menu", async () => {
await trigger.click();
const app1 = page.getByText("App 1");
await expect(app1).toHaveAttribute("href", "https://example.com/app1");
await app1.hover();
// Assert the sidebar looks as we expect
const sidebar = page.getByRole("dialog");
await expect(sidebar).toMatchAriaSnapshot();
await expect(page).toMatchScreenshot(`${type}_menu.png`, {
// We exclude this as we don't want to assert Element's styling, only our own
css: `
#matrixchat {
opacity: 0;
background: orchid;
}
`,
});
});
await test.step("close menu", async () => {
await expect(axe).toHaveNoViolations();
// Assert it closes by clicking the overlay
await page.getByTestId("dialog-overlay").click();
await expect(page.getByRole("dialog")).not.toBeVisible();
});
});
});
}
});