Merge branch 'develop' of https://github.com/vector-im/element-web into t3chguy/dedup-icons-17oct
# Conflicts: # .editorconfig # .eslintignore # .git-blame-ignore-revs # .github/PULL_REQUEST_TEMPLATE.md # .github/labels.yml # .github/release-drafter.yml # .github/workflows/backport.yml # .github/workflows/release-gitflow.yml # .github/workflows/release.yml # .github/workflows/static_analysis.yaml # .gitignore # .lintstagedrc # .npmignore # .prettierignore # CHANGELOG.md # CONTRIBUTING.md # LICENSE-AGPL-3.0 # README.md # babel.config.js # docs/SUMMARY.md # docs/jitsi.md # jest.config.ts # localazy.json # package.json # playwright/snapshots/forgot-password/forgot-password.spec.ts/forgot-password-linux.png # playwright/snapshots/spaces/spaces.spec.ts/space-panel-collapsed-linux.png # release_config.yaml # res/css/structures/_RoomSearch.pcss # res/fonts/Open_Sans/LICENSE.txt # res/jitsi_external_api.min.js.LICENSE.txt # sonar-project.properties # src/@types/global.d.ts # src/async-components/views/dialogs/security/CreateSecretStorageDialog.tsx # src/components/structures/AutocompleteInput.tsx # src/components/structures/ErrorMessage.tsx # src/components/structures/auth/ForgotPassword.tsx # src/components/structures/auth/forgot-password/EnterEmail.tsx # src/components/views/elements/AppPermission.tsx # src/components/views/elements/AppTile.tsx # src/components/views/messages/DecryptionFailureBody.tsx # src/components/views/messages/MessageActionBar.tsx # src/components/views/rooms/EntityTile.tsx # src/components/views/spaces/QuickSettingsButton.tsx # src/voice-broadcast/components/atoms/VoiceBroadcastError.tsx # src/voice-broadcast/components/atoms/VoiceBroadcastRecordingConnectionError.tsx # tsconfig.json # yarn.lock
@@ -1,7 +1,6 @@
|
||||
FROM mcr.microsoft.com/playwright:v1.46.1-jammy
|
||||
FROM mcr.microsoft.com/playwright:v1.48.0-jammy
|
||||
|
||||
WORKDIR /work/matrix-react-sdk
|
||||
VOLUME ["/work/element-web/node_modules"]
|
||||
WORKDIR /work
|
||||
|
||||
# fonts-dejavu is needed for the same RTL rendering as on CI
|
||||
RUN apt-get update && apt-get -y install docker.io fonts-dejavu
|
||||
|
||||
@@ -2,7 +2,4 @@
|
||||
|
||||
set -e
|
||||
|
||||
yarn link
|
||||
yarn --cwd ../element-web install
|
||||
yarn --cwd ../element-web link matrix-react-sdk
|
||||
npx playwright test --update-snapshots --reporter line $@
|
||||
|
||||
@@ -226,7 +226,7 @@ test.describe("Cryptography", function () {
|
||||
// Assert that verified icon is rendered
|
||||
await page.getByTestId("base-card-back-button").click();
|
||||
await page.getByLabel("Room info").nth(1).click();
|
||||
await expect(page.locator('.mx_RoomSummaryCard_badges [data-kind="success"]')).toContainText("Encrypted");
|
||||
await expect(page.locator('.mx_RoomSummaryCard_badges [data-kind="green"]')).toContainText("Encrypted");
|
||||
|
||||
// Take a snapshot of RoomSummaryCard with a verified E2EE icon
|
||||
await expect(page.locator(".mx_RightPanel")).toMatchScreenshot("RoomSummaryCard-with-verified-e2ee.png");
|
||||
|
||||
@@ -70,7 +70,9 @@ test.describe("Cryptography", function () {
|
||||
const lastE2eIcon = last.locator(".mx_EventTile_e2eIcon");
|
||||
await expect(lastE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_decryption_failure/);
|
||||
await lastE2eIcon.focus();
|
||||
await expect(page.getByRole("tooltip")).toContainText("This message could not be decrypted");
|
||||
await expect(await app.getTooltipForElement(lastE2eIcon)).toContainText(
|
||||
"This message could not be decrypted",
|
||||
);
|
||||
|
||||
/* Should show a red padlock for an unencrypted message in an e2e room */
|
||||
await bob.evaluate(
|
||||
@@ -90,7 +92,7 @@ test.describe("Cryptography", function () {
|
||||
await expect(last).toContainText("test unencrypted");
|
||||
await expect(lastE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_warning/);
|
||||
await lastE2eIcon.focus();
|
||||
await expect(page.getByRole("tooltip")).toContainText("Not encrypted");
|
||||
await expect(await app.getTooltipForElement(lastE2eIcon)).toContainText("Not encrypted");
|
||||
|
||||
/* Should show no padlock for an unverified user */
|
||||
// bob sends a valid event
|
||||
@@ -123,7 +125,9 @@ test.describe("Cryptography", function () {
|
||||
await expect(lastTile).toContainText("test encrypted from unverified");
|
||||
await expect(lastTileE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_warning/);
|
||||
await lastTileE2eIcon.focus();
|
||||
await expect(page.getByRole("tooltip")).toContainText("Encrypted by a device not verified by its owner.");
|
||||
await expect(await app.getTooltipForElement(lastTileE2eIcon)).toContainText(
|
||||
"Encrypted by a device not verified by its owner.",
|
||||
);
|
||||
|
||||
/* In legacy crypto: should show a grey padlock for a message from a deleted device.
|
||||
* In rust crypto: should show a red padlock for a message from an unverified device.
|
||||
@@ -159,7 +163,7 @@ test.describe("Cryptography", function () {
|
||||
await expect(last).toContainText("test encrypted from unverified");
|
||||
await expect(lastE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_warning/);
|
||||
await lastE2eIcon.focus();
|
||||
await expect(page.getByRole("tooltip")).toContainText(
|
||||
await expect(await app.getTooltipForElement(lastE2eIcon)).toContainText(
|
||||
workerInfo.project.name === "Legacy Crypto"
|
||||
? "Encrypted by an unknown or deleted device."
|
||||
: "Encrypted by a device not verified by its owner.",
|
||||
@@ -212,7 +216,7 @@ test.describe("Cryptography", function () {
|
||||
// The key is coming from backup, so it is not anymore possible to establish if the claimed device
|
||||
// creator of this key is authentic. The tooltip should be "The authenticity of this encrypted message can't be guaranteed on this device."
|
||||
// It is not "Encrypted by an unknown or deleted device." even if the claimed device is actually deleted.
|
||||
await expect(page.getByRole("tooltip")).toContainText(
|
||||
await expect(await app.getTooltipForElement(lastTileE2eIcon)).toContainText(
|
||||
"The authenticity of this encrypted message can't be guaranteed on this device.",
|
||||
);
|
||||
});
|
||||
@@ -296,7 +300,9 @@ test.describe("Cryptography", function () {
|
||||
const lastE2eIcon = last.locator(".mx_EventTile_e2eIcon");
|
||||
await expect(lastE2eIcon).toHaveClass(/mx_EventTile_e2eIcon_warning/);
|
||||
await lastE2eIcon.focus();
|
||||
await expect(page.getByRole("tooltip")).toContainText("Encrypted by a device not verified by its owner.");
|
||||
await expect(await app.getTooltipForElement(lastE2eIcon)).toContainText(
|
||||
"Encrypted by a device not verified by its owner.",
|
||||
);
|
||||
|
||||
const penultimate = page.locator(".mx_EventTile").filter({ hasText: "test encrypted from verified" });
|
||||
await expect(penultimate.locator(".mx_EventTile_e2eIcon")).not.toBeVisible();
|
||||
|
||||
@@ -8,8 +8,9 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import { expect, JSHandle, type Page } from "@playwright/test";
|
||||
|
||||
import type { CryptoEvent, ICreateRoomOpts, MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import type { ICreateRoomOpts, MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import type {
|
||||
CryptoEvent,
|
||||
EmojiMapping,
|
||||
ShowSasCallbacks,
|
||||
VerificationRequest,
|
||||
|
||||
@@ -32,7 +32,7 @@ test.describe("Soft logout", () => {
|
||||
|
||||
// back to the welcome page
|
||||
await expect(page).toHaveURL(/\/#\/home/);
|
||||
await expect(page.getByRole("heading", { name: "Welcome Alice", exact: true })).toBeVisible();
|
||||
await expect(page.getByRole("heading", { name: `Welcome ${user.userId}`, exact: true })).toBeVisible();
|
||||
});
|
||||
|
||||
test("still shows the soft-logout page when the page is reloaded after a soft-logout", async ({
|
||||
|
||||
@@ -84,7 +84,7 @@ test.describe("FilePanel", () => {
|
||||
await expect(filePanelMessageList.locator(".mx_EventTile")).toHaveCount(3);
|
||||
|
||||
// Assert that the download links are rendered
|
||||
await expect(filePanelMessageList.locator(".mx_MFileBody_download")).toHaveCount(3);
|
||||
await expect(filePanelMessageList.locator(".mx_MFileBody_download,.mx_MFileBody_info")).toHaveCount(3);
|
||||
|
||||
// Assert that the sender of the files is rendered on all of the tiles
|
||||
await expect(filePanelMessageList.getByText(NAME)).toHaveCount(3);
|
||||
@@ -176,8 +176,7 @@ test.describe("FilePanel", () => {
|
||||
// Assert that the file size is displayed in kibibytes, not kilobytes (1000 bytes)
|
||||
// See: https://github.com/vector-im/element-web/issues/24866
|
||||
await expect(tile.locator(".mx_MFileBody_info_filename", { hasText: size })).toBeVisible();
|
||||
await expect(tile.locator(".mx_MFileBody_download a", { hasText: size })).toBeVisible();
|
||||
await expect(tile.locator(".mx_MFileBody_download .mx_MImageBody_size", { hasText: size })).toBeVisible();
|
||||
await expect(tile.locator(".mx_MFileBody_info", { hasText: size })).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -224,7 +224,7 @@ export const test = base.extend<{
|
||||
},
|
||||
|
||||
axe: async ({ page }, use) => {
|
||||
await use(new AxeBuilder({ page }));
|
||||
await use(new AxeBuilder({ page }).exclude("[id^='floating-ui-']"));
|
||||
},
|
||||
checkA11y: async ({ axe }, use, testInfo) =>
|
||||
use(async () => {
|
||||
|
||||
@@ -172,4 +172,22 @@ export class ElementAppPage {
|
||||
await this.page.getByRole("button", { name: "Room info" }).first().click();
|
||||
return this.page.locator(".mx_RightPanel");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a locator for the tooltip associated with an element
|
||||
* @param e The element with the tooltip
|
||||
* @returns Locator to the tooltip
|
||||
*/
|
||||
public async getTooltipForElement(e: Locator): Promise<Locator> {
|
||||
const [labelledById, describedById] = await Promise.all([
|
||||
e.getAttribute("aria-labelledby"),
|
||||
e.getAttribute("aria-describedby"),
|
||||
]);
|
||||
if (!labelledById && !describedById) {
|
||||
throw new Error(
|
||||
"Element has no aria-labelledby or aria-describedy attributes! The tooltip should have added either one of these.",
|
||||
);
|
||||
}
|
||||
return this.page.locator(`#${labelledById ?? describedById}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import { randB64Bytes } from "../../utils/rand";
|
||||
// Docker tag to use for synapse docker image.
|
||||
// We target a specific digest as every now and then a Synapse update will break our CI.
|
||||
// This digest is updated by the playwright-image-updates.yaml workflow periodically.
|
||||
const DOCKER_TAG = "develop@sha256:117a94ee66e4049eb6f40d04cc70d4fc83f7022dacc9871448c141e7756492f9";
|
||||
const DOCKER_TAG = "develop@sha256:fd6ba2d8471a0807e1bccef4124b22d17f0058f2cf9285066fdd94d8c631964a";
|
||||
|
||||
async function cfgDirFromTemplate(opts: StartHomeserverOpts): Promise<Omit<HomeserverConfig, "dockerUrl">> {
|
||||
const templateDir = path.join(__dirname, "templates", opts.template);
|
||||
|
||||
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 198 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 13 KiB |