Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Merge branch 'develop' into florianduros/fix/high-contrast-theme
Browse files Browse the repository at this point in the history
  • Loading branch information
florianduros authored Jun 21, 2024
2 parents 43f8105 + 87bdc78 commit 69e45f9
Show file tree
Hide file tree
Showing 46 changed files with 642 additions and 424 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/pull_request_base_branch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Pull Request Base Branch
on:
pull_request:
types: [opened, edited, synchronize]
jobs:
check_base_branch:
name: Check PR base branch
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v3
with:
script: |
const baseBranch = context.payload.pull_request.base.ref;
if (!['develop', 'staging'].includes(baseBranch) && !baseBranch.startsWith('feat/')) {
core.setFailed(`Invalid base branch: ${baseBranch}`);
}
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@
"@types/react": "17.0.80",
"@types/seedrandom": "3.0.8",
"oidc-client-ts": "3.0.1",
"jwt-decode": "4.0.0"
"jwt-decode": "4.0.0",
"@floating-ui/react": "0.26.11"
},
"dependencies": {
"@babel/runtime": "^7.12.5",
Expand All @@ -77,7 +78,7 @@
"@sentry/browser": "^8.0.0",
"@testing-library/react-hooks": "^8.0.1",
"@vector-im/compound-design-tokens": "^1.2.0",
"@vector-im/compound-web": "^4.6.0",
"@vector-im/compound-web": "^4.8.0",
"@zxcvbn-ts/core": "^3.0.4",
"@zxcvbn-ts/language-common": "^3.0.4",
"@zxcvbn-ts/language-en": "^3.0.2",
Expand Down
45 changes: 45 additions & 0 deletions playwright/e2e/app-loading/guest-registration.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
Copyright 2024 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.
*/

/*
* Tests for application startup with guest registration enabled on the server.
*/

import { expect, test } from "../../element-web-test";

test.use({
startHomeserverOpts: "guest-enabled",
config: async ({ homeserver }, use) => {
await use({
default_server_config: {
"m.homeserver": { base_url: homeserver.config.baseUrl },
},
});
},
});

test("Shows the welcome page by default", async ({ page }) => {
await page.goto("/");
await expect(page.getByRole("heading", { name: "Welcome to Element!" })).toBeVisible();
await expect(page.getByRole("link", { name: "Sign in" })).toBeVisible();
});

test("Room link correctly loads a room view", async ({ page }) => {
await page.goto("/#/room/!room:id");
await page.waitForSelector(".mx_MatrixChat", { timeout: 30000 });
await expect(page).toHaveURL(/\/#\/room\/!room:id$/);
await expect(page.getByRole("heading", { name: "Join the conversation with an account" })).toBeVisible();
});
68 changes: 68 additions & 0 deletions playwright/e2e/app-loading/stored-credentials.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
Copyright 2024 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 { expect, test } from "../../element-web-test";
import { ElementAppPage } from "../../pages/ElementAppPage";

/*
* Tests for application startup with credentials stored in localstorage.
*/

test.use({ displayName: "Boris" });

test("Shows the homepage by default", async ({ pageWithCredentials: page }) => {
await page.goto("/");
await page.waitForSelector(".mx_MatrixChat", { timeout: 30000 });

await expect(page).toHaveURL(/\/#\/home/);
await expect(page.getByRole("heading", { name: "Welcome Boris", exact: true })).toBeVisible();
});

test("Shows the last known page on reload", async ({ pageWithCredentials: page }) => {
await page.goto("/");
await page.waitForSelector(".mx_MatrixChat", { timeout: 30000 });

const app = new ElementAppPage(page);
await app.client.createRoom({ name: "Test Room" });
await app.viewRoomByName("Test Room");

// Navigate away
await page.goto("about:blank");

// And back again
await page.goto("/");
await page.waitForSelector(".mx_MatrixChat", { timeout: 30000 });

// Check that the room reloaded
await expect(page).toHaveURL(/\/#\/room\//);
await expect(page.locator(".mx_LegacyRoomHeader")).toContainText("Test Room");
});

test("Room link correctly loads a room view", async ({ pageWithCredentials: page }) => {
await page.goto("/#/room/!room:id");
await page.waitForSelector(".mx_MatrixChat", { timeout: 30000 });

await expect(page).toHaveURL(/\/#\/room\/!room:id$/);
await expect(page.getByRole("button", { name: "Join the discussion" })).toBeVisible();
});

test("Login link redirects to home page", async ({ pageWithCredentials: page }) => {
await page.goto("/#/login");
await page.waitForSelector(".mx_MatrixChat", { timeout: 30000 });

await expect(page).toHaveURL(/\/#\/home/);
await expect(page.getByRole("heading", { name: "Welcome Boris", exact: true })).toBeVisible();
});
10 changes: 10 additions & 0 deletions playwright/e2e/crypto/crypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ test.describe("Cryptography", function () {
homeserver,
user: aliceCredentials,
}) => {
test.slow();
const securityKey = await enableKeyBackup(app);

// bob sends a valid event
Expand All @@ -468,6 +469,15 @@ test.describe("Cryptography", function () {

/* log out, and back in */
await logOutOfElement(page);
// Reload to work around a Rust crypto bug where it can hold onto the indexeddb even after logout
// https://github.com/element-hq/element-web/issues/25779
await page.addInitScript(() => {
// When we reload, the initScript created by the `user`/`pageWithCredentials` fixtures
// will re-inject the original credentials into localStorage, which we don't want.
// To work around, we add a second initScript which will clear localStorage again.
window.localStorage.clear();
});
await page.reload();
await logIntoElement(page, homeserver, aliceCredentials, securityKey);

/* go back to the test room and find Bob's message again */
Expand Down
4 changes: 0 additions & 4 deletions playwright/e2e/crypto/verification.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ test.describe("Device verification", () => {
// Visit the login page of the app, to load the matrix sdk
await page.goto("/#/login");

await page.pause();

// wait for the page to load
await page.waitForSelector(".mx_AuthPage", { timeout: 30000 });

Expand All @@ -54,8 +52,6 @@ test.describe("Device verification", () => {
aliceBotClient.setCredentials(credentials);
const mxClientHandle = await aliceBotClient.prepareClient();

await page.waitForTimeout(20000);

expectedBackupVersion = await mxClientHandle.evaluate(async (mxClient) => {
return await mxClient.getCrypto()!.getActiveSessionBackupVersion();
});
Expand Down
62 changes: 41 additions & 21 deletions playwright/e2e/login/login.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,38 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import { test, expect } from "../../element-web-test";
import { Page } from "@playwright/test";

import { expect, test } from "../../element-web-test";
import { doTokenRegistration } from "./utils";
import { isDendrite } from "../../plugins/homeserver/dendrite";

test.describe("Login", () => {
test.describe("m.login.password", () => {
test.describe("Password login", () => {
test.use({ startHomeserverOpts: "consent" });

const username = "user1234";
const password = "p4s5W0rD";

test.beforeEach(async ({ page, homeserver }) => {
test.beforeEach(async ({ homeserver }) => {
await homeserver.registerUser(username, password);
await page.goto("/#/login");
});

test("logs in with an existing account and lands on the home screen", async ({
test("Loads the welcome page by default; then logs in with an existing account and lands on the home screen", async ({
page,
homeserver,
checkA11y,
}) => {
// first pick the homeserver, as otherwise the user picker won't be visible
await page.getByRole("button", { name: "Edit" }).click();
await page.getByRole("textbox", { name: "Other homeserver" }).fill(homeserver.config.baseUrl);
await page.getByRole("button", { name: "Continue", exact: true }).click();
// wait for the dialog to go away
await expect(page.locator(".mx_ServerPickerDialog")).toHaveCount(0);
await page.goto("/");

await expect(page.locator(".mx_Spinner")).toHaveCount(0);
await expect(page.locator(".mx_ServerPicker_server")).toHaveText(homeserver.config.baseUrl);
// Should give us the welcome page initially
await expect(page.getByRole("heading", { name: "Welcome to Element!" })).toBeVisible();

// Start the login process
await page.getByRole("link", { name: "Sign in" }).click();

// first pick the homeserver, as otherwise the user picker won't be visible
await selectHomeserver(page, homeserver.config.baseUrl);

await page.getByRole("button", { name: "Edit" }).click();

Expand All @@ -56,14 +58,7 @@ test.describe("Login", () => {
await expect(page.locator(".mx_ServerPicker_server")).toHaveText("server.invalid");

// switch back to the custom homeserver
await page.getByRole("button", { name: "Edit" }).click();
await page.getByRole("textbox", { name: "Other homeserver" }).fill(homeserver.config.baseUrl);
await page.getByRole("button", { name: "Continue", exact: true }).click();
// wait for the dialog to go away
await expect(page.locator(".mx_ServerPickerDialog")).toHaveCount(0);

await expect(page.locator(".mx_Spinner")).toHaveCount(0);
await expect(page.locator(".mx_ServerPicker_server")).toHaveText(homeserver.config.baseUrl);
await selectHomeserver(page, homeserver.config.baseUrl);

await expect(page.getByRole("textbox", { name: "Username" })).toBeVisible();
// Disabled because flaky - see https://github.com/vector-im/element-web/issues/24688
Expand All @@ -76,6 +71,31 @@ test.describe("Login", () => {

await expect(page).toHaveURL(/\/#\/home$/);
});

test("Follows the original link after login", async ({ page, homeserver }) => {
await page.goto("/#/room/!room:id"); // should redirect to the welcome page
await page.getByRole("link", { name: "Sign in" }).click();

await selectHomeserver(page, homeserver.config.baseUrl);

await page.getByRole("textbox", { name: "Username" }).fill(username);
await page.getByPlaceholder("Password").fill(password);
await page.getByRole("button", { name: "Sign in" }).click();

await expect(page).toHaveURL(/\/#\/room\/!room:id$/);
await expect(page.getByRole("button", { name: "Join the discussion" })).toBeVisible();
});

async function selectHomeserver(page: Page, homeserverUrl: string) {
await page.getByRole("button", { name: "Edit" }).click();
await page.getByRole("textbox", { name: "Other homeserver" }).fill(homeserverUrl);
await page.getByRole("button", { name: "Continue", exact: true }).click();
// wait for the dialog to go away
await expect(page.locator(".mx_ServerPickerDialog")).toHaveCount(0);

await expect(page.locator(".mx_Spinner")).toHaveCount(0);
await expect(page.locator(".mx_ServerPicker_server")).toHaveText(homeserverUrl);
}
});

// tests for old-style SSO login, in which we exchange tokens with Synapse, and Synapse talks to an auth server
Expand Down
2 changes: 1 addition & 1 deletion playwright/plugins/homeserver/synapse/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { randB64Bytes } from "../../utils/rand";
// Docker tag to use for `matrixdotorg/synapse` 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:6ef71b95a6ff5c5b1bdcc052e0acc6ac1ef28f6904772a7077f5e0ede260e422";
const DOCKER_TAG = "develop@sha256:54998edd6a29399e53c541cb698ce63569a47fde8680212acf23b0d7b795db95";

async function cfgDirFromTemplate(opts: StartHomeserverOpts): Promise<Omit<HomeserverConfig, "dockerUrl">> {
const templateDir = path.join(__dirname, "templates", opts.template);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A synapse configured with guest registration enabled.
Loading

0 comments on commit 69e45f9

Please sign in to comment.