feat: show call participants in room list (Discord-style)
Docker / Docker Buildx (push) Has been cancelled
Build Debian package / Build package (release) Has been cancelled
Build and Deploy / prepare (release) Has been cancelled
Deploy release / Deploy to Cloudflare Pages (release) Has been cancelled
Build and Deploy / Trigger Pro pipeline (release) Has been cancelled
Build and Deploy / Windows arm64 (release) Has been cancelled
Build and Deploy / Windows x64 (release) Has been cancelled
Build and Deploy / macOS (release) Has been cancelled
Build and Deploy / Linux amd64 (sqlcipher static) (release) Has been cancelled
Build and Deploy / Linux arm64 (sqlcipher static) (release) Has been cancelled
Build and Deploy / ${{ needs.prepare.outputs.deploy == 'true' && 'Deploy' || 'Deploy (dry-run)' }} (release) Has been cancelled
Build and Deploy / Deploy builds to ESS (release) Has been cancelled
Docker / Docker Buildx (push) Has been cancelled
Build Debian package / Build package (release) Has been cancelled
Build and Deploy / prepare (release) Has been cancelled
Deploy release / Deploy to Cloudflare Pages (release) Has been cancelled
Build and Deploy / Trigger Pro pipeline (release) Has been cancelled
Build and Deploy / Windows arm64 (release) Has been cancelled
Build and Deploy / Windows x64 (release) Has been cancelled
Build and Deploy / macOS (release) Has been cancelled
Build and Deploy / Linux amd64 (sqlcipher static) (release) Has been cancelled
Build and Deploy / Linux arm64 (sqlcipher static) (release) Has been cancelled
Build and Deploy / ${{ needs.prepare.outputs.deploy == 'true' && 'Deploy' || 'Deploy (dry-run)' }} (release) Has been cancelled
Build and Deploy / Deploy builds to ESS (release) Has been cancelled
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
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 { test, expect } from "../../element-web-test";
|
||||
|
||||
function formDataParser(data: string, contentType: string | null): Record<string, string> {
|
||||
const [, boundary] =
|
||||
contentType
|
||||
?.split(";")
|
||||
.map((v) => v.trim())
|
||||
.find((v) => v.startsWith("boundary="))
|
||||
?.split("=") ?? [];
|
||||
if (!boundary) {
|
||||
throw Error("No boundary found in form data request");
|
||||
}
|
||||
const dataMap: Record<string, string> = {};
|
||||
for (const dataPart of data.split(boundary).map((p) => p.trim())) {
|
||||
const lines = dataPart.split("\r\n");
|
||||
const fieldName = lines[0].match(/name="([^"]+)"/)?.[1];
|
||||
if (!fieldName) {
|
||||
continue;
|
||||
}
|
||||
const data = lines.slice(1, -1).join("\n").trim();
|
||||
dataMap[fieldName] = data;
|
||||
}
|
||||
return dataMap;
|
||||
}
|
||||
|
||||
test.describe("Rageshakes", () => {
|
||||
test.describe("visible when enabled", () => {
|
||||
test.use({
|
||||
config: {
|
||||
// Enable this just so the options show up.
|
||||
bug_report_endpoint_url: "https://example.org/bug-report-place",
|
||||
},
|
||||
});
|
||||
test("should be able to open bug report dialog via slash command", async ({ page, app, user }) => {
|
||||
await app.client.createRoom({ name: "Test room" });
|
||||
await app.viewRoomByName("Test room");
|
||||
const composer = app.getComposer().locator("[contenteditable]");
|
||||
await composer.fill("/rageshake");
|
||||
await composer.press("Enter");
|
||||
await expect(page.getByRole("dialog", { name: "Submit debug logs" })).toBeVisible();
|
||||
});
|
||||
|
||||
test("should be able to open bug report dialog via feedback dialog", async ({ page, app, user }) => {
|
||||
const menu = await app.openUserMenu();
|
||||
await menu.getByRole("menuitem", { name: "Feedback" }).click();
|
||||
const feedbackDialog = page.getByRole("dialog", { name: "Feedback" });
|
||||
await feedbackDialog.getByRole("button", { name: "debug logs" }).click();
|
||||
await expect(page.getByRole("dialog", { name: "Submit debug logs" })).toBeVisible();
|
||||
});
|
||||
test("should be able to open bug report dialog via Settings", async ({ page, app, user }) => {
|
||||
const settings = await app.settings.openUserSettings("Help & About");
|
||||
await settings.getByRole("button", { name: "Submit debug logs" }).click();
|
||||
// Playwright can't see the dialog when both the settings and bug report dialogs are open, so key off heading.
|
||||
await expect(page.locator(".mx_BugReportDialog")).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("hidden when disabled", () => {
|
||||
test("should NOT be able to open bug report dialog via slash command", async ({ page, app, user }) => {
|
||||
await app.client.createRoom({ name: "Test room" });
|
||||
await app.viewRoomByName("Test room");
|
||||
const composer = app.getComposer().locator("[contenteditable]");
|
||||
await composer.fill("/rageshake");
|
||||
await composer.press("Enter");
|
||||
await expect(page.getByRole("dialog", { name: "Unknown command" })).toBeVisible();
|
||||
});
|
||||
|
||||
test("should NOT be able to open bug report dialog via feedback dialog", async ({ page, app, user }) => {
|
||||
const menu = await app.openUserMenu();
|
||||
await expect(menu.getByRole("menuitem", { name: "Feedback" })).not.toBeVisible();
|
||||
});
|
||||
test("should NOT be able to open bug report dialog via Settings", async ({ page, app, user }) => {
|
||||
const settings = await app.settings.openUserSettings("Help & About");
|
||||
await expect(settings.getByRole("menuitem", { name: "Submit debug logs" })).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("via bug report endpoint", () => {
|
||||
test.use({
|
||||
config: {
|
||||
bug_report_endpoint_url: "http://example.org/bug-report-server",
|
||||
},
|
||||
});
|
||||
|
||||
test("should be able to rageshake to a URL", { tag: "@screenshot" }, async ({ page, app, user }) => {
|
||||
await page.route("http://example.org/bug-report-server", async (route, request) => {
|
||||
if (request.method() !== "POST") {
|
||||
throw Error("Expected POST");
|
||||
}
|
||||
const fields = formDataParser(request.postData(), await request.headerValue("Content-Type"));
|
||||
expect(fields.text).toEqual(
|
||||
"These are some notes\n\nIssue: https://github.com/element-hq/element-web/12345",
|
||||
);
|
||||
expect(fields.app).toEqual("element-web");
|
||||
expect(fields.user_id).toEqual(user.userId);
|
||||
expect(fields.device_id).toEqual(user.deviceId);
|
||||
// We don't check the logs contents, but we'd like for there to be a log.
|
||||
expect(fields["compressed-log"]).toBeDefined();
|
||||
return route.fulfill({ json: {}, status: 200 });
|
||||
});
|
||||
|
||||
const settings = await app.settings.openUserSettings("Help & About");
|
||||
await settings.getByRole("button", { name: "Submit debug logs" }).click();
|
||||
const dialog = page.locator(".mx_BugReportDialog");
|
||||
await dialog
|
||||
.getByRole("textbox", { name: "GitHub issue" })
|
||||
.fill("https://github.com/element-hq/element-web/12345");
|
||||
await dialog.getByRole("textbox", { name: "Notes" }).fill("These are some notes");
|
||||
await expect(dialog).toMatchScreenshot("rageshake_via_url.png");
|
||||
await dialog.getByRole("button", { name: "Send logs" }).click();
|
||||
await expect(page.getByRole("heading", { name: "Logs sent" })).toBeVisible();
|
||||
});
|
||||
});
|
||||
test.describe("via local download", () => {
|
||||
test.use({
|
||||
config: {
|
||||
bug_report_endpoint_url: "local",
|
||||
},
|
||||
});
|
||||
|
||||
test("should be able to rageshake to local download", { tag: "@screenshot" }, async ({ page, app, user }) => {
|
||||
const settings = await app.settings.openUserSettings("Help & About");
|
||||
await settings.getByRole("button", { name: "Download logs" }).click();
|
||||
const dialog = page.locator(".mx_BugReportDialog");
|
||||
await expect(dialog).toMatchScreenshot("rageshake_locally.png");
|
||||
const downloadPromise = page.waitForEvent("download");
|
||||
await dialog.getByRole("button", { name: "Download logs" }).click();
|
||||
const download = await downloadPromise;
|
||||
await download.cancel();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user