Merge remote-tracking branch 'origin/main' into rav/new_context

This commit is contained in:
Richard van der Hoff
2025-10-03 14:32:47 +01:00
5 changed files with 53 additions and 31 deletions
@@ -12,6 +12,32 @@ import { sample, uniqueId } from "lodash-es";
import { test as base } from "./services.js"; import { test as base } from "./services.js";
import { Credentials } from "../utils/api.js"; import { Credentials } from "../utils/api.js";
/** Adds an initScript to the given page which will populate localStorage appropriately so that Element will use the given credentials. */
export async function populateLocalStorageWithCredentials(page: Page, credentials: Credentials) {
await page.addInitScript(
({ credentials }) => {
window.localStorage.setItem("mx_hs_url", credentials.homeserverBaseUrl);
window.localStorage.setItem("mx_user_id", credentials.userId);
window.localStorage.setItem("mx_access_token", credentials.accessToken);
window.localStorage.setItem("mx_device_id", credentials.deviceId);
window.localStorage.setItem("mx_is_guest", "false");
window.localStorage.setItem("mx_has_pickle_key", "false");
window.localStorage.setItem("mx_has_access_token", "true");
window.localStorage.setItem(
"mx_local_settings",
JSON.stringify({
// Retain any other settings which may have already been set
...JSON.parse(window.localStorage.getItem("mx_local_settings") ?? "{}"),
// Ensure the language is set to a consistent value
language: "en",
}),
);
},
{ credentials },
);
}
export const test = base.extend<{ export const test = base.extend<{
/** /**
* The displayname to use for the user registered in {@link #credentials}. * The displayname to use for the user registered in {@link #credentials}.
@@ -38,7 +64,7 @@ export const test = base.extend<{
/** /**
* A (rather poorly-named) test fixture which registers a user per {@link #credentials}, stores * A (rather poorly-named) test fixture which registers a user per {@link #credentials}, stores
* the credentials into localStorage per {@link #homeserver}, and then loads the front page of the * the credentials into localStorage per {@link #pageWithCredentials}, and then loads the front page of the
* app. * app.
*/ */
user: Credentials; user: Credentials;
@@ -58,30 +84,8 @@ export const test = base.extend<{
}); });
}, },
pageWithCredentials: async ({ page, homeserver, credentials }, use) => { pageWithCredentials: async ({ page, credentials }, use) => {
await page.addInitScript( await populateLocalStorageWithCredentials(page, credentials);
({ baseUrl, credentials }) => {
// Seed the localStorage with the required credentials
window.localStorage.setItem("mx_hs_url", baseUrl);
window.localStorage.setItem("mx_user_id", credentials.userId);
window.localStorage.setItem("mx_access_token", credentials.accessToken);
window.localStorage.setItem("mx_device_id", credentials.deviceId);
window.localStorage.setItem("mx_is_guest", "false");
window.localStorage.setItem("mx_has_pickle_key", "false");
window.localStorage.setItem("mx_has_access_token", "true");
window.localStorage.setItem(
"mx_local_settings",
JSON.stringify({
// Retain any other settings which may have already been set
...JSON.parse(window.localStorage.getItem("mx_local_settings") ?? "{}"),
// Ensure the language is set to a consistent value
language: "en",
}),
);
},
{ baseUrl: homeserver.baseUrl, credentials },
);
await use(page); await use(page);
}, },
@@ -13,6 +13,8 @@ import { routeConfigJson } from "./utils/config_json.js";
export * from "./utils/config_json.js"; export * from "./utils/config_json.js";
export { populateLocalStorageWithCredentials } from "./fixtures/user.js";
// Enable experimental service worker support // Enable experimental service worker support
// See https://playwright.dev/docs/service-workers-experimental#how-to-enable // See https://playwright.dev/docs/service-workers-experimental#how-to-enable
process.env["PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS"] = "1"; process.env["PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS"] = "1";
@@ -302,7 +302,7 @@ export class StartedMatrixAuthenticationServiceContainer extends AbstractStarted
password: string, password: string,
displayName?: string, displayName?: string,
admin = false, admin = false,
): Promise<Credentials> { ): Promise<Omit<Credentials, "homeserverBaseUrl">> {
const userId = await this.manageRegisterUser(username, password, displayName, admin); const userId = await this.manageRegisterUser(username, password, displayName, admin);
const { deviceId, accessToken } = await this.manageIssueCompatibilityToken(username, admin); const { deviceId, accessToken } = await this.manageIssueCompatibilityToken(username, admin);
@@ -319,11 +319,16 @@ export class StartedMatrixAuthenticationServiceContainer extends AbstractStarted
/** /**
* Registers a user * Registers a user
*
* @param username - the username of the user to register * @param username - the username of the user to register
* @param password - the password of the user to register * @param password - the password of the user to register
* @param displayName - optional display name to set on the newly registered user * @param displayName - optional display name to set on the newly registered user
*/ */
public async registerUser(username: string, password: string, displayName?: string): Promise<Credentials> { public async registerUser(
username: string,
password: string,
displayName?: string,
): Promise<Omit<Credentials, "homeserverBaseUrl">> {
return this.registerUserInternal(username, password, displayName, false); return this.registerUserInternal(username, password, displayName, false);
} }
@@ -389,6 +389,7 @@ export class StartedSynapseContainer extends AbstractStartedContainer implements
return { return {
homeServer: data.home_server || data.user_id.split(":").slice(1).join(":"), homeServer: data.home_server || data.user_id.split(":").slice(1).join(":"),
homeserverBaseUrl: this.baseUrl,
accessToken: data.access_token, accessToken: data.access_token,
userId: data.user_id, userId: data.user_id,
deviceId: data.device_id, deviceId: data.device_id,
@@ -433,7 +434,10 @@ export class StartedSynapseContainer extends AbstractStartedContainer implements
* @param password - login password * @param password - login password
*/ */
public async loginUser(userId: string, password: string): Promise<Credentials> { public async loginUser(userId: string, password: string): Promise<Credentials> {
return this.csApi.loginUser(userId, password); return {
...(await this.csApi.loginUser(userId, password)),
homeserverBaseUrl: this.baseUrl,
};
} }
/** /**
@@ -480,8 +484,9 @@ export class StartedSynapseWithMasContainer extends StartedSynapseContainer {
* @param password - the password of the user to register * @param password - the password of the user to register
* @param displayName - optional display name to set on the newly registered user * @param displayName - optional display name to set on the newly registered user
*/ */
public registerUser(username: string, password: string, displayName?: string): Promise<Credentials> { public async registerUser(username: string, password: string, displayName?: string): Promise<Credentials> {
return this.mas.registerUser(username, password, displayName); const registered = await this.mas.registerUser(username, password, displayName);
return { ...registered, homeserverBaseUrl: this.baseUrl };
} }
/** /**
@@ -64,10 +64,16 @@ export class Api {
* Credentials for a user. * Credentials for a user.
*/ */
export interface Credentials { export interface Credentials {
/** The base URL of the homeserver's CS API. */
homeserverBaseUrl: string;
accessToken: string; accessToken: string;
userId: string; userId: string;
deviceId: string; deviceId: string;
/** The domain part of the user's matrix ID. */
homeServer: string; homeServer: string;
password: string | null; // null for password-less users password: string | null; // null for password-less users
displayName?: string; displayName?: string;
username: string; // the localpart of the userId username: string; // the localpart of the userId
@@ -86,7 +92,7 @@ export class ClientServerApi extends Api {
* @param userId - The user ID to register. * @param userId - The user ID to register.
* @param password - The password to use for the user. * @param password - The password to use for the user.
*/ */
public async loginUser(userId: string, password: string): Promise<Credentials> { public async loginUser(userId: string, password: string): Promise<Omit<Credentials, "homeserverBaseUrl">> {
const json = await this.request<{ const json = await this.request<{
access_token: string; access_token: string;
user_id: string; user_id: string;