Merge remote-tracking branch 'origin/develop' into hs/url-preview-new-design

This commit is contained in:
Half-Shot 2026-04-14 09:03:33 +01:00
commit 52f4915c88
180 changed files with 6768 additions and 2452 deletions

7
.github/CODEOWNERS vendored
View File

@ -4,12 +4,13 @@
/pnpm-lock.yaml @element-hq/element-web-team
/apps/web/src/SecurityManager.ts @element-hq/element-crypto-web-reviewers
/apps/web/test/SecurityManager-test.ts @element-hq/element-crypto-web-reviewers
/apps/web/test/unit-tests/SecurityManager-test.ts @element-hq/element-crypto-web-reviewers
/apps/web/src/async-components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
/apps/web/test/unit-tests/async-components/dialogs/security/ @element-hq/element-crypto-web-reviewers
/apps/web/src/components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
/apps/web/test/components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
/apps/web/test/unit-tests/components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
/apps/web/src/stores/SetupEncryptionStore.ts @element-hq/element-crypto-web-reviewers
/apps/web/test/stores/SetupEncryptionStore-test.ts @element-hq/element-crypto-web-reviewers
/apps/web/test/unit-tests/stores/SetupEncryptionStore-test.ts @element-hq/element-crypto-web-reviewers
/apps/web/src/components/views/settings/tabs/user/EncryptionUserSettingsTab.tsx @element-hq/element-crypto-web-reviewers
/apps/web/src/components/views/settings/encryption/ @element-hq/element-crypto-web-reviewers
/apps/web/test/unit-tests/components/views/settings/encryption/ @element-hq/element-crypto-web-reviewers

View File

@ -163,7 +163,7 @@ jobs:
- name: Run Playwright tests
working-directory: apps/web
run: |
pnpm playwright test \
pnpm test:playwright \
--shard "$SHARD" \
--project="${{ matrix.project }}" \
${{ (github.event_name == 'pull_request' && matrix.runAllTests == false ) && '--grep-invert @mergequeue' || '' }}

View File

@ -1,6 +1,15 @@
name: Publish shared component npm package
name: Publish npm package
run-name: Publish ${{ inputs.package }}
on:
workflow_dispatch: {}
workflow_dispatch:
inputs:
package:
description: Which package to release
required: true
type: choice
options:
- playwright-common
- shared-components
concurrency: release
jobs:
@ -29,10 +38,9 @@ jobs:
- name: Update npm
run: npm install -g npm@latest
# Need to setup element web too as it needs the translations
- name: 🛠️ Setup EW
- name: 🛠️ Install dependencies
run: pnpm install --frozen-lockfile
- name: 🚀 Publish to npm
working-directory: packages/shared-components
working-directory: packages/${{ inputs.package }}
run: npm publish --access public --provenance

View File

@ -105,7 +105,7 @@
"typescript": "5.9.3"
},
"hakDependencies": {
"matrix-seshat": "^4.0.1"
"matrix-seshat": "4.0.1"
},
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319"
}

View File

@ -30,9 +30,9 @@
"lint:types": "nx lint:types",
"lint:style": "stylelint \"res/css/**/*.pcss\"",
"test": "nx test:unit",
"test:playwright": "playwright test",
"test:playwright:open": "pnpm test:playwright --ui",
"test:playwright:screenshots": "playwright-screenshots-experimental pnpm playwright test --update-snapshots --project=Chrome --grep @screenshot",
"test:playwright": "nx test:playwright --",
"test:playwright:open": "nx test:playwright -- --ui",
"test:playwright:screenshots": "nx test:playwright:screenshots --",
"coverage": "pnpm test --coverage",
"analyse:webpack-bundles": "webpack-bundle-analyzer webpack-stats.json webapp"
},
@ -127,8 +127,7 @@
"@babel/preset-typescript": "^7.12.7",
"@casualbot/jest-sonar-reporter": "2.5.0",
"@element-hq/element-call-embedded": "0.18.0",
"@element-hq/element-web-playwright-common": "catalog:",
"@element-hq/element-web-playwright-common-local": "workspace:*",
"@element-hq/element-web-playwright-common": "workspace:*",
"@fetch-mock/jest": "^0.2.20",
"@jest/globals": "^30.2.0",
"@peculiar/webcrypto": "^1.4.3",

View File

@ -23,6 +23,7 @@ const chromeProject: Project<PlaywrightTestOptions, WorkerOptions & PlaywrightWo
channel: "chromium",
permissions: ["clipboard-write", "clipboard-read", "microphone"],
launchOptions: {
executablePath: "/usr/bin/chromium",
args: ["--use-fake-ui-for-media-stream", "--use-fake-device-for-media-stream", "--mute-audio"],
},
connectOptions: process.env.PW_TEST_CONNECT_WS_ENDPOINT

View File

@ -43,11 +43,7 @@ test.describe("Key storage out of sync toast", () => {
});
test("should prompt for recovery key if 'enter recovery key' pressed", { tag: "@screenshot" }, async ({ page }) => {
// We need to wait for there to be two toasts as the wait below won't work in isolation:
// playwright only evaluates the 'first()' call initially, not subsequent times it checks, so
// it would always be checking the same toast, even if another one is now the first.
await expect(page.getByRole("alert")).toHaveCount(2);
await expect(page.getByRole("alert").first()).toMatchScreenshot(
await expect(page.getByRole("alert").filter({ hasText: "Your key storage is out of sync." })).toMatchScreenshot(
"key-storage-out-of-sync-toast.png",
screenshotOptions,
);

View File

@ -328,11 +328,11 @@ test.describe("Room list", () => {
const roomListView = getRoomList(page);
const videoRoom = roomListView.getByRole("option", { name: "video room" });
await expect(videoRoom).toHaveAttribute("aria-selected", "true"); // wait for room list update
// focus the user menu to avoid to have hover decoration
await page.getByRole("button", { name: "User menu" }).focus();
await expect(videoRoom).toBeVisible();
await expect(videoRoom).toMatchScreenshot("room-list-item-video.png");
});
});

View File

@ -48,9 +48,9 @@ test.describe("Room Directory", () => {
await app.closeDialog();
const resp = await bot.publicRooms({});
expect(resp.total_room_count_estimate).toEqual(1);
expect(resp.chunk).toHaveLength(1);
expect(resp.chunk[0].room_id).toEqual(roomId);
expect(resp.total_room_count_estimate).toBeGreaterThanOrEqual(1);
expect(resp.chunk).toHaveLength(resp.total_room_count_estimate);
expect(resp.chunk.find((r) => r.room_id === roomId)).toBeTruthy();
},
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -44,7 +44,7 @@
"parallel": false,
"cwd": "apps/web"
},
"dependsOn": ["^build"]
"dependsOn": ["^build", "^build:playwright"]
},
"test:unit": {
"executor": "@nx/jest:jest",
@ -53,6 +53,16 @@
"cwd": "apps/web"
},
"dependsOn": ["^build"]
},
"test:playwright": {
"command": "playwright test",
"options": { "cwd": "apps/web" },
"dependsOn": ["^build:playwright"]
},
"test:playwright:screenshots": {
"command": "playwright-screenshots nx test:playwright --update-snapshots --project=Chrome --grep @screenshot",
"options": { "cwd": "apps/web" },
"dependsOn": ["^build:playwright"]
}
}
}

View File

@ -81,6 +81,59 @@ const msgTypeHandlers: Record<string, (event: MatrixEvent) => string | null> = {
},
};
/**
* Extracts plain text from a message body, replacing any spoilered content
* with '[Spoiler]' to prevent spoilers in desktop notifications.
*/
function getNotificationBodyWithoutSpoilers(ev: MatrixEvent): string {
const content = ev.getContent();
const plainBody = content.body ?? "";
const formattedBody = content.formatted_body;
if (typeof formattedBody !== "string" || !formattedBody.length) {
return plainBody;
}
/** Recursively walks HTML tree to hide spoilers. */
function replaceSpoilers(node: Node): Node {
if (node.nodeType !== Node.ELEMENT_NODE || !(node instanceof Element)) {
return node;
}
if (node.hasAttribute("data-mx-spoiler")) {
const e = document.createElement("span");
e.appendChild(document.createTextNode("[Spoiler]"));
return e;
}
for (const childNode of node.childNodes) {
node.replaceChild(replaceSpoilers(childNode), childNode);
}
return node;
}
try {
// Dev note: ideally we would reuse more of the existing rendering stack
// rather than re-parsing and updating the generated HTML here. However,
// that rendering stack is currently quite consolidated and cannot
// easily be refactored to allow the call-site to control how spoilers
// are rendered. The problem is that we now need two different output
// formats:
// - The existing format where spoilers are wrapped in html <span> tags
// - The new format where the spoilered text is replaced with [Spoiler]
const parser = new DOMParser();
const doc = parser.parseFromString(formattedBody, "text/html");
// Use textContent rather than innerHTML/outerHTML since textContent is
// XSS-safe and the input is untrusted.
return replaceSpoilers(doc.body).textContent ?? plainBody;
} catch {
return plainBody;
}
}
export const enum NotifierEvent {
NotificationHiddenChange = "notification_hidden_change",
}
@ -134,7 +187,7 @@ class NotifierClass extends TypedEventEmitter<keyof EmittedEvents, EmittedEvents
// notificationMessageForEvent includes sender, but we already have the sender here
const msgType = ev.getContent().msgtype;
if (ev.getContent().body && (!msgType || !msgTypeHandlers.hasOwnProperty(msgType))) {
msg = stripPlainReply(ev.getContent().body);
msg = stripPlainReply(getNotificationBodyWithoutSpoilers(ev));
}
} else if (ev.getType() === "m.room.member") {
// context is all in the message here, we don't need
@ -145,7 +198,7 @@ class NotifierClass extends TypedEventEmitter<keyof EmittedEvents, EmittedEvents
// notificationMessageForEvent includes sender, but we've just out sender in the title
const msgType = ev.getContent().msgtype;
if (ev.getContent().body && (!msgType || !msgTypeHandlers.hasOwnProperty(msgType))) {
msg = stripPlainReply(ev.getContent().body);
msg = stripPlainReply(getNotificationBodyWithoutSpoilers(ev));
}
}

View File

@ -7,9 +7,10 @@ Please see LICENSE files in the repository root for full details.
*/
import React, { type ComponentProps } from "react";
import { EventType, type MatrixClient, type MatrixEvent, type Room, type User } from "matrix-js-sdk/src/matrix";
import { EventType, type MatrixEvent, type Room, type User } from "matrix-js-sdk/src/matrix";
import MultiInviter, { type CompletionStates, type MultiInviterOptions } from "./utils/MultiInviter";
import type MultiInviter from "./utils/MultiInviter";
import { type CompletionStates } from "./utils/MultiInviter";
import Modal from "./Modal";
import { _t } from "./languageHandler";
import InviteDialog from "./components/views/dialogs/InviteDialog";
@ -19,33 +20,6 @@ import ErrorDialog from "./components/views/dialogs/ErrorDialog";
import { InviteKind } from "./components/views/dialogs/InviteDialogTypes";
import { type Member } from "./utils/direct-messages";
export interface IInviteResult {
states: CompletionStates;
inviter: MultiInviter;
}
/**
* Invites multiple addresses to a room.
*
* Simpler interface to {@link MultiInviter}.
*
* Any failures are returned via the `states` in the result.
*
* @param {string} roomId The ID of the room to invite to
* @param {string[]} addresses Array of strings of addresses to invite. May be matrix IDs or 3pids.
* @param options Options object.
* @returns {Promise} Promise
*/
export async function inviteMultipleToRoom(
client: MatrixClient,
roomId: string,
addresses: string[],
options: MultiInviterOptions = {},
): Promise<IInviteResult> {
const inviter = new MultiInviter(client, roomId, options);
return { states: await inviter.invite(addresses), inviter };
}
export function showStartChatInviteDialog(initialText = ""): void {
// This dialog handles the room creation internally - we don't need to worry about it.
Modal.createDialog(

View File

@ -34,7 +34,7 @@ import { useFeatureEnabled } from "../../hooks/useSettings";
import { useStateArray } from "../../hooks/useStateArray";
import { _t } from "../../languageHandler";
import PosthogTrackers from "../../PosthogTrackers";
import { inviteMultipleToRoom, showRoomInviteDialog } from "../../RoomInvite";
import { showRoomInviteDialog } from "../../RoomInvite";
import { UIComponent } from "../../settings/UIFeature";
import { UPDATE_EVENT } from "../../stores/AsyncStore";
import RightPanelStore from "../../stores/right-panel/RightPanelStore";
@ -76,6 +76,7 @@ import SpaceHierarchy, { showRoom } from "./SpaceHierarchy";
import { type RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
import SpacePillButton from "./SpacePillButton.tsx";
import { useRoomName } from "../../hooks/useRoomName.ts";
import MultiInviter from "../../utils/MultiInviter.ts";
interface IProps {
space: Room;
@ -538,11 +539,12 @@ const SpaceSetupPrivateInvite: React.FC<{
setBusy(true);
const targetIds = emailAddresses.map((name) => name.trim()).filter(Boolean);
try {
const result = await inviteMultipleToRoom(space.client, space.roomId, targetIds);
const inviter = new MultiInviter(space.client, space.roomId);
const states = await inviter.invite(targetIds);
const failedUsers = Object.keys(result.states).filter((a) => result.states[a] === "error");
const failedUsers = Object.keys(states).filter((a) => states[a] === "error");
if (failedUsers.length > 0) {
logger.log("Failed to invite users to space: ", result);
logger.log("Failed to invite users to space:", states);
setError(
_t("create_space|failed_invite_users", {
csvUsers: failedUsers.join(", "),

View File

@ -120,7 +120,7 @@ export default class BugReportDialog extends React.Component<BugReportDialogProp
<>
<p>{errorText}</p>
{error.policyURL && (
<Link size="medium" target="_blank" href={error.policyURL}>
<Link size="md" target="_blank" href={error.policyURL}>
{_t("action|learn_more")}
</Link>
)}

View File

@ -25,7 +25,7 @@ import { getDefaultIdentityServerUrl, setToDefaultIdentityServer } from "../../.
import { buildActivityScores, buildMemberScores, compareMembers } from "../../../utils/SortMembers";
import { abbreviateUrl } from "../../../utils/UrlUtils";
import IdentityAuthClient from "../../../IdentityAuthClient";
import { type IInviteResult, inviteMultipleToRoom, showAnyInviteErrors } from "../../../RoomInvite";
import { showAnyInviteErrors } from "../../../RoomInvite";
import { Action } from "../../../dispatcher/actions";
import { DefaultTagID } from "../../../stores/room-list-v3/skip-list/tag";
import RoomListStore from "../../../stores/room-list/RoomListStore";
@ -63,6 +63,7 @@ import { type NonEmptyArray } from "../../../@types/common";
import { SdkContextClass } from "../../../contexts/SDKContext";
import { type UserProfilesStore } from "../../../stores/UserProfilesStore";
import InviteProgressBody from "./InviteProgressBody.tsx";
import MultiInviter, { type CompletionStates as MultiInviterCompletionStates } from "../../../utils/MultiInviter.ts";
// we have a number of types defined from the Matrix spec which can't reasonably be altered here.
/* eslint-disable camelcase */
@ -409,10 +410,14 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
.map((member) => ({ userId: member.userId, user: toMember(member) }));
}
private shouldAbortAfterInviteError(result: IInviteResult, room: Room): boolean {
private shouldAbortAfterInviteError(
states: MultiInviterCompletionStates,
inviter: MultiInviter,
room: Room,
): boolean {
this.setState({ busy: false });
const userMap = new Map<string, Member>(this.state.targets.map((member) => [member.userId, member]));
return !showAnyInviteErrors(result.states, room, result.inviter, userMap);
return !showAnyInviteErrors(states, room, inviter, userMap);
}
private convertFilter(): Member[] {
@ -483,11 +488,12 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
}
try {
const result = await inviteMultipleToRoom(cli, this.props.roomId, targetIds, {
const inviter = new MultiInviter(cli, this.props.roomId, {
// We show our own progress body, so don't pop up a separate dialog.
inhibitProgressDialog: true,
});
if (!this.shouldAbortAfterInviteError(result, room)) {
const states = await inviter.invite(targetIds);
if (!this.shouldAbortAfterInviteError(states, inviter, room)) {
// handles setting error message too
this.props.onFinished(true);
}

View File

@ -46,7 +46,7 @@ export function EncryptionCard({
return (
<div className={classNames("mx_EncryptionCard", className)}>
<div className="mx_EncryptionCard_header">
<BigIcon destructive={destructive}>
<BigIcon kind={destructive ? "critical" : "primary"}>
<Icon />
</BigIcon>
<Heading as="h2" size="sm" weight="semibold">

View File

@ -228,21 +228,25 @@ export class DeviceListenerCurrentDevice {
logSpan.info("No default 4S key but backup disabled: no toast needed");
await this.setDeviceState("ok", logSpan);
}
} else {
// If we get here, then we are verified, have key backup, and
// 4S, but allSystemsReady is false, which means that either
// secretStorageStatus.ready is false (which means that 4S
// doesn't have all the secrets), or we don't have the backup
// key cached locally. If any of the cross-signing keys are
// missing locally, that is handled by the
// `!allCrossSigningSecretsCached` branch above.
logSpan.warn("4S is missing secrets or backup key not cached", {
} else if (!recoveryIsOk) {
logSpan.warn("4S is missing secrets: setting state to KEY_STORAGE_OUT_OF_SYNC", {
secretStorageStatus,
allCrossSigningSecretsCached,
isCurrentDeviceTrusted,
keyBackupDownloadIsOk,
});
await this.setDeviceState("key_storage_out_of_sync", logSpan);
} else if (!keyBackupDownloadIsOk) {
logSpan.warn("Backup key is not cached locally: setting state to KEY_STORAGE_OUT_OF_SYNC", {
secretStorageStatus,
allCrossSigningSecretsCached,
isCurrentDeviceTrusted,
keyBackupDownloadIsOk,
});
await this.setDeviceState("key_storage_out_of_sync", logSpan);
} else {
// We should not get here
logSpan.error("DeviceListenerCurrentDevice: allSystemsReady was false, but no case matched.");
}
}
}

View File

@ -1114,7 +1114,7 @@
"verification_requested_toast_title": "Verification requested",
"verified_identity_changed": "%(displayName)s's (<b>%(userId)s</b>) digital identity was reset. <a>Learn more</a>",
"verified_identity_changed_no_displayname": "<b>%(userId)s</b>'s digital identity was reset. <a>Learn more</a>",
"verify_toast_description": "As of end of April 2026, unverified devices will not be able to send and receive messages. <a>Learn more</a>",
"verify_toast_description": "As of end of October 2026, unverified devices will not be able to send and receive messages. <a>Learn more</a>",
"verify_toast_title": "Verify this device",
"withdraw_verification_action": "Withdraw verification"
},

View File

@ -10,13 +10,13 @@ import { ClientEvent, EventType, type MatrixClient, type Room } from "matrix-js-
import { KnownMembership } from "matrix-js-sdk/src/types";
import { logger } from "matrix-js-sdk/src/logger";
import { inviteMultipleToRoom, showAnyInviteErrors } from "../RoomInvite";
import { showAnyInviteErrors } from "../RoomInvite";
import Modal, { type IHandle } from "../Modal";
import { _t } from "../languageHandler";
import ErrorDialog from "../components/views/dialogs/ErrorDialog";
import SpaceStore from "../stores/spaces/SpaceStore";
import Spinner from "../components/views/elements/Spinner";
import type { MultiInviterOptions } from "./MultiInviter";
import MultiInviter, { type MultiInviterOptions } from "./MultiInviter";
export interface RoomUpgradeProgress {
roomUpgraded: boolean;
@ -158,7 +158,8 @@ async function inviteUsersToRoom(
userIds: string[],
inviteOptions: MultiInviterOptions,
): Promise<void> {
const result = await inviteMultipleToRoom(client, roomId, userIds, inviteOptions);
const inviter = new MultiInviter(client, roomId, inviteOptions);
const states = await inviter.invite(userIds);
const room = client.getRoom(roomId)!;
showAnyInviteErrors(result.states, room, result.inviter);
showAnyInviteErrors(states, room, inviter);
}

View File

@ -358,6 +358,46 @@ describe("Notifier", () => {
reply,
);
});
it.each([
["This was a triumph", "This was a triumph", "This was a triumph"],
["This was a triumph", "<span data-mx-spoiler>This was a triumph</span>", "[Spoiler]"],
["This was a triumph", '<span data-mx-spoiler="triumph">This was a triumph</span>', "[Spoiler]"],
["foo bar baz", "foo <span data-mx-spoiler>bar</span> baz", "foo [Spoiler] baz"],
["foo foo foo", "foo <span data-mx-spoiler>foo</span> foo", "foo [Spoiler] foo"],
[
"a b c d e",
"a <span data-mx-spoiler>b</span> c <span data-mx-spoiler>d</span> e",
"a [Spoiler] c [Spoiler] e",
],
["foo foo", "foo <span data-mx-spoiler></span> foo", "foo [Spoiler] foo"],
["foo bar baz", "foo <span data-mx-spoiler>b<em>a</em>r</span> baz", "foo [Spoiler] baz"],
["foobar", "<span data-mx-spoiler>foo</span><span data-mx-spoiler>bar</span>", "[Spoiler][Spoiler]"],
["foo bar baz", "<strong>foo <span data-mx-spoiler>bar</span> baz</strong>", "foo [Spoiler] baz"],
["foo <bar> baz", "foo <span data-mx-spoiler>&lt;bar&gt;</span> baz", "foo [Spoiler] baz"],
["foo\nbar\nbaz", "foo<span data-mx-spoiler><br>bar<br></span>baz", "foo[Spoiler]baz"],
])("should hide spoilers in notification", (body, formattedBody, expected) => {
const spoilerEvent = mkEvent({
event: true,
type: EventType.RoomMessage,
user: mockClient.getSafeUserId(),
room: testRoom.roomId,
content: {
msgtype: MsgType.Text,
body: body,
format: "org.matrix.custom.html",
formatted_body: formattedBody,
},
});
Notifier.displayPopupNotification(spoilerEvent, testRoom);
expect(MockPlatform.displayNotification).toHaveBeenCalledWith(
"@bob:example.org (!room1:server)",
expected,
expect.any(String),
testRoom,
spoilerEvent,
);
});
});
describe("getSoundForRoom", () => {

View File

@ -1,33 +0,0 @@
/*
Copyright 2025 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { getMockClientWithEventEmitter } from "../test-utils";
import { inviteMultipleToRoom } from "../../src/RoomInvite.tsx";
afterEach(() => {
jest.restoreAllMocks();
});
describe("inviteMultipleToRoom", () => {
it("can be called wth no `options`", async () => {
const client = getMockClientWithEventEmitter({});
const { states, inviter } = await inviteMultipleToRoom(client, "!room:id", []);
expect(states).toEqual({});
// @ts-ignore reference to private property
expect(inviter.options).toEqual({});
});
});

View File

@ -128,7 +128,7 @@ exports[`<UnsupportedBrowserView /> should match snapshot 1`] = `
</div>
</div>
<div
class="_separator_cqpyv_8"
class="_separator_13qwf_8"
data-kind="primary"
data-orientation="horizontal"
role="separator"

View File

@ -107,7 +107,7 @@ exports[`MessagePanel should handle lots of membership events quickly 1`] = `
class="mx_GenericEventListSummary_avatars"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="1"
data-testid="avatar-img"
data-type="round"

View File

@ -11,7 +11,7 @@ exports[`RoomView for a local room in state CREATING should match the snapshot 1
>
<span
aria-label="Open room settings"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -95,7 +95,7 @@ exports[`RoomView for a local room in state ERROR should match the snapshot 1`]
>
<span
aria-label="Open room settings"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -185,7 +185,7 @@ exports[`RoomView for a local room in state ERROR should match the snapshot 1`]
<button
aria-label="Avatar"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -285,7 +285,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
>
<span
aria-label="Open room settings"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -375,7 +375,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
<button
aria-label="Avatar"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -663,7 +663,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
>
<span
aria-label="Open room settings"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -748,7 +748,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
<button
aria-label="Avatar"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -1023,7 +1023,7 @@ exports[`RoomView invites renders an invite room 1`] = `
</h3>
<p>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -1105,7 +1105,7 @@ exports[`RoomView should hide the composer when hideComposer=true 1`] = `
<button
aria-label="Open room settings"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -1257,7 +1257,7 @@ exports[`RoomView should hide the composer when hideComposer=true 1`] = `
tabindex="0"
>
<div
class="_stacked-avatars_zysgz_109"
class="_stacked-avatars_7h2br_109"
/>
0
</div>
@ -1644,7 +1644,7 @@ exports[`RoomView should hide the pinned message banner when hidePinnedMessageBa
<button
aria-label="Open room settings"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -1796,7 +1796,7 @@ exports[`RoomView should hide the pinned message banner when hidePinnedMessageBa
tabindex="0"
>
<div
class="_stacked-avatars_zysgz_109"
class="_stacked-avatars_7h2br_109"
/>
0
</div>
@ -2119,7 +2119,7 @@ exports[`RoomView should hide the right panel when hideRightPanel=true 1`] = `
<button
aria-label="Open room settings"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -2271,7 +2271,7 @@ exports[`RoomView should hide the right panel when hideRightPanel=true 1`] = `
tabindex="0"
>
<div
class="_stacked-avatars_zysgz_109"
class="_stacked-avatars_7h2br_109"
/>
0
</div>
@ -2594,7 +2594,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
<button
aria-label="Open room settings"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -2746,7 +2746,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
tabindex="0"
>
<div
class="_stacked-avatars_zysgz_109"
class="_stacked-avatars_7h2br_109"
/>
0
</div>
@ -2808,7 +2808,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
<button
aria-label="Open room settings"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -2960,7 +2960,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
tabindex="0"
>
<div
class="_stacked-avatars_zysgz_109"
class="_stacked-avatars_7h2br_109"
/>
0
</div>
@ -3323,7 +3323,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
<button
aria-label="Open room settings"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -3448,7 +3448,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
tabindex="0"
>
<div
class="_stacked-avatars_zysgz_109"
class="_stacked-avatars_7h2br_109"
/>
0
</div>

View File

@ -86,7 +86,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="mx_SpaceHierarchy_roomTile_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="5"
data-testid="avatar-img"
data-type="round"
@ -184,7 +184,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="mx_SpaceHierarchy_roomTile_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="6"
data-testid="avatar-img"
data-type="round"
@ -283,7 +283,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="mx_SpaceHierarchy_roomTile_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -400,7 +400,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="mx_SpaceHierarchy_roomTile_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -504,7 +504,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
class="mx_SpaceHierarchy_roomTile_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="6"
data-testid="avatar-img"
data-type="round"
@ -675,7 +675,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> should not render cycles 1`] = `
class="mx_SpaceHierarchy_roomTile_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="5"
data-testid="avatar-img"
data-type="round"
@ -773,7 +773,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> should not render cycles 1`] = `
class="mx_SpaceHierarchy_roomTile_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="6"
data-testid="avatar-img"
data-type="round"
@ -872,7 +872,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> should not render cycles 1`] = `
class="mx_SpaceHierarchy_roomTile_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"

View File

@ -53,8 +53,9 @@ exports[`CompleteSecurity Allows verifying with another device if one is availab
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="primary"
data-size="lg"
>
<svg
fill="currentColor"
@ -245,8 +246,9 @@ exports[`CompleteSecurity Allows verifying with recovery key if one is available
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="primary"
data-size="lg"
>
<svg
fill="currentColor"

View File

@ -42,8 +42,9 @@ exports[`<MasUnlockCrossSigningAuthEntry/> should render 1`] = `
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="primary"
data-size="lg"
>
<svg
fill="currentColor"

View File

@ -6,7 +6,7 @@ exports[`DecoratedRoomAvatar shows an avatar with globe icon and tooltip for pub
class="mx_DecoratedRoomAvatar mx_DecoratedRoomAvatar_cutout"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -42,7 +42,7 @@ exports[`DecoratedRoomAvatar shows the presence indicator in a DM room that also
class="mx_DecoratedRoomAvatar mx_DecoratedRoomAvatar_cutout"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="5"
data-testid="avatar-img"
data-type="round"

View File

@ -3,7 +3,7 @@
exports[`RoomAvatar should not render an invite avatar if the user has disabled it 1`] = `
<div>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="6"
data-testid="avatar-img"
data-type="round"
@ -19,7 +19,7 @@ exports[`RoomAvatar should render an avatar for a room the user is invited to 1`
<div>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar"
data-color="6"
data-testid="avatar-img"
data-type="round"
@ -27,7 +27,7 @@ exports[`RoomAvatar should render an avatar for a room the user is invited to 1`
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="36px"
loading="lazy"
@ -42,7 +42,7 @@ exports[`RoomAvatar should render an avatar for a room the user is invited to 1`
exports[`RoomAvatar should render as expected for a DM room 1`] = `
<div>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -57,7 +57,7 @@ exports[`RoomAvatar should render as expected for a DM room 1`] = `
exports[`RoomAvatar should render as expected for a LocalRoom 1`] = `
<div>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -72,7 +72,7 @@ exports[`RoomAvatar should render as expected for a LocalRoom 1`] = `
exports[`RoomAvatar should render as expected for a Room 1`] = `
<div>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="6"
data-testid="avatar-img"
data-type="round"

View File

@ -4,7 +4,7 @@ exports[`<RoomAvatarView /> should not render a decoration 1`] = `
<DocumentFragment>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -12,7 +12,7 @@ exports[`<RoomAvatarView /> should not render a decoration 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="32px"
loading="lazy"
@ -32,7 +32,7 @@ exports[`<RoomAvatarView /> should render a low priority room decoration 1`] = `
>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_icon"
class="_avatar_7h2br_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_icon"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -40,7 +40,7 @@ exports[`<RoomAvatarView /> should render a low priority room decoration 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="32px"
loading="lazy"
@ -76,7 +76,7 @@ exports[`<RoomAvatarView /> should render a public room decoration 1`] = `
>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_icon"
class="_avatar_7h2br_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_icon"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -84,7 +84,7 @@ exports[`<RoomAvatarView /> should render a public room decoration 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="32px"
loading="lazy"
@ -120,7 +120,7 @@ exports[`<RoomAvatarView /> should render a video room decoration 1`] = `
>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_icon"
class="_avatar_7h2br_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_icon"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -128,7 +128,7 @@ exports[`<RoomAvatarView /> should render a video room decoration 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="32px"
loading="lazy"
@ -164,7 +164,7 @@ exports[`<RoomAvatarView /> should render the AWAY presence 1`] = `
>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_presence"
class="_avatar_7h2br_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_presence"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -172,7 +172,7 @@ exports[`<RoomAvatarView /> should render the AWAY presence 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="32px"
loading="lazy"
@ -221,7 +221,7 @@ exports[`<RoomAvatarView /> should render the BUSY presence 1`] = `
>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_presence"
class="_avatar_7h2br_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_presence"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -229,7 +229,7 @@ exports[`<RoomAvatarView /> should render the BUSY presence 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="32px"
loading="lazy"
@ -280,7 +280,7 @@ exports[`<RoomAvatarView /> should render the OFFLINE presence 1`] = `
>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_presence"
class="_avatar_7h2br_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_presence"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -288,7 +288,7 @@ exports[`<RoomAvatarView /> should render the OFFLINE presence 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="32px"
loading="lazy"
@ -339,7 +339,7 @@ exports[`<RoomAvatarView /> should render the ONLINE presence 1`] = `
>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_presence"
class="_avatar_7h2br_8 mx_BaseAvatar mx_RoomAvatarView_RoomAvatar mx_RoomAvatarView_RoomAvatar_presence"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -347,7 +347,7 @@ exports[`<RoomAvatarView /> should render the ONLINE presence 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="32px"
loading="lazy"

View File

@ -11,7 +11,7 @@ exports[`<BeaconMarker /> renders marker when beacon has location 1`] = `
class="mx_Marker_border"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="6"
data-testid="avatar-img"
data-type="round"

View File

@ -41,7 +41,7 @@ exports[`<BeaconViewDialog /> renders own beacon status when user is live sharin
class="mx_DialogOwnBeaconStatus"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar mx_DialogOwnBeaconStatus_avatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar mx_DialogOwnBeaconStatus_avatar _avatar-imageless_7h2br_55"
data-color="6"
data-testid="avatar-img"
data-type="round"

View File

@ -41,7 +41,7 @@ exports[`<DialogSidebar /> renders sidebar correctly with beacons 1`] = `
class="mx_BeaconListItem"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar mx_BeaconListItem_avatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar mx_BeaconListItem_avatar _avatar-imageless_7h2br_55"
data-color="1"
data-testid="avatar-img"
data-type="round"

View File

@ -9,8 +9,9 @@ exports[`ConfirmKeyStorageOffDialog renders 1`] = `
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8 _destructive_1r8kr_34"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="critical"
data-size="lg"
>
<svg
fill="currentColor"

View File

@ -36,7 +36,7 @@ exports[`ConfirmUserActionDialog renders 1`] = `
class="mx_ConfirmUserActionDialog_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"

View File

@ -120,7 +120,7 @@ exports[`<ManageRestrictedJoinRuleDialog /> should list spaces which are not par
>
<div>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="1"
data-testid="avatar-img"
data-type="round"

View File

@ -106,7 +106,7 @@ exports[`AppTile for a pinned widget should render 1`] = `
<span>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar mx_WidgetAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar mx_WidgetAvatar"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -115,7 +115,7 @@ exports[`AppTile for a pinned widget should render 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="20px"
loading="lazy"
@ -222,7 +222,7 @@ exports[`AppTile for a pinned widget should render permission request 1`] = `
<span>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar mx_WidgetAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar mx_WidgetAvatar"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -231,7 +231,7 @@ exports[`AppTile for a pinned widget should render permission request 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="20px"
loading="lazy"
@ -329,7 +329,7 @@ exports[`AppTile for a pinned widget should render permission request 1`] = `
</div>
<div>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -417,7 +417,7 @@ exports[`AppTile preserves non-persisted widget on container move 1`] = `
<span>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar mx_WidgetAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar mx_WidgetAvatar"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -426,7 +426,7 @@ exports[`AppTile preserves non-persisted widget on container move 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="20px"
loading="lazy"

View File

@ -9,10 +9,10 @@ exports[`<FacePile /> renders with a tooltip 1`] = `
tabindex="0"
>
<div
class="_stacked-avatars_zysgz_109"
class="_stacked-avatars_7h2br_109"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="4"
data-testid="avatar-img"
data-type="round"

View File

@ -40,7 +40,7 @@ exports[`<Pill> should render the expected pill for @room 1`] = `
>
<span
aria-hidden="true"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -71,7 +71,7 @@ exports[`<Pill> should render the expected pill for a known user not in the room
>
<span
aria-hidden="true"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="5"
data-testid="avatar-img"
data-type="round"
@ -101,7 +101,7 @@ exports[`<Pill> should render the expected pill for a message in another room 1`
>
<span
aria-hidden="true"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -131,7 +131,7 @@ exports[`<Pill> should render the expected pill for a message in the same room 1
>
<span
aria-hidden="true"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="4"
data-testid="avatar-img"
data-type="round"
@ -161,7 +161,7 @@ exports[`<Pill> should render the expected pill for a room alias 1`] = `
>
<span
aria-hidden="true"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -191,7 +191,7 @@ exports[`<Pill> should render the expected pill for a space 1`] = `
>
<span
aria-hidden="true"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -252,7 +252,7 @@ exports[`<Pill> when rendering a pill for a room should render the expected pill
>
<span
aria-hidden="true"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -282,7 +282,7 @@ exports[`<Pill> when rendering a pill for a user in the room should render as ex
>
<span
aria-hidden="true"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="4"
data-testid="avatar-img"
data-type="round"

View File

@ -20,7 +20,7 @@ exports[`ReplyChain should call setQuoteExpanded if chain is longer than 2 lines
class="mx_ReplyTile_sender"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"

View File

@ -10,10 +10,10 @@ exports[`<RoomFacePile /> renders 1`] = `
tabindex="0"
>
<div
class="_stacked-avatars_zysgz_109"
class="_stacked-avatars_7h2br_109"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="4"
data-testid="avatar-img"
data-type="round"

View File

@ -214,36 +214,28 @@ describe("<TextualBody />", () => {
const ev = mkRoomTextMessage("Chat with @user:example.com");
const { container } = getComponent({ mxEvent: ev });
const content = container.querySelector(".mx_EventTile_body");
expect(content.innerHTML).toMatchInlineSnapshot(
`"Chat with <a href="https://matrix.to/#/@user:example.com" rel="noreferrer noopener" data-linkified="true">@user:example.com</a>"`,
);
expect(content.innerHTML).toMatchSnapshot();
});
it("should pillify an MXID permalink", () => {
const ev = mkRoomTextMessage("Chat with https://matrix.to/#/@user:example.com");
const { container } = getComponent({ mxEvent: ev });
const content = container.querySelector(".mx_EventTile_body");
expect(content.innerHTML).toMatchInlineSnapshot(
`"Chat with <bdi><a class="mx_Pill mx_UserPill mx_UserPill_me" href="https://matrix.to/#/@user:example.com"><span aria-label="Profile picture" aria-hidden="true" data-testid="avatar-img" data-type="round" data-color="2" class="_avatar_zysgz_8 mx_BaseAvatar" style="--cpd-avatar-size: 16px;"><img loading="lazy" alt="" referrerpolicy="no-referrer" class="_image_zysgz_43" data-type="round" width="16px" height="16px" src="mxc://avatar.url/image.png"></span><span class="mx_Pill_text">Member</span></a></bdi>"`,
);
expect(content.innerHTML).toMatchSnapshot();
});
it("should not pillify room aliases", () => {
const ev = mkRoomTextMessage("Visit #room:example.com");
const { container } = getComponent({ mxEvent: ev });
const content = container.querySelector(".mx_EventTile_body");
expect(content.innerHTML).toMatchInlineSnapshot(
`"Visit <a href="https://matrix.to/#/#room:example.com" rel="noreferrer noopener" data-linkified="true">#room:example.com</a>"`,
);
expect(content.innerHTML).toMatchSnapshot();
});
it("should pillify a room alias permalink", () => {
const ev = mkRoomTextMessage("Visit https://matrix.to/#/#room:example.com");
const { container } = getComponent({ mxEvent: ev });
const content = container.querySelector(".mx_EventTile_body");
expect(content.innerHTML).toMatchInlineSnapshot(
`"Visit <bdi><a class="mx_Pill mx_RoomPill" href="https://matrix.to/#/#room:example.com"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 24 24" class="mx_Pill_LinkIcon mx_BaseAvatar"><path d="M12 19.071q-1.467 1.467-3.536 1.467-2.067 0-3.535-1.467t-1.467-3.535q0-2.07 1.467-3.536L7.05 9.879q.3-.3.707-.3t.707.3.301.707-.3.707l-2.122 2.121a2.9 2.9 0 0 0-.884 2.122q0 1.237.884 2.12.884.885 2.121.885t2.122-.884l2.121-2.121q.3-.3.707-.3t.707.3.3.707q0 .405-.3.707zm-1.414-4.243q-.3.3-.707.301a.97.97 0 0 1-.707-.3q-.3-.3-.301-.708 0-.405.3-.707l4.243-4.242q.3-.3.707-.3t.707.3.3.707-.3.707zm6.364-.707q-.3.3-.707.3a.97.97 0 0 1-.707-.3q-.3-.3-.301-.707 0-.405.3-.707l2.122-2.121q.884-.885.884-2.121 0-1.238-.884-2.122a2.9 2.9 0 0 0-2.121-.884q-1.237 0-2.122.884l-2.121 2.122q-.3.3-.707.3a.97.97 0 0 1-.707-.3q-.3-.3-.3-.708 0-.405.3-.707L12 4.93q1.467-1.467 3.536-1.467t3.535 1.467 1.467 3.536T19.071 12z"></path></svg><span class="mx_Pill_text">#room:example.com</span></a></bdi>"`,
);
expect(content.innerHTML).toMatchSnapshot();
});
it("should pillify a permalink to a message in the same room with the label »Message from Member«", () => {
@ -279,9 +271,7 @@ describe("<TextualBody />", () => {
});
const { container } = getComponent({ mxEvent: ev });
const content = container.querySelector(".mx_EventTile_body");
expect(content.innerHTML).toMatchInlineSnapshot(
`"foo <bdi><span tabindex="0"><span class="mx_Pill mx_KeywordPill"><span class="mx_Pill_text">bar</span></span></span></bdi> baz"`,
);
expect(content.innerHTML).toMatchSnapshot();
});
});

View File

@ -74,7 +74,7 @@ exports[`<MImageBody/> should open ImageView using thumbnail for encrypted svg 1
<button
aria-label="Profile picture"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar mx_Dialog_nonDialogButton _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar mx_Dialog_nonDialogButton _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"

View File

@ -92,7 +92,7 @@ exports[`MLocationBody <MLocationBody> without error renders marker correctly fo
class="mx_Marker_border"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"

View File

@ -100,7 +100,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for an
<span
aria-hidden="true"
aria-label="Profile picture"
class="_avatar_zysgz_8 mx_BaseAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -108,7 +108,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for an
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="16px"
loading="lazy"
@ -145,7 +145,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for eve
<span
aria-hidden="true"
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -153,7 +153,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for eve
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="16px"
loading="lazy"
@ -192,7 +192,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for roo
<span
aria-hidden="true"
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -200,7 +200,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for roo
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="16px"
loading="lazy"
@ -319,7 +319,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills get injected c
<span
aria-hidden="true"
aria-label="Profile picture"
class="_avatar_zysgz_8 mx_BaseAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -327,7 +327,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills get injected c
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="16px"
loading="lazy"
@ -567,9 +567,15 @@ exports[`<TextualBody /> renders plain-text m.text correctly linkification get a
</div>
`;
exports[`<TextualBody /> renders plain-text m.text correctly should pillify a permalink to a message in the same room with the label »Message from Member« 1`] = `"Visit <bdi><a class="mx_Pill mx_EventPill" href="https://matrix.to/#/!room1:example.com/%event_id%"><span aria-label="Profile picture" aria-hidden="true" data-testid="avatar-img" data-type="round" data-color="2" class="_avatar_zysgz_8 mx_BaseAvatar" style="--cpd-avatar-size: 16px;"><img loading="lazy" alt="" referrerpolicy="no-referrer" class="_image_zysgz_43" data-type="round" width="16px" height="16px" src="mxc://avatar.url/image.png"></span><span class="mx_Pill_text">Message from Member</span></a></bdi>"`;
exports[`<TextualBody /> renders plain-text m.text correctly should not pillify MXIDs 1`] = `"Chat with <a href="https://matrix.to/#/@user:example.com" rel="noreferrer noopener" data-linkified="true">@user:example.com</a>"`;
exports[`<TextualBody /> renders plain-text m.text correctly should pillify a permalink to an event in another room with the label »Message in Room 2« 1`] = `"Visit <bdi><a class="mx_Pill mx_EventPill" href="https://matrix.to/#/!room2:example.com/%event_id%"><span aria-label="Avatar" aria-hidden="true" data-testid="avatar-img" data-type="round" data-color="2" class="_avatar_zysgz_8 mx_BaseAvatar" style="--cpd-avatar-size: 16px;"><img loading="lazy" alt="" referrerpolicy="no-referrer" class="_image_zysgz_43" data-type="round" width="16px" height="16px" src="mxc://avatar.url/room.png"></span><span class="mx_Pill_text">Message in Room 2</span></a></bdi>"`;
exports[`<TextualBody /> renders plain-text m.text correctly should not pillify room aliases 1`] = `"Visit <a href="https://matrix.to/#/#room:example.com" rel="noreferrer noopener" data-linkified="true">#room:example.com</a>"`;
exports[`<TextualBody /> renders plain-text m.text correctly should pillify a keyword responsible for triggering a notification 1`] = `"foo <bdi><span tabindex="0"><span class="mx_Pill mx_KeywordPill"><span class="mx_Pill_text">bar</span></span></span></bdi> baz"`;
exports[`<TextualBody /> renders plain-text m.text correctly should pillify a permalink to a message in the same room with the label »Message from Member« 1`] = `"Visit <bdi><a class="mx_Pill mx_EventPill" href="https://matrix.to/#/!room1:example.com/%event_id%"><span aria-label="Profile picture" aria-hidden="true" data-testid="avatar-img" data-type="round" data-color="2" class="_avatar_7h2br_8 mx_BaseAvatar" style="--cpd-avatar-size: 16px;"><img loading="lazy" alt="" referrerpolicy="no-referrer" class="_image_7h2br_43" data-type="round" width="16px" height="16px" src="mxc://avatar.url/image.png"></span><span class="mx_Pill_text">Message from Member</span></a></bdi>"`;
exports[`<TextualBody /> renders plain-text m.text correctly should pillify a permalink to an event in another room with the label »Message in Room 2« 1`] = `"Visit <bdi><a class="mx_Pill mx_EventPill" href="https://matrix.to/#/!room2:example.com/%event_id%"><span aria-label="Avatar" aria-hidden="true" data-testid="avatar-img" data-type="round" data-color="2" class="_avatar_7h2br_8 mx_BaseAvatar" style="--cpd-avatar-size: 16px;"><img loading="lazy" alt="" referrerpolicy="no-referrer" class="_image_7h2br_43" data-type="round" width="16px" height="16px" src="mxc://avatar.url/room.png"></span><span class="mx_Pill_text">Message in Room 2</span></a></bdi>"`;
exports[`<TextualBody /> renders plain-text m.text correctly should pillify a permalink to an unknown message in the same room with the label »Message« 1`] = `
<div
@ -604,6 +610,10 @@ exports[`<TextualBody /> renders plain-text m.text correctly should pillify a pe
</div>
`;
exports[`<TextualBody /> renders plain-text m.text correctly should pillify a room alias permalink 1`] = `"Visit <bdi><a class="mx_Pill mx_RoomPill" href="https://matrix.to/#/#room:example.com"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 24 24" class="mx_Pill_LinkIcon mx_BaseAvatar"><path d="M12 19.071q-1.467 1.467-3.536 1.467-2.067 0-3.535-1.467t-1.467-3.535q0-2.07 1.467-3.536L7.05 9.879q.3-.3.707-.3t.707.3.301.707-.3.707l-2.122 2.121a2.9 2.9 0 0 0-.884 2.122q0 1.237.884 2.12.884.885 2.121.885t2.122-.884l2.121-2.121q.3-.3.707-.3t.707.3.3.707q0 .405-.3.707zm-1.414-4.243q-.3.3-.707.301a.97.97 0 0 1-.707-.3q-.3-.3-.301-.708 0-.405.3-.707l4.243-4.242q.3-.3.707-.3t.707.3.3.707-.3.707zm6.364-.707q-.3.3-.707.3a.97.97 0 0 1-.707-.3q-.3-.3-.301-.707 0-.405.3-.707l2.122-2.121q.884-.885.884-2.121 0-1.238-.884-2.122a2.9 2.9 0 0 0-2.121-.884q-1.237 0-2.122.884l-2.121 2.122q-.3.3-.707.3a.97.97 0 0 1-.707-.3q-.3-.3-.3-.708 0-.405.3-.707L12 4.93q1.467-1.467 3.536-1.467t3.535 1.467 1.467 3.536T19.071 12z"></path></svg><span class="mx_Pill_text">#room:example.com</span></a></bdi>"`;
exports[`<TextualBody /> renders plain-text m.text correctly should pillify an MXID permalink 1`] = `"Chat with <bdi><a class="mx_Pill mx_UserPill mx_UserPill_me" href="https://matrix.to/#/@user:example.com"><span aria-label="Profile picture" aria-hidden="true" data-testid="avatar-img" data-type="round" data-color="2" class="_avatar_7h2br_8 mx_BaseAvatar" style="--cpd-avatar-size: 16px;"><img loading="lazy" alt="" referrerpolicy="no-referrer" class="_image_7h2br_43" data-type="round" width="16px" height="16px" src="mxc://avatar.url/image.png"></span><span class="mx_Pill_text">Member</span></a></bdi>"`;
exports[`<TextualBody /> renders plain-text m.text correctly simple message renders as expected 1`] = `
<div
class="mx_EventTile_body translate"

View File

@ -172,7 +172,7 @@ exports[`<ExtensionsCard /> should render widgets 1`] = `
Add extensions
</button>
<div
class="_separator_cqpyv_8"
class="_separator_13qwf_8"
data-kind="primary"
data-orientation="horizontal"
role="separator"
@ -187,7 +187,7 @@ exports[`<ExtensionsCard /> should render widgets 1`] = `
>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar mx_WidgetAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar mx_WidgetAvatar"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -196,7 +196,7 @@ exports[`<ExtensionsCard /> should render widgets 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="24px"
loading="lazy"
@ -240,7 +240,7 @@ exports[`<ExtensionsCard /> should render widgets 1`] = `
>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar mx_WidgetAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar mx_WidgetAvatar"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -249,7 +249,7 @@ exports[`<ExtensionsCard /> should render widgets 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="24px"
loading="lazy"

View File

@ -141,7 +141,7 @@ exports[`<PinnedMessagesCard /> should show two pinned messages 1`] = `
>
<div>
<span
class="_avatar_zysgz_8 mx_BaseAvatar mx_PinnedEventTile_senderAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar mx_PinnedEventTile_senderAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -211,7 +211,7 @@ exports[`<PinnedMessagesCard /> should show two pinned messages 1`] = `
</div>
</div>
<div
class="_separator_cqpyv_8 mx_PinnedMessagesCard_Separator"
class="_separator_13qwf_8 mx_PinnedMessagesCard_Separator"
data-kind="primary"
data-orientation="horizontal"
role="separator"
@ -222,7 +222,7 @@ exports[`<PinnedMessagesCard /> should show two pinned messages 1`] = `
>
<div>
<span
class="_avatar_zysgz_8 mx_BaseAvatar mx_PinnedEventTile_senderAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar mx_PinnedEventTile_senderAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -369,7 +369,7 @@ exports[`<PinnedMessagesCard /> unpin all should not allow to unpinall 1`] = `
>
<div>
<span
class="_avatar_zysgz_8 mx_BaseAvatar mx_PinnedEventTile_senderAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar mx_PinnedEventTile_senderAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -439,7 +439,7 @@ exports[`<PinnedMessagesCard /> unpin all should not allow to unpinall 1`] = `
</div>
</div>
<div
class="_separator_cqpyv_8 mx_PinnedMessagesCard_Separator"
class="_separator_13qwf_8 mx_PinnedMessagesCard_Separator"
data-kind="primary"
data-orientation="horizontal"
role="separator"
@ -450,7 +450,7 @@ exports[`<PinnedMessagesCard /> unpin all should not allow to unpinall 1`] = `
>
<div>
<span
class="_avatar_zysgz_8 mx_BaseAvatar mx_PinnedEventTile_senderAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar mx_PinnedEventTile_senderAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"

View File

@ -61,7 +61,7 @@ exports[`<UserInfo /> with crypto enabled renders <BasicUserInfo /> 1`] = `
<button
aria-label="Profile picture"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -144,13 +144,13 @@ exports[`<UserInfo /> with crypto enabled renders <BasicUserInfo /> 1`] = `
class="mx_UserInfo_container"
>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -162,13 +162,13 @@ exports[`<UserInfo /> with crypto enabled renders <BasicUserInfo /> 1`] = `
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Send message
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -181,14 +181,14 @@ exports[`<UserInfo /> with crypto enabled renders <BasicUserInfo /> 1`] = `
</svg>
</button>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26 _disabled_lqfwq_118"
class="_item_bym9p_8 _interactive_bym9p_26 _disabled_bym9p_140"
data-kind="primary"
disabled=""
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -200,13 +200,13 @@ exports[`<UserInfo /> with crypto enabled renders <BasicUserInfo /> 1`] = `
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Jump to read receipt
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -219,13 +219,13 @@ exports[`<UserInfo /> with crypto enabled renders <BasicUserInfo /> 1`] = `
</svg>
</button>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -237,13 +237,13 @@ exports[`<UserInfo /> with crypto enabled renders <BasicUserInfo /> 1`] = `
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Share profile
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -260,13 +260,13 @@ exports[`<UserInfo /> with crypto enabled renders <BasicUserInfo /> 1`] = `
class="mx_UserInfo_container"
>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="critical"
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -278,13 +278,13 @@ exports[`<UserInfo /> with crypto enabled renders <BasicUserInfo /> 1`] = `
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Ignore
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -363,7 +363,7 @@ exports[`<UserInfo /> with crypto enabled should render a deactivate button for
<button
aria-label="Profile picture"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -446,13 +446,13 @@ exports[`<UserInfo /> with crypto enabled should render a deactivate button for
class="mx_UserInfo_container"
>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -464,13 +464,13 @@ exports[`<UserInfo /> with crypto enabled should render a deactivate button for
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Send message
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -483,14 +483,14 @@ exports[`<UserInfo /> with crypto enabled should render a deactivate button for
</svg>
</button>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26 _disabled_lqfwq_118"
class="_item_bym9p_8 _interactive_bym9p_26 _disabled_bym9p_140"
data-kind="primary"
disabled=""
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -502,13 +502,13 @@ exports[`<UserInfo /> with crypto enabled should render a deactivate button for
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Jump to read receipt
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -521,13 +521,13 @@ exports[`<UserInfo /> with crypto enabled should render a deactivate button for
</svg>
</button>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -539,13 +539,13 @@ exports[`<UserInfo /> with crypto enabled should render a deactivate button for
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Share profile
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -562,13 +562,13 @@ exports[`<UserInfo /> with crypto enabled should render a deactivate button for
class="mx_UserInfo_container"
>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="critical"
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -580,13 +580,13 @@ exports[`<UserInfo /> with crypto enabled should render a deactivate button for
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Deactivate user
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -603,13 +603,13 @@ exports[`<UserInfo /> with crypto enabled should render a deactivate button for
class="mx_UserInfo_container"
>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="critical"
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -621,13 +621,13 @@ exports[`<UserInfo /> with crypto enabled should render a deactivate button for
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Ignore
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"

View File

@ -55,13 +55,13 @@ exports[`<UserInfoBasic /> should display the defaut values 1`] = `
</div>
</div>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -73,13 +73,13 @@ exports[`<UserInfoBasic /> should display the defaut values 1`] = `
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Send message
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -92,13 +92,13 @@ exports[`<UserInfoBasic /> should display the defaut values 1`] = `
</svg>
</button>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -110,13 +110,13 @@ exports[`<UserInfoBasic /> should display the defaut values 1`] = `
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Invite
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -129,14 +129,14 @@ exports[`<UserInfoBasic /> should display the defaut values 1`] = `
</svg>
</button>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26 _disabled_lqfwq_118"
class="_item_bym9p_8 _interactive_bym9p_26 _disabled_bym9p_140"
data-kind="primary"
disabled=""
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -148,13 +148,13 @@ exports[`<UserInfoBasic /> should display the defaut values 1`] = `
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Jump to read receipt
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -167,13 +167,13 @@ exports[`<UserInfoBasic /> should display the defaut values 1`] = `
</svg>
</button>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -185,13 +185,13 @@ exports[`<UserInfoBasic /> should display the defaut values 1`] = `
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Share profile
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -204,13 +204,13 @@ exports[`<UserInfoBasic /> should display the defaut values 1`] = `
</svg>
</button>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -222,13 +222,13 @@ exports[`<UserInfoBasic /> should display the defaut values 1`] = `
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Mention
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -245,13 +245,13 @@ exports[`<UserInfoBasic /> should display the defaut values 1`] = `
class="mx_UserInfo_container"
>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="critical"
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -263,13 +263,13 @@ exports[`<UserInfoBasic /> should display the defaut values 1`] = `
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Deactivate user
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -286,13 +286,13 @@ exports[`<UserInfoBasic /> should display the defaut values 1`] = `
class="mx_UserInfo_container"
>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="critical"
role="button"
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -304,13 +304,13 @@ exports[`<UserInfoBasic /> should display the defaut values 1`] = `
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Ignore
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"

View File

@ -24,7 +24,7 @@ exports[`<UserInfoHeaderVerificationView /> renders verified badge when user is
style="--mx-flex-display: flex; --mx-flex-direction: row; --mx-flex-align: center; --mx-flex-justify: center; --mx-flex-gap: 0; --mx-flex-wrap: nowrap;"
>
<span
class="_typography_6v6n8_153 _font-body-sm-medium_6v6n8_41 _badge_18gm1_8 mx_UserInfo_verified_badge"
class="_typography_6v6n8_153 _font-body-sm-medium_6v6n8_41 _badge_10dml_8 mx_UserInfo_verified_badge"
data-kind="green"
>
<svg

View File

@ -14,7 +14,7 @@ exports[`<UserInfoHeaderView /> renders custom user identifiers in the header 1`
<button
aria-label="Profile picture"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"

View File

@ -9,7 +9,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
<button
aria-label="Open room settings"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"

View File

@ -8,7 +8,7 @@ exports[`<PinnedEventTile /> should render pinned event 1`] = `
>
<div>
<span
class="_avatar_zysgz_8 mx_BaseAvatar mx_PinnedEventTile_senderAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar mx_PinnedEventTile_senderAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -87,7 +87,7 @@ exports[`<PinnedEventTile /> should render pinned event with thread info 1`] = `
>
<div>
<span
class="_avatar_zysgz_8 mx_BaseAvatar mx_PinnedEventTile_senderAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar mx_PinnedEventTile_senderAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -202,7 +202,7 @@ exports[`<PinnedEventTile /> should render the menu with all the options 1`] = `
tabindex="-1"
>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
data-orientation="vertical"
data-radix-collection-item=""
@ -211,7 +211,7 @@ exports[`<PinnedEventTile /> should render the menu with all the options 1`] = `
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -223,13 +223,13 @@ exports[`<PinnedEventTile /> should render the menu with all the options 1`] = `
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
View in timeline
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -242,7 +242,7 @@ exports[`<PinnedEventTile /> should render the menu with all the options 1`] = `
</svg>
</button>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
data-orientation="vertical"
data-radix-collection-item=""
@ -251,7 +251,7 @@ exports[`<PinnedEventTile /> should render the menu with all the options 1`] = `
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -268,13 +268,13 @@ exports[`<PinnedEventTile /> should render the menu with all the options 1`] = `
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Unpin
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -287,7 +287,7 @@ exports[`<PinnedEventTile /> should render the menu with all the options 1`] = `
</svg>
</button>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
data-orientation="vertical"
data-radix-collection-item=""
@ -296,7 +296,7 @@ exports[`<PinnedEventTile /> should render the menu with all the options 1`] = `
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -308,13 +308,13 @@ exports[`<PinnedEventTile /> should render the menu with all the options 1`] = `
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Forward
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -327,13 +327,13 @@ exports[`<PinnedEventTile /> should render the menu with all the options 1`] = `
</svg>
</button>
<div
class="_separator_cqpyv_8"
class="_separator_13qwf_8"
data-kind="primary"
data-orientation="horizontal"
role="separator"
/>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="critical"
data-orientation="vertical"
data-radix-collection-item=""
@ -342,7 +342,7 @@ exports[`<PinnedEventTile /> should render the menu with all the options 1`] = `
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -354,13 +354,13 @@ exports[`<PinnedEventTile /> should render the menu with all the options 1`] = `
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Delete
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -393,7 +393,7 @@ exports[`<PinnedEventTile /> should render the menu without unpin and delete 1`]
tabindex="-1"
>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
data-orientation="vertical"
data-radix-collection-item=""
@ -402,7 +402,7 @@ exports[`<PinnedEventTile /> should render the menu without unpin and delete 1`]
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -414,13 +414,13 @@ exports[`<PinnedEventTile /> should render the menu without unpin and delete 1`]
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
View in timeline
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -433,7 +433,7 @@ exports[`<PinnedEventTile /> should render the menu without unpin and delete 1`]
</svg>
</button>
<button
class="_item_lqfwq_8 _interactive_lqfwq_26"
class="_item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
data-orientation="vertical"
data-radix-collection-item=""
@ -442,7 +442,7 @@ exports[`<PinnedEventTile /> should render the menu without unpin and delete 1`]
>
<svg
aria-hidden="true"
class="_icon_lqfwq_50"
class="_icon_bym9p_51"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
@ -454,13 +454,13 @@ exports[`<PinnedEventTile /> should render the menu without unpin and delete 1`]
/>
</svg>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
Forward
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"

View File

@ -59,7 +59,7 @@ exports[`ReadReceiptGroup <ReadReceiptPerson /> should fall back to userId if ro
<span
aria-hidden="true"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -99,7 +99,7 @@ exports[`ReadReceiptGroup <ReadReceiptPerson /> should render 1`] = `
aria-hidden="true"
aria-label="Profile picture"
aria-live="off"
class="_avatar_zysgz_8 mx_BaseAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -107,7 +107,7 @@ exports[`ReadReceiptGroup <ReadReceiptPerson /> should render 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="24px"
loading="lazy"

View File

@ -23,7 +23,7 @@ exports[`<RoomPreviewBar /> message case AskToJoin renders the corresponding mes
</h3>
<p>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="6"
data-testid="avatar-img"
data-type="round"
@ -48,7 +48,7 @@ exports[`<RoomPreviewBar /> message case AskToJoin renders the corresponding mes
</h3>
<p>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="6"
data-testid="avatar-img"
data-type="round"
@ -73,7 +73,7 @@ exports[`<RoomPreviewBar /> message case AskToJoin renders the corresponding mes
</h3>
<p>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="1"
data-testid="avatar-img"
data-type="round"
@ -274,7 +274,7 @@ exports[`<RoomPreviewBar /> with an invite with an invited email when client has
</h3>
<p>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="6"
data-testid="avatar-img"
data-type="round"
@ -332,7 +332,7 @@ exports[`<RoomPreviewBar /> with an invite without an invited email for a dm roo
</h3>
<p>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="6"
data-testid="avatar-img"
data-type="round"
@ -370,7 +370,7 @@ exports[`<RoomPreviewBar /> with an invite without an invited email for a non-dm
</h3>
<p>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="6"
data-testid="avatar-img"
data-type="round"

View File

@ -14,7 +14,7 @@ exports[`RoomTile when message previews are enabled and there is a message in a
class="mx_DecoratedRoomAvatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -112,7 +112,7 @@ exports[`RoomTile when message previews are enabled and there is a message in th
class="mx_DecoratedRoomAvatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -218,7 +218,7 @@ exports[`RoomTile when message previews are enabled should render a room without
class="mx_DecoratedRoomAvatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -304,7 +304,7 @@ exports[`RoomTile when message previews are not enabled should render the room 1
class="mx_DecoratedRoomAvatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"

View File

@ -19,7 +19,7 @@ exports[`MemberTileView RoomMemberTileView should display an verified E2EIcon wh
class="mx_MemberTileView_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -95,7 +95,7 @@ exports[`MemberTileView RoomMemberTileView should display an warning E2EIcon whe
class="mx_MemberTileView_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -171,7 +171,7 @@ exports[`MemberTileView RoomMemberTileView should not display an E2EIcon when th
class="mx_MemberTileView_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -230,7 +230,7 @@ exports[`MemberTileView ThreePidInviteTileView renders ThreePidInvite correctly
>
<span
aria-hidden="true"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="1"
data-testid="avatar-img"
data-type="round"

View File

@ -86,7 +86,7 @@ exports[`<LayoutSwitcher /> should render 1`] = `
class="mx_EventTile_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -180,7 +180,7 @@ exports[`<LayoutSwitcher /> should render 1`] = `
class="mx_EventTile_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -277,7 +277,7 @@ exports[`<LayoutSwitcher /> should render 1`] = `
class="mx_EventTile_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -354,7 +354,7 @@ exports[`<LayoutSwitcher /> should render 1`] = `
</form>
</div>
<div
class="_separator_cqpyv_8"
class="_separator_13qwf_8"
data-kind="primary"
data-orientation="horizontal"
role="separator"

View File

@ -270,7 +270,7 @@ exports[`<ThemeChoicePanel /> custom theme should display custom theme 1`] = `
</div>
</div>
<div
class="_separator_cqpyv_8"
class="_separator_13qwf_8"
data-kind="primary"
data-orientation="horizontal"
role="separator"
@ -549,7 +549,7 @@ exports[`<ThemeChoicePanel /> custom theme should render the custom theme sectio
</div>
</div>
<div
class="_separator_cqpyv_8"
class="_separator_13qwf_8"
data-kind="primary"
data-orientation="horizontal"
role="separator"
@ -719,7 +719,7 @@ exports[`<ThemeChoicePanel /> renders the theme choice UI 1`] = `
</form>
</div>
<div
class="_separator_cqpyv_8"
class="_separator_13qwf_8"
data-kind="primary"
data-orientation="horizontal"
role="separator"

View File

@ -3,7 +3,7 @@
exports[`<ChangeRecoveryKey /> flow to change the recovery key should display the recovery key 1`] = `
<DocumentFragment>
<nav
class="_breadcrumb_1xygz_8"
class="_breadcrumb_t96w3_8"
>
<button
aria-label="Back"
@ -31,13 +31,13 @@ exports[`<ChangeRecoveryKey /> flow to change the recovery key should display th
</div>
</button>
<ol
class="_pages_1xygz_17"
class="_pages_t96w3_17"
>
<li>
<a
class="_link_1v5rz_8"
class="_link_k9ljz_8"
data-kind="primary"
data-size="small"
data-size="sm"
rel="noreferrer noopener"
role="button"
tabindex="0"
@ -48,7 +48,7 @@ exports[`<ChangeRecoveryKey /> flow to change the recovery key should display th
<li>
<span
aria-current="page"
class="_last-page_1xygz_30"
class="_last-page_t96w3_30"
>
Change recovery key
</span>
@ -62,8 +62,9 @@ exports[`<ChangeRecoveryKey /> flow to change the recovery key should display th
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="primary"
data-size="lg"
>
<svg
fill="currentColor"
@ -165,7 +166,7 @@ exports[`<ChangeRecoveryKey /> flow to change the recovery key should display th
exports[`<ChangeRecoveryKey /> flow to set up a recovery key should ask the user to enter the recovery key 1`] = `
<DocumentFragment>
<nav
class="_breadcrumb_1xygz_8"
class="_breadcrumb_t96w3_8"
>
<button
aria-label="Back"
@ -193,13 +194,13 @@ exports[`<ChangeRecoveryKey /> flow to set up a recovery key should ask the user
</div>
</button>
<ol
class="_pages_1xygz_17"
class="_pages_t96w3_17"
>
<li>
<a
class="_link_1v5rz_8"
class="_link_k9ljz_8"
data-kind="primary"
data-size="small"
data-size="sm"
rel="noreferrer noopener"
role="button"
tabindex="0"
@ -210,7 +211,7 @@ exports[`<ChangeRecoveryKey /> flow to set up a recovery key should ask the user
<li>
<span
aria-current="page"
class="_last-page_1xygz_30"
class="_last-page_t96w3_30"
>
Get recovery key
</span>
@ -224,8 +225,9 @@ exports[`<ChangeRecoveryKey /> flow to set up a recovery key should ask the user
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="primary"
data-size="lg"
>
<svg
fill="currentColor"
@ -324,7 +326,7 @@ exports[`<ChangeRecoveryKey /> flow to set up a recovery key should ask the user
exports[`<ChangeRecoveryKey /> flow to set up a recovery key should ask the user to enter the recovery key 2`] = `
<DocumentFragment>
<nav
class="_breadcrumb_1xygz_8"
class="_breadcrumb_t96w3_8"
>
<button
aria-label="Back"
@ -352,13 +354,13 @@ exports[`<ChangeRecoveryKey /> flow to set up a recovery key should ask the user
</div>
</button>
<ol
class="_pages_1xygz_17"
class="_pages_t96w3_17"
>
<li>
<a
class="_link_1v5rz_8"
class="_link_k9ljz_8"
data-kind="primary"
data-size="small"
data-size="sm"
rel="noreferrer noopener"
role="button"
tabindex="0"
@ -369,7 +371,7 @@ exports[`<ChangeRecoveryKey /> flow to set up a recovery key should ask the user
<li>
<span
aria-current="page"
class="_last-page_1xygz_30"
class="_last-page_t96w3_30"
>
Get recovery key
</span>
@ -383,8 +385,9 @@ exports[`<ChangeRecoveryKey /> flow to set up a recovery key should ask the user
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="primary"
data-size="lg"
>
<svg
fill="currentColor"
@ -505,7 +508,7 @@ exports[`<ChangeRecoveryKey /> flow to set up a recovery key should ask the user
exports[`<ChangeRecoveryKey /> flow to set up a recovery key should display information about the recovery key 1`] = `
<DocumentFragment>
<nav
class="_breadcrumb_1xygz_8"
class="_breadcrumb_t96w3_8"
>
<button
aria-label="Back"
@ -533,13 +536,13 @@ exports[`<ChangeRecoveryKey /> flow to set up a recovery key should display info
</div>
</button>
<ol
class="_pages_1xygz_17"
class="_pages_t96w3_17"
>
<li>
<a
class="_link_1v5rz_8"
class="_link_k9ljz_8"
data-kind="primary"
data-size="small"
data-size="sm"
rel="noreferrer noopener"
role="button"
tabindex="0"
@ -550,7 +553,7 @@ exports[`<ChangeRecoveryKey /> flow to set up a recovery key should display info
<li>
<span
aria-current="page"
class="_last-page_1xygz_30"
class="_last-page_t96w3_30"
>
Get recovery key
</span>
@ -564,8 +567,9 @@ exports[`<ChangeRecoveryKey /> flow to set up a recovery key should display info
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="primary"
data-size="lg"
>
<svg
fill="currentColor"
@ -622,7 +626,7 @@ exports[`<ChangeRecoveryKey /> flow to set up a recovery key should display info
exports[`<ChangeRecoveryKey /> flow to set up a recovery key should display the recovery key 1`] = `
<DocumentFragment>
<nav
class="_breadcrumb_1xygz_8"
class="_breadcrumb_t96w3_8"
>
<button
aria-label="Back"
@ -650,13 +654,13 @@ exports[`<ChangeRecoveryKey /> flow to set up a recovery key should display the
</div>
</button>
<ol
class="_pages_1xygz_17"
class="_pages_t96w3_17"
>
<li>
<a
class="_link_1v5rz_8"
class="_link_k9ljz_8"
data-kind="primary"
data-size="small"
data-size="sm"
rel="noreferrer noopener"
role="button"
tabindex="0"
@ -667,7 +671,7 @@ exports[`<ChangeRecoveryKey /> flow to set up a recovery key should display the
<li>
<span
aria-current="page"
class="_last-page_1xygz_30"
class="_last-page_t96w3_30"
>
Get recovery key
</span>
@ -681,8 +685,9 @@ exports[`<ChangeRecoveryKey /> flow to set up a recovery key should display the
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="primary"
data-size="lg"
>
<svg
fill="currentColor"

View File

@ -3,7 +3,7 @@
exports[`<DeleteKeyStoragePanel /> should match snapshot 1`] = `
<DocumentFragment>
<nav
class="_breadcrumb_1xygz_8"
class="_breadcrumb_t96w3_8"
>
<button
aria-label="Back"
@ -31,13 +31,13 @@ exports[`<DeleteKeyStoragePanel /> should match snapshot 1`] = `
</div>
</button>
<ol
class="_pages_1xygz_17"
class="_pages_t96w3_17"
>
<li>
<a
class="_link_1v5rz_8"
class="_link_k9ljz_8"
data-kind="primary"
data-size="small"
data-size="sm"
rel="noreferrer noopener"
role="button"
tabindex="0"
@ -48,7 +48,7 @@ exports[`<DeleteKeyStoragePanel /> should match snapshot 1`] = `
<li>
<span
aria-current="page"
class="_last-page_1xygz_30"
class="_last-page_t96w3_30"
>
Delete key storage
</span>
@ -62,8 +62,9 @@ exports[`<DeleteKeyStoragePanel /> should match snapshot 1`] = `
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8 _destructive_1r8kr_34"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="critical"
data-size="lg"
>
<svg
fill="currentColor"
@ -89,7 +90,7 @@ exports[`<DeleteKeyStoragePanel /> should match snapshot 1`] = `
>
Deleting key storage will remove your cryptographic identity and message keys from the server and turn off the following security features:
<ul
class="_visual-list_1mgc1_8"
class="_visual-list_6zpfn_8"
>
<li
class="_visual-list-item_1nc1y_8"

View File

@ -9,8 +9,9 @@ exports[`<EncryptionCard /> should render 1`] = `
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="primary"
data-size="lg"
>
<svg
fill="currentColor"

View File

@ -3,7 +3,7 @@
exports[`<ResetIdentityPanel /> should display the 'forgot recovery key' variant correctly 1`] = `
<DocumentFragment>
<nav
class="_breadcrumb_1xygz_8"
class="_breadcrumb_t96w3_8"
>
<button
aria-label="Back"
@ -31,13 +31,13 @@ exports[`<ResetIdentityPanel /> should display the 'forgot recovery key' variant
</div>
</button>
<ol
class="_pages_1xygz_17"
class="_pages_t96w3_17"
>
<li>
<a
class="_link_1v5rz_8"
class="_link_k9ljz_8"
data-kind="primary"
data-size="small"
data-size="sm"
rel="noreferrer noopener"
role="button"
tabindex="0"
@ -48,7 +48,7 @@ exports[`<ResetIdentityPanel /> should display the 'forgot recovery key' variant
<li>
<span
aria-current="page"
class="_last-page_1xygz_30"
class="_last-page_t96w3_30"
>
Reset encryption
</span>
@ -62,8 +62,9 @@ exports[`<ResetIdentityPanel /> should display the 'forgot recovery key' variant
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8 _destructive_1r8kr_34"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="critical"
data-size="lg"
>
<svg
fill="currentColor"
@ -88,7 +89,7 @@ exports[`<ResetIdentityPanel /> should display the 'forgot recovery key' variant
style="--mx-flex-display: flex; --mx-flex-direction: column; --mx-flex-align: normal; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x); --mx-flex-wrap: nowrap;"
>
<ul
class="_visual-list_1mgc1_8"
class="_visual-list_6zpfn_8"
>
<li
class="_visual-list-item_1nc1y_8"
@ -186,7 +187,7 @@ exports[`<ResetIdentityPanel /> should display the 'forgot recovery key' variant
exports[`<ResetIdentityPanel /> should display the 'sync failed' variant correctly 1`] = `
<DocumentFragment>
<nav
class="_breadcrumb_1xygz_8"
class="_breadcrumb_t96w3_8"
>
<button
aria-label="Back"
@ -214,13 +215,13 @@ exports[`<ResetIdentityPanel /> should display the 'sync failed' variant correct
</div>
</button>
<ol
class="_pages_1xygz_17"
class="_pages_t96w3_17"
>
<li>
<a
class="_link_1v5rz_8"
class="_link_k9ljz_8"
data-kind="primary"
data-size="small"
data-size="sm"
rel="noreferrer noopener"
role="button"
tabindex="0"
@ -231,7 +232,7 @@ exports[`<ResetIdentityPanel /> should display the 'sync failed' variant correct
<li>
<span
aria-current="page"
class="_last-page_1xygz_30"
class="_last-page_t96w3_30"
>
Reset encryption
</span>
@ -245,8 +246,9 @@ exports[`<ResetIdentityPanel /> should display the 'sync failed' variant correct
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8 _destructive_1r8kr_34"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="critical"
data-size="lg"
>
<svg
fill="currentColor"
@ -271,7 +273,7 @@ exports[`<ResetIdentityPanel /> should display the 'sync failed' variant correct
style="--mx-flex-display: flex; --mx-flex-direction: column; --mx-flex-align: normal; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x); --mx-flex-wrap: nowrap;"
>
<ul
class="_visual-list_1mgc1_8"
class="_visual-list_6zpfn_8"
>
<li
class="_visual-list-item_1nc1y_8"
@ -369,7 +371,7 @@ exports[`<ResetIdentityPanel /> should display the 'sync failed' variant correct
exports[`<ResetIdentityPanel /> should reset the encryption when the continue button is clicked 1`] = `
<DocumentFragment>
<nav
class="_breadcrumb_1xygz_8"
class="_breadcrumb_t96w3_8"
>
<button
aria-label="Back"
@ -397,13 +399,13 @@ exports[`<ResetIdentityPanel /> should reset the encryption when the continue bu
</div>
</button>
<ol
class="_pages_1xygz_17"
class="_pages_t96w3_17"
>
<li>
<a
class="_link_1v5rz_8"
class="_link_k9ljz_8"
data-kind="primary"
data-size="small"
data-size="sm"
rel="noreferrer noopener"
role="button"
tabindex="0"
@ -414,7 +416,7 @@ exports[`<ResetIdentityPanel /> should reset the encryption when the continue bu
<li>
<span
aria-current="page"
class="_last-page_1xygz_30"
class="_last-page_t96w3_30"
>
Reset encryption
</span>
@ -428,8 +430,9 @@ exports[`<ResetIdentityPanel /> should reset the encryption when the continue bu
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8 _destructive_1r8kr_34"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="critical"
data-size="lg"
>
<svg
fill="currentColor"
@ -454,7 +457,7 @@ exports[`<ResetIdentityPanel /> should reset the encryption when the continue bu
style="--mx-flex-display: flex; --mx-flex-direction: column; --mx-flex-align: normal; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x); --mx-flex-wrap: nowrap;"
>
<ul
class="_visual-list_1mgc1_8"
class="_visual-list_6zpfn_8"
>
<li
class="_visual-list-item_1nc1y_8"
@ -555,7 +558,7 @@ exports[`<ResetIdentityPanel /> should reset the encryption when the continue bu
exports[`<ResetIdentityPanel /> should reset the encryption when the continue button is clicked 2`] = `
<DocumentFragment>
<nav
class="_breadcrumb_1xygz_8"
class="_breadcrumb_t96w3_8"
>
<button
aria-label="Back"
@ -583,13 +586,13 @@ exports[`<ResetIdentityPanel /> should reset the encryption when the continue bu
</div>
</button>
<ol
class="_pages_1xygz_17"
class="_pages_t96w3_17"
>
<li>
<a
class="_link_1v5rz_8"
class="_link_k9ljz_8"
data-kind="primary"
data-size="small"
data-size="sm"
rel="noreferrer noopener"
role="button"
tabindex="0"
@ -600,7 +603,7 @@ exports[`<ResetIdentityPanel /> should reset the encryption when the continue bu
<li>
<span
aria-current="page"
class="_last-page_1xygz_30"
class="_last-page_t96w3_30"
>
Reset encryption
</span>
@ -614,8 +617,9 @@ exports[`<ResetIdentityPanel /> should reset the encryption when the continue bu
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8 _destructive_1r8kr_34"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="critical"
data-size="lg"
>
<svg
fill="currentColor"
@ -640,7 +644,7 @@ exports[`<ResetIdentityPanel /> should reset the encryption when the continue bu
style="--mx-flex-display: flex; --mx-flex-direction: column; --mx-flex-align: normal; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x); --mx-flex-wrap: nowrap;"
>
<ul
class="_visual-list_1mgc1_8"
class="_visual-list_6zpfn_8"
>
<li
class="_visual-list-item_1nc1y_8"

View File

@ -986,7 +986,7 @@ exports[`<Notifications /> correctly handles the loading/disabled state 1`] = `
/>
</div>
<div
class="_separator_cqpyv_8"
class="_separator_13qwf_8"
data-kind="primary"
data-orientation="horizontal"
role="separator"
@ -2268,7 +2268,7 @@ exports[`<Notifications /> matches the snapshot 1`] = `
</div>
</div>
<div
class="_separator_cqpyv_8"
class="_separator_13qwf_8"
data-kind="primary"
data-orientation="horizontal"
role="separator"
@ -2296,7 +2296,7 @@ exports[`<Notifications /> matches the snapshot 1`] = `
</ul>
</div>
<div
class="_separator_cqpyv_8"
class="_separator_13qwf_8"
data-kind="primary"
data-orientation="horizontal"
role="separator"

View File

@ -17,7 +17,7 @@ exports[`PeopleRoomSettingsTab with requests to join renders requests fully 1`]
>
<span
aria-label="Profile picture"
class="_avatar_zysgz_8 mx_BaseAvatar mx_PeopleRoomSettingsTab_avatar"
class="_avatar_7h2br_8 mx_BaseAvatar mx_PeopleRoomSettingsTab_avatar"
data-color="4"
data-testid="avatar-img"
data-type="round"
@ -26,7 +26,7 @@ exports[`PeopleRoomSettingsTab with requests to join renders requests fully 1`]
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="42px"
loading="lazy"
@ -123,7 +123,7 @@ exports[`PeopleRoomSettingsTab with requests to join renders requests reduced 1`
class="mx_PeopleRoomSettingsTab_knock"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar mx_PeopleRoomSettingsTab_avatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar mx_PeopleRoomSettingsTab_avatar _avatar-imageless_7h2br_55"
data-color="4"
data-testid="avatar-img"
data-type="round"

View File

@ -139,7 +139,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
</form>
</div>
<div
class="_separator_cqpyv_8"
class="_separator_13qwf_8"
data-kind="primary"
data-orientation="horizontal"
role="separator"
@ -229,7 +229,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
class="mx_EventTile_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -323,7 +323,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
class="mx_EventTile_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -420,7 +420,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
class="mx_EventTile_avatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -497,7 +497,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
</form>
</div>
<div
class="_separator_cqpyv_8"
class="_separator_13qwf_8"
data-kind="primary"
data-orientation="horizontal"
role="separator"

View File

@ -232,7 +232,7 @@ exports[`<EncryptionUserSettingsTab /> should display the reset identity panel w
class="mx_SettingsTab_sections"
>
<nav
class="_breadcrumb_1xygz_8"
class="_breadcrumb_t96w3_8"
>
<button
aria-label="Back"
@ -260,13 +260,13 @@ exports[`<EncryptionUserSettingsTab /> should display the reset identity panel w
</div>
</button>
<ol
class="_pages_1xygz_17"
class="_pages_t96w3_17"
>
<li>
<a
class="_link_1v5rz_8"
class="_link_k9ljz_8"
data-kind="primary"
data-size="small"
data-size="sm"
rel="noreferrer noopener"
role="button"
tabindex="0"
@ -277,7 +277,7 @@ exports[`<EncryptionUserSettingsTab /> should display the reset identity panel w
<li>
<span
aria-current="page"
class="_last-page_1xygz_30"
class="_last-page_t96w3_30"
>
Reset encryption
</span>
@ -291,8 +291,9 @@ exports[`<EncryptionUserSettingsTab /> should display the reset identity panel w
class="mx_EncryptionCard_header"
>
<div
class="_content_1r8kr_8 _destructive_1r8kr_34"
data-size="large"
class="_big-icon_1ssbv_8"
data-kind="critical"
data-size="lg"
>
<svg
fill="currentColor"
@ -317,7 +318,7 @@ exports[`<EncryptionUserSettingsTab /> should display the reset identity panel w
style="--mx-flex-display: flex; --mx-flex-direction: column; --mx-flex-align: normal; --mx-flex-justify: start; --mx-flex-gap: var(--cpd-space-3x); --mx-flex-wrap: nowrap;"
>
<ul
class="_visual-list_1mgc1_8"
class="_visual-list_6zpfn_8"
>
<li
class="_visual-list-item_1nc1y_8"

View File

@ -1660,7 +1660,7 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
</form>
</div>
<div
class="_separator_cqpyv_8"
class="_separator_13qwf_8"
data-kind="primary"
data-orientation="horizontal"
role="separator"

View File

@ -27,7 +27,7 @@ exports[`<AddExistingToSpaceDialog /> looks as expected 1`] = `
>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar"
data-color="2"
data-testid="avatar-img"
data-type="square"
@ -35,7 +35,7 @@ exports[`<AddExistingToSpaceDialog /> looks as expected 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="square"
height="40px"
loading="lazy"

View File

@ -21,7 +21,7 @@ exports[`<SpacePanel /> should show all activated MetaSpaces in the correct orde
class="mx_UserMenu_userAvatar"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar mx_UserMenu_userAvatar_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar mx_UserMenu_userAvatar_BaseAvatar _avatar-imageless_7h2br_55"
data-color="5"
data-testid="avatar-img"
data-type="round"

View File

@ -88,7 +88,7 @@ exports[`SpaceItem should render a space with subspaces 1`] = `
>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -96,7 +96,7 @@ exports[`SpaceItem should render a space with subspaces 1`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="32px"
loading="lazy"
@ -177,7 +177,7 @@ exports[`SpaceItem should render a space with subspaces 2`] = `
>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -185,7 +185,7 @@ exports[`SpaceItem should render a space with subspaces 2`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="32px"
loading="lazy"
@ -245,7 +245,7 @@ exports[`SpaceItem should render a space with subspaces 2`] = `
>
<span
aria-label="Avatar"
class="_avatar_zysgz_8 mx_BaseAvatar"
class="_avatar_7h2br_8 mx_BaseAvatar"
data-color="4"
data-testid="avatar-img"
data-type="round"
@ -253,7 +253,7 @@ exports[`SpaceItem should render a space with subspaces 2`] = `
>
<img
alt=""
class="_image_zysgz_43"
class="_image_7h2br_43"
data-type="round"
height="24px"
loading="lazy"

View File

@ -26,7 +26,7 @@ exports[`ThreadsActivityCentre renders notifications matching the snapshot 1`] =
class="mx_ThreadsActivityCentre_rows"
>
<button
class="mx_ThreadsActivityCentreRow _item_lqfwq_8 _interactive_lqfwq_26"
class="mx_ThreadsActivityCentreRow _item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
data-orientation="vertical"
data-radix-collection-item=""
@ -34,10 +34,10 @@ exports[`ThreadsActivityCentre renders notifications matching the snapshot 1`] =
tabindex="-1"
>
<div
class="mx_DecoratedRoomAvatar _icon_lqfwq_50"
class="mx_DecoratedRoomAvatar _icon_bym9p_51"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -48,13 +48,13 @@ exports[`ThreadsActivityCentre renders notifications matching the snapshot 1`] =
</span>
</div>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
This is a real highlight
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -74,7 +74,7 @@ exports[`ThreadsActivityCentre renders notifications matching the snapshot 1`] =
</div>
</button>
<button
class="mx_ThreadsActivityCentreRow _item_lqfwq_8 _interactive_lqfwq_26"
class="mx_ThreadsActivityCentreRow _item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
data-orientation="vertical"
data-radix-collection-item=""
@ -82,10 +82,10 @@ exports[`ThreadsActivityCentre renders notifications matching the snapshot 1`] =
tabindex="-1"
>
<div
class="mx_DecoratedRoomAvatar _icon_lqfwq_50"
class="mx_DecoratedRoomAvatar _icon_bym9p_51"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="2"
data-testid="avatar-img"
data-type="round"
@ -96,13 +96,13 @@ exports[`ThreadsActivityCentre renders notifications matching the snapshot 1`] =
</span>
</div>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
A notification
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -185,7 +185,7 @@ exports[`ThreadsActivityCentre should order the room with the same notification
class="mx_ThreadsActivityCentre_rows"
>
<button
class="mx_ThreadsActivityCentreRow _item_lqfwq_8 _interactive_lqfwq_26"
class="mx_ThreadsActivityCentreRow _item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
data-orientation="vertical"
data-radix-collection-item=""
@ -193,10 +193,10 @@ exports[`ThreadsActivityCentre should order the room with the same notification
tabindex="-1"
>
<div
class="mx_DecoratedRoomAvatar _icon_lqfwq_50"
class="mx_DecoratedRoomAvatar _icon_bym9p_51"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="5"
data-testid="avatar-img"
data-type="round"
@ -207,13 +207,13 @@ exports[`ThreadsActivityCentre should order the room with the same notification
</span>
</div>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
This is a third real highlight
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -233,7 +233,7 @@ exports[`ThreadsActivityCentre should order the room with the same notification
</div>
</button>
<button
class="mx_ThreadsActivityCentreRow _item_lqfwq_8 _interactive_lqfwq_26"
class="mx_ThreadsActivityCentreRow _item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
data-orientation="vertical"
data-radix-collection-item=""
@ -241,10 +241,10 @@ exports[`ThreadsActivityCentre should order the room with the same notification
tabindex="-1"
>
<div
class="mx_DecoratedRoomAvatar _icon_lqfwq_50"
class="mx_DecoratedRoomAvatar _icon_bym9p_51"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="3"
data-testid="avatar-img"
data-type="round"
@ -255,13 +255,13 @@ exports[`ThreadsActivityCentre should order the room with the same notification
</span>
</div>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
This is a real highlight
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"
@ -281,7 +281,7 @@ exports[`ThreadsActivityCentre should order the room with the same notification
</div>
</button>
<button
class="mx_ThreadsActivityCentreRow _item_lqfwq_8 _interactive_lqfwq_26"
class="mx_ThreadsActivityCentreRow _item_bym9p_8 _interactive_bym9p_26"
data-kind="primary"
data-orientation="vertical"
data-radix-collection-item=""
@ -289,10 +289,10 @@ exports[`ThreadsActivityCentre should order the room with the same notification
tabindex="-1"
>
<div
class="mx_DecoratedRoomAvatar _icon_lqfwq_50"
class="mx_DecoratedRoomAvatar _icon_bym9p_51"
>
<span
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="4"
data-testid="avatar-img"
data-type="round"
@ -303,13 +303,13 @@ exports[`ThreadsActivityCentre should order the room with the same notification
</span>
</div>
<span
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_lqfwq_34"
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _label_bym9p_35"
>
This is a second real highlight
</span>
<svg
aria-hidden="true"
class="_nav-hint_lqfwq_59"
class="_nav-hint_bym9p_60"
fill="currentColor"
height="24"
viewBox="8 0 8 24"

View File

@ -48,7 +48,7 @@ exports[`mention pills should pillify @room 1`] = `
>
<span
aria-hidden="true"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="4"
data-testid="avatar-img"
data-type="round"
@ -81,7 +81,7 @@ exports[`mention pills should pillify @room in an intentional mentions world 1`]
>
<span
aria-hidden="true"
class="_avatar_zysgz_8 mx_BaseAvatar _avatar-imageless_zysgz_55"
class="_avatar_7h2br_8 mx_BaseAvatar _avatar-imageless_7h2br_55"
data-color="4"
data-testid="avatar-img"
data-type="round"

File diff suppressed because one or more lines are too long

View File

@ -141,7 +141,7 @@ exports[`showIncompatibleBrowser should match snapshot 1`] = `
</div>
</div>
<div
class="_separator_cqpyv_8"
class="_separator_13qwf_8"
data-kind="primary"
data-orientation="horizontal"
role="separator"

View File

@ -5,13 +5,9 @@ process.env.GITHUB_ACTIONS = "1";
export default {
workspaces: {
"packages/shared-components": {
ignoreDependencies: [
// Used for vitest browser tests
"@playwright/test",
],
},
"packages/shared-components": {},
"packages/playwright-common": {
entry: ["src/fixtures/index.ts", "src/testcontainers/index.ts"],
ignoreDependencies: [
// Used in playwright-screenshots.sh
"wait-on",

View File

@ -27,7 +27,6 @@
"devDependencies": {
"@action-validator/cli": "^0.6.0",
"@action-validator/core": "^0.6.0",
"@element-hq/element-web-playwright-common": "catalog:",
"@nx-tools/nx-container": "^7.2.1",
"@nx/jest": "^22.5.0",
"@playwright/test": "catalog:",

1
packages/playwright-common/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
lib/

View File

@ -12,4 +12,13 @@ RUN npm i -g playwright@${PLAYWRIGHT_VERSION}
COPY docker-entrypoint.sh /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
# We use `docker-init` as PID 1, which means that the container shuts down correctly on SIGTERM.
#
# (The problem is that PID 1 doesn't get default signal handlers, and
# playwright server doesn't register a SIGTERM handler, so if that ends up as
# PID 1, then it ignores SIGTERM. Likewise bash doesn't set a SIGTERM handler by default.
#
# The easiest solution is to use docker-init, which is in fact `tini` (https://github.com/krallin/tini).
#
# See https://github.com/krallin/tini/issues/8#issuecomment-146135930 for a good explanation of all this.)
ENTRYPOINT ["/usr/bin/docker-init", "/docker-entrypoint.sh"]

View File

@ -1,10 +1,16 @@
# @element-hq/element-web-playwright-common
Set of Playwright utilities to make it easier to write tests for Element Web, Element Web Modules & Element Desktop.
Set of Playwright & testcontainers utilities to make it easier to write tests for Element Web, Element Web Modules & Element Desktop.
# This is a partial clone of https://github.com/element-hq/element-modules/tree/main/packages/element-web-playwright-common
The main export includes a number of fixtures and custom assertions as documented in JSDoc.
In the future the rest of the package will be brought into this monorepo, for now it serves as an experimental alternative to https://github.com/element-hq/element-modules/pull/188
The `lib/testcontainers` export contains the following modules:
- `SynapseContainer` - A testcontainer for running a Synapse server
- `MatrixAuthenticationServiceContainer` - A testcontainer for running a Matrix Authentication Service
- `MailpitContainer` - A testcontainer for running a Mailpit SMTP server
There are a number of utils available in the `lib/utils` export.
## Releases

View File

@ -1,4 +1,2 @@
#!/bin/bash
# We use npm here as we used `npm i -g` to install playwright in the Dockerfile
npm exec -- playwright run-server --port "$PORT" --host 0.0.0.0
exec /usr/bin/playwright run-server --port "$PORT" --host 0.0.0.0

View File

@ -1,5 +1,5 @@
{
"name": "@element-hq/element-web-playwright-common-local",
"name": "@element-hq/element-web-playwright-common",
"type": "module",
"version": "3.0.0",
"license": "SEE LICENSE IN README.md",
@ -12,10 +12,34 @@
"engines": {
"node": ">=20.0.0"
},
"main": "lib/index.js",
"types": "lib/index.d.ts",
"bin": {
"playwright-screenshots-experimental": "playwright-screenshots.sh"
"playwright-screenshots": "playwright-screenshots.sh"
},
"scripts": {
"prepack": "nx build:playwright",
"lint:types": "tsc --noEmit"
},
"devDependencies": {
"@element-hq/element-web-module-api": "*",
"@types/lodash-es": "^4.17.12",
"typescript": "^5.8.2",
"wait-on": "^9.0.4"
},
"dependencies": {
"@axe-core/playwright": "^4.10.1",
"@testcontainers/postgresql": "^11.0.0",
"glob": "^13.0.5",
"lodash-es": "^4.17.23",
"mailpit-api": "^1.2.0",
"strip-ansi": "^7.1.0",
"testcontainers": "^11.0.0",
"yaml": "^2.7.0"
},
"peerDependencies": {
"@element-hq/element-web-module-api": "*",
"@playwright/test": "catalog:",
"playwright-core": "catalog:"
}
}

View File

@ -19,8 +19,15 @@ WS_PORT=3000
PW_VERSION=$(pnpm --silent -- playwright --version | awk '{print $2}')
IMAGE_NAME="ghcr.io/element-hq/element-web/playwright-server:$PW_VERSION"
# Pull the image, failing that build the image
docker pull "$IMAGE_NAME" 2>/dev/null || build_image "$IMAGE_NAME"
# If the image exists in the repository, pull it; otherwise, build it.
#
# (This explicit test gives the user clearer progress info than just
# `docker pull 2>/dev/null || build_image`.)
if docker manifest inspect "$IMAGE_NAME" &>/dev/null; then
docker pull "$IMAGE_NAME"
else
build_image "$IMAGE_NAME"
fi
# Start the playwright-server in docker
CONTAINER=$(docker run --network=host -v /tmp:/tmp --rm -d -e PORT="$WS_PORT" "$IMAGE_NAME")

View File

@ -3,6 +3,13 @@
"projectType": "library",
"root": "packages/playwright-common",
"targets": {
"build:playwright": {
"cache": true,
"command": "tsc",
"inputs": ["src"],
"outputs": ["{projectRoot}/lib"],
"options": { "cwd": "packages/playwright-common" }
},
"docker:prebuild": {
"cache": true,
"command": "echo PLAYWRIGHT_VERSION=$(pnpm --silent -- playwright --version | awk '{print $2}') > .env.docker:build",

View File

@ -0,0 +1,12 @@
/*
Copyright 2024-2025 New Vector Ltd.
Copyright 2024 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
declare module "playwright-core/lib/utils" {
// This type is not public in playwright-core utils
export function sanitizeForFilePath(filePath: string): string;
}

View File

@ -0,0 +1,37 @@
/*
Copyright 2024-2025 New Vector Ltd.
Copyright 2023 The Matrix.org Foundation C.I.C.
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 as baseExpect, type ExpectMatcherState, type MatcherReturnType } from "@playwright/test";
import type { AxeBuilder } from "@axe-core/playwright";
export type Expectations = {
/**
* Assert that the given AxeBuilder instance has no violations.
* @param receiver - The AxeBuilder instance to check.
*/
toHaveNoViolations: (this: ExpectMatcherState, receiver: AxeBuilder) => Promise<MatcherReturnType>;
};
export const expect = baseExpect.extend<Expectations>({
async toHaveNoViolations(this: ExpectMatcherState, receiver: AxeBuilder) {
const testInfo = test.info();
if (!testInfo) throw new Error(`toHaveNoViolations() must be called during the test`);
const results = await receiver.analyze();
await testInfo.attach("accessibility-scan-results", {
body: JSON.stringify(results, null, 2),
contentType: "application/json",
});
baseExpect(results.violations).toEqual([]);
return { pass: true, message: (): string => "", name: "toHaveNoViolations" };
},
});

View File

@ -0,0 +1,21 @@
/*
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 { mergeExpects, type Expect } from "@playwright/test";
import {
expect as screenshotExpectations,
type Expectations as ScreenshotExpectations,
type ToMatchScreenshotOptions,
} from "./screenshot.js";
import { expect as axeExpectations, type Expectations as AxeExpectations } from "./axe.js";
export const expect = mergeExpects(screenshotExpectations, axeExpectations) as Expect<
ScreenshotExpectations & AxeExpectations
>;
export type { ToMatchScreenshotOptions };

View File

@ -0,0 +1,79 @@
/*
Copyright 2024-2025 New Vector Ltd.
Copyright 2023 The Matrix.org Foundation C.I.C.
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 as baseExpect,
type ElementHandle,
type ExpectMatcherState,
type Locator,
type Page,
type PageAssertionsToHaveScreenshotOptions,
type MatcherReturnType,
} from "@playwright/test";
import { sanitizeForFilePath } from "playwright-core/lib/utils";
import { extname } from "node:path";
import { ANNOTATION } from "../stale-screenshot-reporter.js";
// Based on https://github.com/microsoft/playwright/blob/2b77ed4d7aafa85a600caa0b0d101b72c8437eeb/packages/playwright/src/util.ts#L206C8-L210C2
function sanitizeFilePathBeforeExtension(filePath: string): string {
const ext = extname(filePath);
const base = filePath.substring(0, filePath.length - ext.length);
return sanitizeForFilePath(base) + ext;
}
export interface ToMatchScreenshotOptions extends PageAssertionsToHaveScreenshotOptions {
css?: string;
}
export type Expectations = {
toMatchScreenshot: (
this: ExpectMatcherState,
receiver: Page | Locator,
name: `${string}.png`,
options?: ToMatchScreenshotOptions,
) => Promise<MatcherReturnType>;
};
/**
* Provides an upgrade to the `toHaveScreenshot` expectation.
* Unfortunately, we can't just extend the existing `toHaveScreenshot` expectation
*/
export const expect = baseExpect.extend<Expectations>({
async toMatchScreenshot(receiver, name, options) {
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 style: ElementHandle<Element> | undefined;
if (options?.css) {
// We add a custom style tag before taking screenshots
style = (await page.addStyleTag({
content: options.css,
})) as ElementHandle<Element>;
}
const screenshotName = sanitizeFilePathBeforeExtension(name);
await baseExpect(receiver).toHaveScreenshot(screenshotName, options);
await style?.evaluate((tag) => tag.remove());
testInfo.annotations.push({
type: ANNOTATION,
description: testInfo.snapshotPath(screenshotName),
});
return { pass: true, message: (): string => "", name: "toMatchScreenshot" };
},
});

Some files were not shown because too many files have changed in this diff Show More