Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
"@babel/runtime": "^7.12.5",
"@casualbot/jest-sonar-reporter": "2.2.7",
"@element-hq/element-call-embedded": "0.16.0",
"@element-hq/element-web-playwright-common": "^1.4.6",
"@element-hq/element-web-playwright-common": "^2.0.0",
"@peculiar/webcrypto": "^1.4.3",
"@playwright/test": "^1.50.1",
"@principalstudio/html-webpack-inject-preload": "^1.2.7",
Expand Down
59 changes: 59 additions & 0 deletions playwright/e2e/crypto/history-sharing.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
Copyright 2025 New Vector Ltd.

SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/

import { createNewInstance } from "@element-hq/element-web-playwright-common";

import { expect, test } from "../../element-web-test";
import { ElementAppPage } from "../../pages/ElementAppPage";
import { createRoom, sendMessageInCurrentRoom } from "./utils";

test.use({
displayName: "Alice",
labsFlags: ["feature_share_history_on_invite"],
});

/** Tests for MSC4268: encrypted history sharing */
test.describe("History sharing", function () {
test(
"We should share history when sending invites",
{ tag: "@screenshot" },
async (
{ labsFlags, browser, page: alicePage, user: aliceCredentials, app: aliceElementApp, homeserver },
testInfo,
) => {
// In this test, Alice creates an encrypted room and sends an event;
// we then invite Bob, and ensure Bob can see the content.

await aliceElementApp.client.bootstrapCrossSigning(aliceCredentials);

// Register a second user, and open it in a second instance of the app
const bobCredentials = await homeserver.registerUser(`user_${testInfo.testId}_bob`, "password", "Bob");
const bobPage = await createNewInstance(browser, bobCredentials, {}, labsFlags);
const bobElementApp = new ElementAppPage(bobPage);
await bobElementApp.client.bootstrapCrossSigning(bobCredentials);

// Create the room and send a message
await createRoom(alicePage, "TestRoom", true);
await sendMessageInCurrentRoom(alicePage, "A message from Alice");

// Send the invite to Bob
await aliceElementApp.inviteUserToCurrentRoom(bobCredentials.userId);

// Bob accepts the invite
await bobPage.getByRole("option", { name: "TestRoom" }).click();
await bobPage.getByRole("button", { name: "Accept" }).click();

// Bob should now be able to decrypt the event
await expect(bobPage.getByText("A message from Alice")).toBeVisible();

const mask = [bobPage.locator(".mx_MessageTimestamp")];
await expect(bobPage.locator(".mx_RoomView_body")).toMatchScreenshot("shared-history-invite-accepted.png", {
mask,
});
},
);
});
9 changes: 3 additions & 6 deletions playwright/e2e/knock/create-knock-room.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ test.describe("Create Knock Room", () => {

await expect(page.locator(".mx_RoomHeader").getByText("Cybersecurity")).toBeVisible();

const urlHash = await page.evaluate(() => window.location.hash);
const roomId = urlHash.replace("#/room/", "");
const roomId = await app.getCurrentRoomIdFromUrl();

// Room should have a knock join rule
await waitForRoom(page, app.client, roomId, (room) => {
Expand All @@ -44,8 +43,7 @@ test.describe("Create Knock Room", () => {

await expect(page.locator(".mx_RoomHeader").getByText("Cybersecurity")).toBeVisible();

const urlHash = await page.evaluate(() => window.location.hash);
const roomId = urlHash.replace("#/room/", "");
const roomId = await app.getCurrentRoomIdFromUrl();

await app.settings.openRoomSettings("Security & Privacy");

Expand All @@ -70,8 +68,7 @@ test.describe("Create Knock Room", () => {

await expect(page.locator(".mx_RoomHeader").getByText("Cybersecurity")).toBeVisible();

const urlHash = await page.evaluate(() => window.location.hash);
const roomId = urlHash.replace("#/room/", "");
const roomId = await app.getCurrentRoomIdFromUrl();

// Room should have a knock join rule
await waitForRoom(page, app.client, roomId, (room) => {
Expand Down
1 change: 1 addition & 0 deletions playwright/e2e/login/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export async function doTokenRegistration(
await expect(page.getByRole("heading", { name: "Welcome Alice", exact: true })).toBeVisible();

return page.evaluate(() => ({
homeserverBaseUrl: window.mxMatrixClientPeg.get().getHomeserverUrl(),
accessToken: window.mxMatrixClientPeg.get().getAccessToken(),
userId: window.mxMatrixClientPeg.get().getUserId(),
deviceId: window.mxMatrixClientPeg.get().getDeviceId(),
Expand Down
16 changes: 3 additions & 13 deletions playwright/e2e/oidc/oidc-native.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/

import { type Config, CONFIG_JSON } from "@element-hq/element-web-playwright-common";
import { type Config } from "@element-hq/element-web-playwright-common";
import { type Browser, type Page } from "@playwright/test";
import { type StartedHomeserverContainer } from "@element-hq/element-web-playwright-common/lib/testcontainers/HomeserverContainer";
import { routeConfigJson } from "@element-hq/element-web-playwright-common";

import { test, expect } from "../../element-web-test.ts";
import { logInAccountMas, registerAccountMas } from ".";
Expand Down Expand Up @@ -242,17 +243,6 @@ async function verifyUsingOtherDevice(deviceToVerifyPage: Page, alreadyVerifiedD
*/
async function newContext(browser: Browser, config: Partial<Partial<Config>>, homeserver: StartedHomeserverContainer) {
const otherContext = await browser.newContext();
await otherContext.route(`http://localhost:8080/config.json*`, async (route) => {
const json = {
...CONFIG_JSON,
...config,
default_server_config: {
"m.homeserver": {
base_url: homeserver.baseUrl,
},
},
};
await route.fulfill({ json });
});
await routeConfigJson(otherContext, homeserver.baseUrl, config);
return otherContext;
}
29 changes: 29 additions & 0 deletions playwright/pages/ElementAppPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,20 @@ export class ElementAppPage {
return await this.page.evaluate(() => navigator.clipboard.readText());
}

/**
* Get the room ID from the current URL.
*
* @returns The room ID.
* @throws if the current URL does not contain a room ID.
*/
public async getCurrentRoomIdFromUrl(): Promise<string> {
const urlHash = await this.page.evaluate(() => window.location.hash);
if (!urlHash.startsWith("#/room/")) {
throw new Error("URL hash suggests we are not in a room");
}
return urlHash.replace("#/room/", "");
}

/**
* Opens the given room by name. The room must be visible in the
* room list and the room may contain unread messages.
Expand Down Expand Up @@ -197,6 +211,21 @@ export class ElementAppPage {
return memberlist;
}

/**
* Open the room info panel, and use it to send an invite to the given user.
*
* @param userId - The user to invite to the room.
*/
public async inviteUserToCurrentRoom(userId: string): Promise<void> {
await this.toggleRoomInfoPanel(); // TODO skip this if the room info panel is already open
await this.page.getByLabel("Right panel").getByRole("menuitem", { name: "Invite" }).click();

const input = this.page.getByRole("dialog").getByTestId("invite-dialog-input");
await input.fill(userId);
await input.press("Enter");
await this.page.getByRole("dialog").getByRole("button", { name: "Invite" }).click();
}

/**
* Get a locator for the tooltip associated with an element
* @param e The element with the tooltip
Expand Down
13 changes: 2 additions & 11 deletions playwright/plugins/homeserver/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/

import { type ClientServerApi } from "@element-hq/element-web-playwright-common/lib/utils/api.js";
import { type ClientServerApi, type Credentials } from "@element-hq/element-web-playwright-common/lib/utils/api.js";
export { type Credentials } from "@element-hq/element-web-playwright-common/lib/utils/api.js";

export interface HomeserverInstance {
readonly baseUrl: string;
Expand Down Expand Up @@ -37,14 +38,4 @@ export interface HomeserverInstance {
setThreepid(userId: string, medium: string, address: string): Promise<void>;
}

export interface Credentials {
accessToken: string;
userId: string;
deviceId: string;
homeServer: string;
password: string | null; // null for password-less users
displayName?: string;
username: string; // the localpart of the userId
}

export type HomeserverType = "synapse" | "dendrite" | "pinecone";
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1738,10 +1738,10 @@
resolved "https://registry.yarnpkg.com/@element-hq/element-web-module-api/-/element-web-module-api-1.4.1.tgz#a46526d58985190f9989bf1686ea872687d3c6e1"
integrity sha512-A8yaQtX7QoKThzzZVU+VYOFhpiNyppEMuIQijK48RvhVp1nwmy0cTD6u/6Yn64saNwJjtna+Oy+Qzo/TfwwhxQ==

"@element-hq/element-web-playwright-common@^1.4.6":
version "1.4.6"
resolved "https://registry.yarnpkg.com/@element-hq/element-web-playwright-common/-/element-web-playwright-common-1.4.6.tgz#a94d5d4ea94627aec430dd904c43f509a2e6c4b2"
integrity sha512-LJ4V6e6NrF2ikNCsxR93PFwDfcRUTY3b2reXwlFJeo44pj8vTYFxkuJwokibFx6+x1zkXWAIMh/0saTMRUXdSA==
"@element-hq/element-web-playwright-common@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@element-hq/element-web-playwright-common/-/element-web-playwright-common-2.0.0.tgz#30cf741a33c69540b4bc434f5349d0fe900bc611"
integrity sha512-axrWlPzP/OljYq53cefo9hha0SGDDu4HeM+sgevgbZSFSms8LsdMsMCyRyUcVBiGYb1xdKmM3RUsWOw5//eE+A==
dependencies:
"@axe-core/playwright" "^4.10.1"
"@testcontainers/postgresql" "^11.0.0"
Expand Down
Loading