Skip to content

Commit

Permalink
Merge branch 'develop' into midhun/memberlist-redesign
Browse files Browse the repository at this point in the history
  • Loading branch information
MidhunSureshR authored Jan 8, 2025
2 parents 37a6d09 + b6aba14 commit 8e8a5cb
Show file tree
Hide file tree
Showing 46 changed files with 1,443 additions and 1,177 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
/src/i18n/strings
/src/i18n/strings/en_EN.json @element-hq/element-web-reviewers
# Ignore the synapse plugin as this is updated by GHA for docker image updating
/playwright/plugins/homeserver/synapse/index.ts
/playwright/testcontainers/synapse.ts

3 changes: 3 additions & 0 deletions .github/labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@
- name: "X-Upcoming-Release-Blocker"
description: "This does not affect the current release cycle but will affect the next one"
color: "e99695"
- name: "X-Run-All-Tests"
description: "When applied to PRs, it'll run the full gamut of end-to-end tests on the PR"
color: "ff7979"
- name: "Z-Actions"
color: "ededed"
- name: "Z-Cache-Confusion"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/dockerhub.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3

- name: Set up QEMU
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3
uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3
Expand All @@ -51,7 +51,7 @@ jobs:
- name: Build and push
id: build-and-push
uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6
uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6
with:
context: .
push: true
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/end-to-end-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,13 @@ jobs:
- Chrome
- Firefox
- WebKit
isCron:
- ${{ github.event_name == 'schedule' }}
# Skip the Firefox & Safari runs unless this was a cron trigger
runAllTests:
- ${{ github.event_name == 'schedule' || contains(github.event.pull_request.labels.*.name, 'X-Run-All-Tests') }}
# Skip the Firefox & Safari runs unless this was a cron trigger or PR has X-Run-All-Tests label
exclude:
- isCron: false
- runAllTests: false
project: Firefox
- isCron: false
- runAllTests: false
project: WebKit
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -170,7 +170,7 @@ jobs:
yarn playwright test \
--shard "${{ matrix.runner }}/${{ needs.build.outputs.num-runners }}" \
--project="${{ matrix.project }}" \
${{ github.event_name == 'pull_request' && '--grep-invert @mergequeue' || '' }}
${{ (github.event_name == 'pull_request' && matrix.runAllTests == false ) && '--grep-invert @mergequeue' || '' }}
- name: Upload blob report to GitHub Actions Artifacts
if: always()
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/playwright-image-updates.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
docker pull "$IMAGE"
INSPECT=$(docker inspect --format='{{index .RepoDigests 0}}' "$IMAGE")
DIGEST=${INSPECT#*@}
sed -i "s/const DOCKER_TAG.*/const DOCKER_TAG = \"develop@$DIGEST\";/" playwright/plugins/homeserver/synapse/index.ts
sed -i "s/const TAG.*/const TAG = \"develop@$DIGEST\";/" playwright/testcontainers/synapse.ts
env:
IMAGE: ghcr.io/element-hq/synapse:develop

Expand Down
2 changes: 2 additions & 0 deletions docs/playwright.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ has to be disabled in Playwright on Firefox & Webkit to retain routing functiona
Anything testing VoIP/microphone will need to have `@no-webkit` as fake microphone functionality is not available
there at this time.

If you wish to run all tests in a PR, you can give it the label `X-Run-All-Tests`.

## Supporter container runtimes

We use testcontainers to spin up various instances of Synapse, Matrix Authentication Service, and more.
Expand Down
91 changes: 91 additions & 0 deletions playwright/e2e/crypto/backups-mas.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
Copyright 2024 New Vector Ltd.
Copyright 2023 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/

import { test, expect } from "../../element-web-test";
import { registerAccountMas } from "../oidc";
import { isDendrite } from "../../plugins/homeserver/dendrite";
import { TestClientServerAPI } from "../csAPI";
import { masHomeserver } from "../../plugins/homeserver/synapse/masHomeserver.ts";

// These tests register an account with MAS because then we go through the "normal" registration flow
// and crypto gets set up. Using the 'user' fixture create a a user an synthesizes an existing login,
// which is faster but leaves us without crypto set up.
test.use(masHomeserver);
test.describe("Encryption state after registration", () => {
test.skip(isDendrite, "does not yet support MAS");

test("Key backup is enabled by default", async ({ page, mailhogClient, app }) => {
await page.goto("/#/login");
await page.getByRole("button", { name: "Continue" }).click();
await registerAccountMas(page, mailhogClient, "alice", "alice@email.com", "Pa$sW0rD!");

await app.settings.openUserSettings("Security & Privacy");
await expect(page.getByText("This session is backing up your keys.")).toBeVisible();
});

test("user is prompted to set up recovery", async ({ page, mailhogClient, app }) => {
await page.goto("/#/login");
await page.getByRole("button", { name: "Continue" }).click();
await registerAccountMas(page, mailhogClient, "alice", "alice@email.com", "Pa$sW0rD!");

await page.getByRole("button", { name: "Add room" }).click();
await page.getByRole("menuitem", { name: "New room" }).click();
await page.getByRole("textbox", { name: "Name" }).fill("test room");
await page.getByRole("button", { name: "Create room" }).click();

await expect(page.getByRole("heading", { name: "Set up recovery" })).toBeVisible();
});
});

test.describe("Key backup reset from elsewhere", () => {
test.skip(isDendrite, "does not yet support MAS");

test("Key backup is disabled when reset from elsewhere", async ({ page, mailhogClient, request, homeserver }) => {
const testUsername = "alice";
const testPassword = "Pa$sW0rD!";

// there's a delay before keys are uploaded so the error doesn't appear immediately: use a fake
// clock so we can skip the delay
await page.clock.install();

await page.goto("/#/login");
await page.getByRole("button", { name: "Continue" }).click();
await registerAccountMas(page, mailhogClient, testUsername, "alice@email.com", testPassword);

await page.getByRole("button", { name: "Add room" }).click();
await page.getByRole("menuitem", { name: "New room" }).click();
await page.getByRole("textbox", { name: "Name" }).fill("test room");
await page.getByRole("button", { name: "Create room" }).click();

// @ts-ignore - this runs in the browser scope where mxMatrixClientPeg is a thing. Here, it is not.
const accessToken = await page.evaluate(() => mxMatrixClientPeg.get().getAccessToken());

const csAPI = new TestClientServerAPI(request, homeserver, accessToken);

const backupInfo = await csAPI.getCurrentBackupInfo();

await csAPI.deleteBackupVersion(backupInfo.version);

await page.getByRole("textbox", { name: "Send an encrypted message…" }).fill("/discardsession");
await page.getByRole("button", { name: "Send message" }).click();

await page.getByRole("textbox", { name: "Send an encrypted message…" }).fill("Message with broken key backup");
await page.getByRole("button", { name: "Send message" }).click();

// Should be the message we sent plus the room creation event
await expect(page.locator(".mx_EventTile")).toHaveCount(2);
await expect(
page.locator(".mx_RoomView_MessageList > .mx_EventTile_last .mx_EventTile_receiptSent"),
).toBeVisible();

// Wait for it to try uploading the key
await page.clock.fastForward(20000);

await expect(page.getByRole("heading", { level: 1, name: "New Recovery Method" })).toBeVisible();
});
});
83 changes: 0 additions & 83 deletions playwright/e2e/crypto/backups.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ Please see LICENSE files in the repository root for full details.
import { type Page } from "@playwright/test";

import { test, expect } from "../../element-web-test";
import { registerAccountMas } from "../oidc";
import { isDendrite } from "../../plugins/homeserver/dendrite";
import { TestClientServerAPI } from "../csAPI";
import { masHomeserver } from "../../plugins/homeserver/synapse/masHomeserver.ts";

async function expectBackupVersionToBe(page: Page, version: string) {
await expect(page.locator(".mx_SecureBackupPanel_statusList tr:nth-child(5) td")).toHaveText(
Expand All @@ -22,85 +18,6 @@ async function expectBackupVersionToBe(page: Page, version: string) {
await expect(page.locator(".mx_SecureBackupPanel_statusList tr:nth-child(6) td")).toHaveText(version);
}

// These tests register an account with MAS because then we go through the "normal" registration flow
// and crypto gets set up. Using the 'user' fixture create a a user an synthesizes an existing login,
// which is faster but leaves us without crypto set up.
test.describe("Encryption state after registration", () => {
test.use(masHomeserver);
test.skip(isDendrite, "does not yet support MAS");

test("Key backup is enabled by default", async ({ page, mailhogClient, app }) => {
await page.goto("/#/login");
await page.getByRole("button", { name: "Continue" }).click();
await registerAccountMas(page, mailhogClient, "alice", "alice@email.com", "Pa$sW0rD!");

await app.settings.openUserSettings("Security & Privacy");
await expect(page.getByText("This session is backing up your keys.")).toBeVisible();
});

test("user is prompted to set up recovery", async ({ page, mailhogClient, app }) => {
await page.goto("/#/login");
await page.getByRole("button", { name: "Continue" }).click();
await registerAccountMas(page, mailhogClient, "alice", "alice@email.com", "Pa$sW0rD!");

await page.getByRole("button", { name: "Add room" }).click();
await page.getByRole("menuitem", { name: "New room" }).click();
await page.getByRole("textbox", { name: "Name" }).fill("test room");
await page.getByRole("button", { name: "Create room" }).click();

await expect(page.getByRole("heading", { name: "Set up recovery" })).toBeVisible();
});
});

test.describe("Key backup reset from elsewhere", () => {
test.use(masHomeserver);
test.skip(isDendrite, "does not yet support MAS");

test("Key backup is disabled when reset from elsewhere", async ({ page, mailhogClient, request, homeserver }) => {
const testUsername = "alice";
const testPassword = "Pa$sW0rD!";

// there's a delay before keys are uploaded so the error doesn't appear immediately: use a fake
// clock so we can skip the delay
await page.clock.install();

await page.goto("/#/login");
await page.getByRole("button", { name: "Continue" }).click();
await registerAccountMas(page, mailhogClient, testUsername, "alice@email.com", testPassword);

await page.getByRole("button", { name: "Add room" }).click();
await page.getByRole("menuitem", { name: "New room" }).click();
await page.getByRole("textbox", { name: "Name" }).fill("test room");
await page.getByRole("button", { name: "Create room" }).click();

// @ts-ignore - this runs in the browser scope where mxMatrixClientPeg is a thing. Here, it is not.
const accessToken = await page.evaluate(() => mxMatrixClientPeg.get().getAccessToken());

const csAPI = new TestClientServerAPI(request, homeserver, accessToken);

const backupInfo = await csAPI.getCurrentBackupInfo();

await csAPI.deleteBackupVersion(backupInfo.version);

await page.getByRole("textbox", { name: "Send an encrypted message…" }).fill("/discardsession");
await page.getByRole("button", { name: "Send message" }).click();

await page.getByRole("textbox", { name: "Send an encrypted message…" }).fill("Message with broken key backup");
await page.getByRole("button", { name: "Send message" }).click();

// Should be the message we sent plus the room creation event
await expect(page.locator(".mx_EventTile")).toHaveCount(2);
await expect(
page.locator(".mx_RoomView_MessageList > .mx_EventTile_last .mx_EventTile_receiptSent"),
).toBeVisible();

// Wait for it to try uploading the key
await page.clock.fastForward(20000);

await expect(page.getByRole("heading", { level: 1, name: "New Recovery Method" })).toBeVisible();
});
});

test.describe("Backups", () => {
test.use({
displayName: "Hanako",
Expand Down
44 changes: 22 additions & 22 deletions playwright/e2e/crypto/dehydration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,30 @@ function getMemberTileByName(page: Page, name: string): Locator {
return page.locator(`.mx_MemberTileView, [title="${name}"]`);
}

test.describe("Dehydration", () => {
test.skip(isDendrite, "does not yet support dehydration v2");

test.use({
displayName: NAME,
synapseConfigOptions: {
experimental_features: {
msc2697_enabled: false,
msc3814_enabled: true,
},
test.use({
displayName: NAME,
synapseConfigOptions: {
experimental_features: {
msc2697_enabled: false,
msc3814_enabled: true,
},
config: async ({ config, context }, use) => {
const wellKnown = {
...config.default_server_config,
"org.matrix.msc3814": true,
};

await context.route("https://localhost/.well-known/matrix/client", async (route) => {
await route.fulfill({ json: wellKnown });
});
},
config: async ({ config, context }, use) => {
const wellKnown = {
...config.default_server_config,
"org.matrix.msc3814": true,
};

await context.route("https://localhost/.well-known/matrix/client", async (route) => {
await route.fulfill({ json: wellKnown });
});

await use(config);
},
});

await use(config);
},
});
test.describe("Dehydration", () => {
test.skip(isDendrite, "does not yet support dehydration v2");

test("Create dehydrated device", async ({ page, user, app }, workerInfo) => {
// Create a backup (which will create SSSS, and dehydrated device)
Expand Down
25 changes: 13 additions & 12 deletions playwright/e2e/forgot-password/forgot-password.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,21 @@ const username = "user1234";
const password = "oETo7MPf0o";
const email = "user@nowhere.dummy";

test.describe("Forgot Password", () => {
test.skip(isDendrite, "not yet wired up");
test.use(emailHomeserver);
test.use({
config: {
// The only thing that we really *need* (otherwise Element refuses to load) is a default homeserver.
// We point that to a guaranteed-invalid domain.
default_server_config: {
"m.homeserver": {
base_url: "https://server.invalid",
},
test.use(emailHomeserver);
test.use({
config: {
// The only thing that we really *need* (otherwise Element refuses to load) is a default homeserver.
// We point that to a guaranteed-invalid domain.
default_server_config: {
"m.homeserver": {
base_url: "https://server.invalid",
},
},
});
},
});

test.describe("Forgot Password", () => {
test.skip(isDendrite, "not yet wired up");

test("renders properly", { tag: "@screenshot" }, async ({ page, homeserver }) => {
await page.goto("/");
Expand Down
10 changes: 5 additions & 5 deletions playwright/e2e/login/consent.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ Please see LICENSE files in the repository root for full details.
import { test, expect } from "../../element-web-test";
import { consentHomeserver } from "../../plugins/homeserver/synapse/consentHomeserver.ts";

test.describe("Consent", () => {
test.use(consentHomeserver);
test.use({
displayName: "Bob",
});
test.use(consentHomeserver);
test.use({
displayName: "Bob",
});

test.describe("Consent", () => {
test("should prompt the user to consent to terms when server deems it necessary", async ({
context,
page,
Expand Down
Loading

0 comments on commit 8e8a5cb

Please sign in to comment.