@element-hq/element-web-playwright-common 1.4.6 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,7 @@
1
1
  import { type Page } from "@playwright/test";
2
2
  import { Credentials } from "../utils/api.js";
3
+ /** Adds an initScript to the given page which will populate localStorage appropriately so that Element will use the given credentials. */
4
+ export declare function populateLocalStorageWithCredentials(page: Page, credentials: Credentials): Promise<void>;
3
5
  export declare const test: import("playwright/test").TestType<import("playwright/test").PlaywrightTestArgs & import("playwright/test").PlaywrightTestOptions & import("./services.js").TestFixtures & {
4
6
  /**
5
7
  * The displayname to use for the user registered in {@link #credentials}.
@@ -23,7 +25,7 @@ export declare const test: import("playwright/test").TestType<import("playwright
23
25
  pageWithCredentials: Page;
24
26
  /**
25
27
  * A (rather poorly-named) test fixture which registers a user per {@link #credentials}, stores
26
- * the credentials into localStorage per {@link #homeserver}, and then loads the front page of the
28
+ * the credentials into localStorage per {@link #pageWithCredentials}, and then loads the front page of the
27
29
  * app.
28
30
  */
29
31
  user: Credentials;
@@ -1 +1 @@
1
- {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/fixtures/user.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAI7C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,eAAO,MAAM,IAAI;IACb;;;;;OAKG;kBACW,MAAM;IAEpB;;;OAGG;iBACU,WAAW;IAExB;;;;;;OAMG;yBACkB,IAAI;IAEzB;;;;OAIG;UACG,WAAW;iLAiDnB,CAAC"}
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/fixtures/user.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAI7C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,0IAA0I;AAC1I,wBAAsB,mCAAmC,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,iBAuB7F;AAED,eAAO,MAAM,IAAI;IACb;;;;;OAKG;kBACW,MAAM;IAEpB;;;OAGG;iBACU,WAAW;IAExB;;;;;;OAMG;yBACkB,IAAI;IAEzB;;;;OAIG;UACG,WAAW;iLA2BnB,CAAC"}
@@ -7,6 +7,24 @@ Please see LICENSE files in the repository root for full details.
7
7
  */
8
8
  import { sample, uniqueId } from "lodash-es";
9
9
  import { test as base } from "./services.js";
10
+ /** Adds an initScript to the given page which will populate localStorage appropriately so that Element will use the given credentials. */
11
+ export async function populateLocalStorageWithCredentials(page, credentials) {
12
+ await page.addInitScript(({ credentials }) => {
13
+ window.localStorage.setItem("mx_hs_url", credentials.homeserverBaseUrl);
14
+ window.localStorage.setItem("mx_user_id", credentials.userId);
15
+ window.localStorage.setItem("mx_access_token", credentials.accessToken);
16
+ window.localStorage.setItem("mx_device_id", credentials.deviceId);
17
+ window.localStorage.setItem("mx_is_guest", "false");
18
+ window.localStorage.setItem("mx_has_pickle_key", "false");
19
+ window.localStorage.setItem("mx_has_access_token", "true");
20
+ window.localStorage.setItem("mx_local_settings", JSON.stringify({
21
+ // Retain any other settings which may have already been set
22
+ ...JSON.parse(window.localStorage.getItem("mx_local_settings") ?? "{}"),
23
+ // Ensure the language is set to a consistent value
24
+ language: "en",
25
+ }));
26
+ }, { credentials });
27
+ }
10
28
  export const test = base.extend({
11
29
  displayName: undefined,
12
30
  credentials: async ({ homeserver, displayName: testDisplayName }, use, testInfo) => {
@@ -20,23 +38,8 @@ export const test = base.extend({
20
38
  displayName,
21
39
  });
22
40
  },
23
- pageWithCredentials: async ({ page, homeserver, credentials }, use) => {
24
- await page.addInitScript(({ baseUrl, credentials }) => {
25
- // Seed the localStorage with the required credentials
26
- window.localStorage.setItem("mx_hs_url", baseUrl);
27
- window.localStorage.setItem("mx_user_id", credentials.userId);
28
- window.localStorage.setItem("mx_access_token", credentials.accessToken);
29
- window.localStorage.setItem("mx_device_id", credentials.deviceId);
30
- window.localStorage.setItem("mx_is_guest", "false");
31
- window.localStorage.setItem("mx_has_pickle_key", "false");
32
- window.localStorage.setItem("mx_has_access_token", "true");
33
- window.localStorage.setItem("mx_local_settings", JSON.stringify({
34
- // Retain any other settings which may have already been set
35
- ...JSON.parse(window.localStorage.getItem("mx_local_settings") ?? "{}"),
36
- // Ensure the language is set to a consistent value
37
- language: "en",
38
- }));
39
- }, { baseUrl: homeserver.baseUrl, credentials });
41
+ pageWithCredentials: async ({ page, credentials }, use) => {
42
+ await populateLocalStorageWithCredentials(page, credentials);
40
43
  await use(page);
41
44
  },
42
45
  user: async ({ pageWithCredentials: page, credentials }, use) => {
package/lib/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  import { type Config as BaseConfig } from "@element-hq/element-web-module-api";
2
+ export * from "./utils/config_json.js";
3
+ export * from "./utils/context.js";
4
+ export { populateLocalStorageWithCredentials } from "./fixtures/user.js";
2
5
  export interface Config extends BaseConfig {
3
6
  default_server_config: {
4
7
  "m.homeserver"?: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,MAAM,IAAI,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAU/E,MAAM,WAAW,MAAO,SAAQ,UAAU;IACtC,qBAAqB,EAAE;QACnB,cAAc,CAAC,EAAE;YACb,QAAQ,EAAE,MAAM,CAAC;YACjB,WAAW,CAAC,EAAE,MAAM,CAAC;SACxB,CAAC;QACF,mBAAmB,CAAC,EAAE;YAClB,QAAQ,EAAE,MAAM,CAAC;YACjB,WAAW,CAAC,EAAE,MAAM,CAAC;SACxB,CAAC;KACL,CAAC;IACF,yBAAyB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAGD,eAAO,MAAM,WAAW,EAAE,OAAO,CAAC,MAAM,CAevC,CAAC;AAEF,MAAM,WAAW,YAAY;IACzB;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC;IAEpC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;CAC5B;AAED,eAAO,MAAM,IAAI;;;;;;;kNAkCf,CAAC;AAEH,OAAO,EAAE,MAAM,EAAE,KAAK,wBAAwB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,MAAM,IAAI,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAK/E,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AAEnC,OAAO,EAAE,mCAAmC,EAAE,MAAM,oBAAoB,CAAC;AAQzE,MAAM,WAAW,MAAO,SAAQ,UAAU;IACtC,qBAAqB,EAAE;QACnB,cAAc,CAAC,EAAE;YACb,QAAQ,EAAE,MAAM,CAAC;YACjB,WAAW,CAAC,EAAE,MAAM,CAAC;SACxB,CAAC;QACF,mBAAmB,CAAC,EAAE;YAClB,QAAQ,EAAE,MAAM,CAAC;YACjB,WAAW,CAAC,EAAE,MAAM,CAAC;SACxB,CAAC;KACL,CAAC;IACF,yBAAyB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAGD,eAAO,MAAM,WAAW,EAAE,OAAO,CAAC,MAAM,CAevC,CAAC;AAEF,MAAM,WAAW,YAAY;IACzB;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC;IAEpC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;CAC5B;AAED,eAAO,MAAM,IAAI;;;;;;;kNASf,CAAC;AAEH,OAAO,EAAE,MAAM,EAAE,KAAK,wBAAwB,EAAE,MAAM,mBAAmB,CAAC"}
package/lib/index.js CHANGED
@@ -6,6 +6,10 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
6
6
  Please see LICENSE files in the repository root for full details.
7
7
  */
8
8
  import { test as base } from "./fixtures/index.js";
9
+ import { routeConfigJson } from "./utils/config_json.js";
10
+ export * from "./utils/config_json.js";
11
+ export * from "./utils/context.js";
12
+ export { populateLocalStorageWithCredentials } from "./fixtures/user.js";
9
13
  // Enable experimental service worker support
10
14
  // See https://playwright.dev/docs/service-workers-experimental#how-to-enable
11
15
  process.env["PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS"] = "1";
@@ -29,32 +33,7 @@ export const test = base.extend({
29
33
  labsFlags: async ({}, use) => use([]),
30
34
  disablePresence: async ({}, use) => use(false),
31
35
  page: async ({ homeserver, context, page, config, labsFlags, disablePresence }, use) => {
32
- await context.route(`http://localhost:8080/config.json*`, async (route) => {
33
- const json = {
34
- ...CONFIG_JSON,
35
- ...config,
36
- default_server_config: {
37
- "m.homeserver": {
38
- base_url: homeserver.baseUrl,
39
- },
40
- ...config.default_server_config,
41
- },
42
- };
43
- json["features"] = {
44
- ...json["features"],
45
- // Enable the lab features
46
- ...labsFlags.reduce((obj, flag) => {
47
- obj[flag] = true;
48
- return obj;
49
- }, {}),
50
- };
51
- if (disablePresence) {
52
- json["enable_presence_by_hs_url"] = {
53
- [homeserver.baseUrl]: false,
54
- };
55
- }
56
- await route.fulfill({ json });
57
- });
36
+ await routeConfigJson(context, homeserver.baseUrl, config, labsFlags, disablePresence);
58
37
  await use(page);
59
38
  },
60
39
  });
@@ -41,11 +41,12 @@ export declare class StartedMatrixAuthenticationServiceContainer extends Abstrac
41
41
  private registerUserInternal;
42
42
  /**
43
43
  * Registers a user
44
+ *
44
45
  * @param username - the username of the user to register
45
46
  * @param password - the password of the user to register
46
47
  * @param displayName - optional display name to set on the newly registered user
47
48
  */
48
- registerUser(username: string, password: string, displayName?: string): Promise<Credentials>;
49
+ registerUser(username: string, password: string, displayName?: string): Promise<Omit<Credentials, "homeserverBaseUrl">>;
49
50
  /**
50
51
  * Binds a 3pid
51
52
  * @param username - the username of the user to bind the 3pid to
@@ -1 +1 @@
1
- {"version":3,"file":"mas.d.ts","sourceRoot":"","sources":["../../src/testcontainers/mas.ts"],"names":[],"mappings":"AAOA,OAAO,EACH,wBAAwB,EACxB,gBAAgB,EAChB,KAAK,oBAAoB,EAEzB,KAAK,UAAU,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAK7E,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAKnD,OAAO,KAAK,EAAE,UAAU,IAAI,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE/D,OAAO,EAAE,KAAK,SAAS,EAAE,CAAC;AAmH1B;;;;;GAKG;AACH,qBAAa,oCAAqC,SAAQ,gBAAgB;IACtE,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiC;gBAGlD,EAAE,EAAE,0BAA0B,EAC9B,KAAK,GAAE,MAAkE;IAe7E;;;OAGG;IACI,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI;IAQnD;;OAEG;IACmB,KAAK,IAAI,OAAO,CAAC,2CAA2C,CAAC;CA0BtF;AAED;;GAEG;AACH,qBAAa,2CAA4C,SAAQ,wBAAwB;aAKjE,OAAO,EAAE,MAAM;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI;IALzB,OAAO,CAAC,iBAAiB,CAAC,CAAkB;gBAGxC,SAAS,EAAE,oBAAoB,EACf,OAAO,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAAE;IAKnC;;OAEG;IACU,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAYhC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;YAQ1D,kBAAkB;YAgClB,6BAA6B;YAmB7B,oBAAoB;IAoBlC;;;;;OAKG;IACU,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAIzG;;;;;OAKG;IACU,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAO7F"}
1
+ {"version":3,"file":"mas.d.ts","sourceRoot":"","sources":["../../src/testcontainers/mas.ts"],"names":[],"mappings":"AAOA,OAAO,EACH,wBAAwB,EACxB,gBAAgB,EAChB,KAAK,oBAAoB,EAEzB,KAAK,UAAU,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAK7E,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAKnD,OAAO,KAAK,EAAE,UAAU,IAAI,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE/D,OAAO,EAAE,KAAK,SAAS,EAAE,CAAC;AAmH1B;;;;;GAKG;AACH,qBAAa,oCAAqC,SAAQ,gBAAgB;IACtE,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiC;gBAGlD,EAAE,EAAE,0BAA0B,EAC9B,KAAK,GAAE,MAAkE;IAe7E;;;OAGG;IACI,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI;IAQnD;;OAEG;IACmB,KAAK,IAAI,OAAO,CAAC,2CAA2C,CAAC;CA0BtF;AAED;;GAEG;AACH,qBAAa,2CAA4C,SAAQ,wBAAwB;aAKjE,OAAO,EAAE,MAAM;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI;IALzB,OAAO,CAAC,iBAAiB,CAAC,CAAkB;gBAGxC,SAAS,EAAE,oBAAoB,EACf,OAAO,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAAE;IAKnC;;OAEG;IACU,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAYhC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;YAQ1D,kBAAkB;YAgClB,6BAA6B;YAmB7B,oBAAoB;IAoBlC;;;;;;OAMG;IACU,YAAY,CACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;IAIlD;;;;;OAKG;IACU,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAO7F"}
@@ -244,6 +244,7 @@ export class StartedMatrixAuthenticationServiceContainer extends AbstractStarted
244
244
  }
245
245
  /**
246
246
  * Registers a user
247
+ *
247
248
  * @param username - the username of the user to register
248
249
  * @param password - the password of the user to register
249
250
  * @param displayName - optional display name to set on the newly registered user
@@ -1 +1 @@
1
- {"version":3,"file":"synapse.d.ts","sourceRoot":"","sources":["../../src/testcontainers/synapse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"synapse.d.ts","sourceRoot":"","sources":["../../src/testcontainers/synapse.ts"],"names":[],"mappings":"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"}
@@ -299,6 +299,7 @@ export class StartedSynapseContainer extends AbstractStartedContainer {
299
299
  });
300
300
  return {
301
301
  homeServer: data.home_server || data.user_id.split(":").slice(1).join(":"),
302
+ homeserverBaseUrl: this.baseUrl,
302
303
  accessToken: data.access_token,
303
304
  userId: data.user_id,
304
305
  deviceId: data.device_id,
@@ -332,7 +333,10 @@ export class StartedSynapseContainer extends AbstractStartedContainer {
332
333
  * @param password - login password
333
334
  */
334
335
  async loginUser(userId, password) {
335
- return this.csApi.loginUser(userId, password);
336
+ return {
337
+ ...(await this.csApi.loginUser(userId, password)),
338
+ homeserverBaseUrl: this.baseUrl,
339
+ };
336
340
  }
337
341
  /**
338
342
  * Binds a 3pid
@@ -372,8 +376,9 @@ export class StartedSynapseWithMasContainer extends StartedSynapseContainer {
372
376
  * @param password - the password of the user to register
373
377
  * @param displayName - optional display name to set on the newly registered user
374
378
  */
375
- registerUser(username, password, displayName) {
376
- return this.mas.registerUser(username, password, displayName);
379
+ async registerUser(username, password, displayName) {
380
+ const registered = await this.mas.registerUser(username, password, displayName);
381
+ return { ...registered, homeserverBaseUrl: this.baseUrl };
377
382
  }
378
383
  /**
379
384
  * Binds a 3pid
@@ -26,9 +26,12 @@ export declare class Api {
26
26
  * Credentials for a user.
27
27
  */
28
28
  export interface Credentials {
29
+ /** The base URL of the homeserver's CS API. */
30
+ homeserverBaseUrl: string;
29
31
  accessToken: string;
30
32
  userId: string;
31
33
  deviceId: string;
34
+ /** The domain part of the user's matrix ID. */
32
35
  homeServer: string;
33
36
  password: string | null;
34
37
  displayName?: string;
@@ -44,6 +47,6 @@ export declare class ClientServerApi extends Api {
44
47
  * @param userId - The user ID to register.
45
48
  * @param password - The password to use for the user.
46
49
  */
47
- loginUser(userId: string, password: string): Promise<Credentials>;
50
+ loginUser(userId: string, password: string): Promise<Omit<Credentials, "homeserverBaseUrl">>;
48
51
  }
49
52
  //# sourceMappingURL=api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/utils/api.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,MAAM,IAAI,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;AAErD;;GAEG;AACH,qBAAa,GAAG;IAGO,OAAO,CAAC,QAAQ,CAAC,OAAO;IAF3C,OAAO,CAAC,QAAQ,CAAC,CAAoB;gBAED,OAAO,EAAE,MAAM;IAEnD;;;OAGG;IACI,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAInD;;;;;;OAMG;IACU,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC;IAC9F,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CAyB9G;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,GAAG;gBACjB,OAAO,EAAE,MAAM;IAIlC;;;;OAIG;IACU,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAwBjF"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/utils/api.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,MAAM,IAAI,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;AAErD;;GAEG;AACH,qBAAa,GAAG;IAGO,OAAO,CAAC,QAAQ,CAAC,OAAO;IAF3C,OAAO,CAAC,QAAQ,CAAC,CAAoB;gBAED,OAAO,EAAE,MAAM;IAEnD;;;OAGG;IACI,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAInD;;;;;;OAMG;IACU,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC;IAC9F,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CAyB9G;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,+CAA+C;IAC/C,iBAAiB,EAAE,MAAM,CAAC;IAE1B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IAEjB,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IAEnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,GAAG;gBACjB,OAAO,EAAE,MAAM;IAIlC;;;;OAIG;IACU,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;CAwB5G"}
@@ -0,0 +1,21 @@
1
+ import { BrowserContext, Page } from "@playwright/test";
2
+ import { Config } from "../index.js";
3
+ /** Construct a suitable config.json for the given homeserver
4
+ *
5
+ * @param homeserverBaseUrl - The `baseUrl` of the homeserver that the client should be configured to connect to.
6
+ * @param additionalConfig - Additional config to add to the default config.json.
7
+ * @param labsFlags - Lab flags to enable in the client.
8
+ * @param disablePresence - Whether to disable presence for the given homeserver.
9
+ */
10
+ export declare function buildConfigJson(homeserverBaseUrl: string, additionalConfig?: Partial<Config>, labsFlags?: string[], disablePresence?: boolean): Partial<Config>;
11
+ /**
12
+ * Add a route to the browser context/page which will serve a suitable config.json for the given homeserver.
13
+ *
14
+ * @param context - The browser context or page to route the config.json to.
15
+ * @param homeserverBaseUrl - The `baseUrl` of the homeserver that the client should be configured to connect to.
16
+ * @param additionalConfig - Additional config to add to the default config.json.
17
+ * @param labsFlags - Lab flags to enable in the client.
18
+ * @param disablePresence - Whether to disable presence for the given homeserver.
19
+ */
20
+ export declare function routeConfigJson(context: BrowserContext | Page, homeserverBaseUrl: string, additionalConfig?: Partial<Config>, labsFlags?: string[], disablePresence?: boolean): Promise<void>;
21
+ //# sourceMappingURL=config_json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config_json.d.ts","sourceRoot":"","sources":["../../src/utils/config_json.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,MAAM,EAAe,MAAM,aAAa,CAAC;AAElD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC3B,iBAAiB,EAAE,MAAM,EACzB,gBAAgB,GAAE,OAAO,CAAC,MAAM,CAAM,EACtC,SAAS,GAAE,MAAM,EAAO,EACxB,eAAe,GAAE,OAAe,GACjC,OAAO,CAAC,MAAM,CAAC,CAyBjB;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACjC,OAAO,EAAE,cAAc,GAAG,IAAI,EAC9B,iBAAiB,EAAE,MAAM,EACzB,gBAAgB,GAAE,OAAO,CAAC,MAAM,CAAM,EACtC,SAAS,GAAE,MAAM,EAAO,EACxB,eAAe,GAAE,OAAe,GACjC,OAAO,CAAC,IAAI,CAAC,CAKf"}
@@ -0,0 +1,55 @@
1
+ /*
2
+ Copyright 2025 New Vector Ltd.
3
+
4
+ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
5
+ Please see LICENSE files in the repository root for full details.
6
+ */
7
+ import { CONFIG_JSON } from "../index.js";
8
+ /** Construct a suitable config.json for the given homeserver
9
+ *
10
+ * @param homeserverBaseUrl - The `baseUrl` of the homeserver that the client should be configured to connect to.
11
+ * @param additionalConfig - Additional config to add to the default config.json.
12
+ * @param labsFlags - Lab flags to enable in the client.
13
+ * @param disablePresence - Whether to disable presence for the given homeserver.
14
+ */
15
+ export function buildConfigJson(homeserverBaseUrl, additionalConfig = {}, labsFlags = [], disablePresence = false) {
16
+ const json = {
17
+ ...CONFIG_JSON,
18
+ ...additionalConfig,
19
+ default_server_config: {
20
+ "m.homeserver": {
21
+ base_url: homeserverBaseUrl,
22
+ },
23
+ ...additionalConfig.default_server_config,
24
+ },
25
+ };
26
+ json["features"] = {
27
+ ...json["features"],
28
+ // Enable the lab features
29
+ ...labsFlags.reduce((obj, flag) => {
30
+ obj[flag] = true;
31
+ return obj;
32
+ }, {}),
33
+ };
34
+ if (disablePresence) {
35
+ json["enable_presence_by_hs_url"] = {
36
+ [homeserverBaseUrl]: false,
37
+ };
38
+ }
39
+ return json;
40
+ }
41
+ /**
42
+ * Add a route to the browser context/page which will serve a suitable config.json for the given homeserver.
43
+ *
44
+ * @param context - The browser context or page to route the config.json to.
45
+ * @param homeserverBaseUrl - The `baseUrl` of the homeserver that the client should be configured to connect to.
46
+ * @param additionalConfig - Additional config to add to the default config.json.
47
+ * @param labsFlags - Lab flags to enable in the client.
48
+ * @param disablePresence - Whether to disable presence for the given homeserver.
49
+ */
50
+ export async function routeConfigJson(context, homeserverBaseUrl, additionalConfig = {}, labsFlags = [], disablePresence = false) {
51
+ await context.route(`http://localhost:8080/config.json*`, async (route) => {
52
+ const json = buildConfigJson(homeserverBaseUrl, additionalConfig, labsFlags, disablePresence);
53
+ await route.fulfill({ json });
54
+ });
55
+ }
@@ -0,0 +1,14 @@
1
+ import { Browser } from "playwright-core";
2
+ import { Page } from "@playwright/test";
3
+ import { Credentials } from "./api.js";
4
+ import { Config } from "../index.js";
5
+ /** Create a new instance of the application, in a separate browser context, using the given credentials.
6
+ *
7
+ * @param browser - the browser to use
8
+ * @param credentials - the credentials to use for the new instance
9
+ * @param additionalConfig - additional config for the `config.json` for the new instance
10
+ * @param labsFlags - additional labs flags for the `config.json` for the new instance
11
+ * @param disablePresence - whether to disable presence for the new instance
12
+ */
13
+ export declare function createNewInstance(browser: Browser, credentials: Credentials, additionalConfig?: Partial<Config>, labsFlags?: string[], disablePresence?: boolean): Promise<Page>;
14
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/utils/context.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACnC,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,WAAW,EACxB,gBAAgB,GAAE,OAAO,CAAC,MAAM,CAAM,EACtC,SAAS,GAAE,MAAM,EAAO,EACxB,eAAe,GAAE,OAAe,GACjC,OAAO,CAAC,IAAI,CAAC,CAQf"}
@@ -0,0 +1,25 @@
1
+ /*
2
+ Copyright 2025 New Vector Ltd.
3
+
4
+ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
5
+ Please see LICENSE files in the repository root for full details.
6
+ */
7
+ import { routeConfigJson } from "./config_json.js";
8
+ import { populateLocalStorageWithCredentials } from "../fixtures/user.js";
9
+ /** Create a new instance of the application, in a separate browser context, using the given credentials.
10
+ *
11
+ * @param browser - the browser to use
12
+ * @param credentials - the credentials to use for the new instance
13
+ * @param additionalConfig - additional config for the `config.json` for the new instance
14
+ * @param labsFlags - additional labs flags for the `config.json` for the new instance
15
+ * @param disablePresence - whether to disable presence for the new instance
16
+ */
17
+ export async function createNewInstance(browser, credentials, additionalConfig = {}, labsFlags = [], disablePresence = false) {
18
+ const context = await browser.newContext();
19
+ await routeConfigJson(context, credentials.homeserverBaseUrl, additionalConfig, labsFlags, disablePresence);
20
+ const page = await context.newPage();
21
+ await populateLocalStorageWithCredentials(page, credentials);
22
+ await page.goto("/");
23
+ await page.waitForSelector(".mx_MatrixChat", { timeout: 30000 });
24
+ return page;
25
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@element-hq/element-web-playwright-common",
3
3
  "type": "module",
4
- "version": "1.4.6",
4
+ "version": "2.0.0",
5
5
  "license": "SEE LICENSE IN README.md",
6
6
  "repository": {
7
7
  "type": "git",
@@ -12,6 +12,32 @@ import { sample, uniqueId } from "lodash-es";
12
12
  import { test as base } from "./services.js";
13
13
  import { Credentials } from "../utils/api.js";
14
14
 
15
+ /** Adds an initScript to the given page which will populate localStorage appropriately so that Element will use the given credentials. */
16
+ export async function populateLocalStorageWithCredentials(page: Page, credentials: Credentials) {
17
+ await page.addInitScript(
18
+ ({ credentials }) => {
19
+ window.localStorage.setItem("mx_hs_url", credentials.homeserverBaseUrl);
20
+ window.localStorage.setItem("mx_user_id", credentials.userId);
21
+ window.localStorage.setItem("mx_access_token", credentials.accessToken);
22
+ window.localStorage.setItem("mx_device_id", credentials.deviceId);
23
+ window.localStorage.setItem("mx_is_guest", "false");
24
+ window.localStorage.setItem("mx_has_pickle_key", "false");
25
+ window.localStorage.setItem("mx_has_access_token", "true");
26
+
27
+ window.localStorage.setItem(
28
+ "mx_local_settings",
29
+ JSON.stringify({
30
+ // Retain any other settings which may have already been set
31
+ ...JSON.parse(window.localStorage.getItem("mx_local_settings") ?? "{}"),
32
+ // Ensure the language is set to a consistent value
33
+ language: "en",
34
+ }),
35
+ );
36
+ },
37
+ { credentials },
38
+ );
39
+ }
40
+
15
41
  export const test = base.extend<{
16
42
  /**
17
43
  * The displayname to use for the user registered in {@link #credentials}.
@@ -38,7 +64,7 @@ export const test = base.extend<{
38
64
 
39
65
  /**
40
66
  * A (rather poorly-named) test fixture which registers a user per {@link #credentials}, stores
41
- * the credentials into localStorage per {@link #homeserver}, and then loads the front page of the
67
+ * the credentials into localStorage per {@link #pageWithCredentials}, and then loads the front page of the
42
68
  * app.
43
69
  */
44
70
  user: Credentials;
@@ -58,30 +84,8 @@ export const test = base.extend<{
58
84
  });
59
85
  },
60
86
 
61
- pageWithCredentials: async ({ page, homeserver, credentials }, use) => {
62
- await page.addInitScript(
63
- ({ baseUrl, credentials }) => {
64
- // Seed the localStorage with the required credentials
65
- window.localStorage.setItem("mx_hs_url", baseUrl);
66
- window.localStorage.setItem("mx_user_id", credentials.userId);
67
- window.localStorage.setItem("mx_access_token", credentials.accessToken);
68
- window.localStorage.setItem("mx_device_id", credentials.deviceId);
69
- window.localStorage.setItem("mx_is_guest", "false");
70
- window.localStorage.setItem("mx_has_pickle_key", "false");
71
- window.localStorage.setItem("mx_has_access_token", "true");
72
-
73
- window.localStorage.setItem(
74
- "mx_local_settings",
75
- JSON.stringify({
76
- // Retain any other settings which may have already been set
77
- ...JSON.parse(window.localStorage.getItem("mx_local_settings") ?? "{}"),
78
- // Ensure the language is set to a consistent value
79
- language: "en",
80
- }),
81
- );
82
- },
83
- { baseUrl: homeserver.baseUrl, credentials },
84
- );
87
+ pageWithCredentials: async ({ page, credentials }, use) => {
88
+ await populateLocalStorageWithCredentials(page, credentials);
85
89
  await use(page);
86
90
  },
87
91
 
package/src/index.ts CHANGED
@@ -9,6 +9,12 @@ Please see LICENSE files in the repository root for full details.
9
9
  import { type Config as BaseConfig } from "@element-hq/element-web-module-api";
10
10
 
11
11
  import { test as base } from "./fixtures/index.js";
12
+ import { routeConfigJson } from "./utils/config_json.js";
13
+
14
+ export * from "./utils/config_json.js";
15
+ export * from "./utils/context.js";
16
+
17
+ export { populateLocalStorageWithCredentials } from "./fixtures/user.js";
12
18
 
13
19
  // Enable experimental service worker support
14
20
  // See https://playwright.dev/docs/service-workers-experimental#how-to-enable
@@ -68,32 +74,7 @@ export const test = base.extend<TestFixtures>({
68
74
  labsFlags: async ({}, use) => use([]),
69
75
  disablePresence: async ({}, use) => use(false),
70
76
  page: async ({ homeserver, context, page, config, labsFlags, disablePresence }, use) => {
71
- await context.route(`http://localhost:8080/config.json*`, async (route) => {
72
- const json = {
73
- ...CONFIG_JSON,
74
- ...config,
75
- default_server_config: {
76
- "m.homeserver": {
77
- base_url: homeserver.baseUrl,
78
- },
79
- ...config.default_server_config,
80
- },
81
- };
82
- json["features"] = {
83
- ...json["features"],
84
- // Enable the lab features
85
- ...labsFlags.reduce<NonNullable<(typeof CONFIG_JSON)["features"]>>((obj, flag) => {
86
- obj[flag] = true;
87
- return obj;
88
- }, {}),
89
- };
90
- if (disablePresence) {
91
- json["enable_presence_by_hs_url"] = {
92
- [homeserver.baseUrl]: false,
93
- };
94
- }
95
- await route.fulfill({ json });
96
- });
77
+ await routeConfigJson(context, homeserver.baseUrl, config, labsFlags, disablePresence);
97
78
  await use(page);
98
79
  },
99
80
  });
@@ -302,7 +302,7 @@ export class StartedMatrixAuthenticationServiceContainer extends AbstractStarted
302
302
  password: string,
303
303
  displayName?: string,
304
304
  admin = false,
305
- ): Promise<Credentials> {
305
+ ): Promise<Omit<Credentials, "homeserverBaseUrl">> {
306
306
  const userId = await this.manageRegisterUser(username, password, displayName, admin);
307
307
  const { deviceId, accessToken } = await this.manageIssueCompatibilityToken(username, admin);
308
308
 
@@ -319,11 +319,16 @@ export class StartedMatrixAuthenticationServiceContainer extends AbstractStarted
319
319
 
320
320
  /**
321
321
  * Registers a user
322
+ *
322
323
  * @param username - the username of the user to register
323
324
  * @param password - the password of the user to register
324
325
  * @param displayName - optional display name to set on the newly registered user
325
326
  */
326
- public async registerUser(username: string, password: string, displayName?: string): Promise<Credentials> {
327
+ public async registerUser(
328
+ username: string,
329
+ password: string,
330
+ displayName?: string,
331
+ ): Promise<Omit<Credentials, "homeserverBaseUrl">> {
327
332
  return this.registerUserInternal(username, password, displayName, false);
328
333
  }
329
334
 
@@ -389,6 +389,7 @@ export class StartedSynapseContainer extends AbstractStartedContainer implements
389
389
 
390
390
  return {
391
391
  homeServer: data.home_server || data.user_id.split(":").slice(1).join(":"),
392
+ homeserverBaseUrl: this.baseUrl,
392
393
  accessToken: data.access_token,
393
394
  userId: data.user_id,
394
395
  deviceId: data.device_id,
@@ -433,7 +434,10 @@ export class StartedSynapseContainer extends AbstractStartedContainer implements
433
434
  * @param password - login password
434
435
  */
435
436
  public async loginUser(userId: string, password: string): Promise<Credentials> {
436
- return this.csApi.loginUser(userId, password);
437
+ return {
438
+ ...(await this.csApi.loginUser(userId, password)),
439
+ homeserverBaseUrl: this.baseUrl,
440
+ };
437
441
  }
438
442
 
439
443
  /**
@@ -480,8 +484,9 @@ export class StartedSynapseWithMasContainer extends StartedSynapseContainer {
480
484
  * @param password - the password of the user to register
481
485
  * @param displayName - optional display name to set on the newly registered user
482
486
  */
483
- public registerUser(username: string, password: string, displayName?: string): Promise<Credentials> {
484
- return this.mas.registerUser(username, password, displayName);
487
+ public async registerUser(username: string, password: string, displayName?: string): Promise<Credentials> {
488
+ const registered = await this.mas.registerUser(username, password, displayName);
489
+ return { ...registered, homeserverBaseUrl: this.baseUrl };
485
490
  }
486
491
 
487
492
  /**
package/src/utils/api.ts CHANGED
@@ -64,10 +64,16 @@ export class Api {
64
64
  * Credentials for a user.
65
65
  */
66
66
  export interface Credentials {
67
+ /** The base URL of the homeserver's CS API. */
68
+ homeserverBaseUrl: string;
69
+
67
70
  accessToken: string;
68
71
  userId: string;
69
72
  deviceId: string;
73
+
74
+ /** The domain part of the user's matrix ID. */
70
75
  homeServer: string;
76
+
71
77
  password: string | null; // null for password-less users
72
78
  displayName?: string;
73
79
  username: string; // the localpart of the userId
@@ -86,7 +92,7 @@ export class ClientServerApi extends Api {
86
92
  * @param userId - The user ID to register.
87
93
  * @param password - The password to use for the user.
88
94
  */
89
- public async loginUser(userId: string, password: string): Promise<Credentials> {
95
+ public async loginUser(userId: string, password: string): Promise<Omit<Credentials, "homeserverBaseUrl">> {
90
96
  const json = await this.request<{
91
97
  access_token: string;
92
98
  user_id: string;
@@ -0,0 +1,71 @@
1
+ /*
2
+ Copyright 2025 New Vector Ltd.
3
+
4
+ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
5
+ Please see LICENSE files in the repository root for full details.
6
+ */
7
+
8
+ import { BrowserContext, Page } from "@playwright/test";
9
+
10
+ import { Config, CONFIG_JSON } from "../index.js";
11
+
12
+ /** Construct a suitable config.json for the given homeserver
13
+ *
14
+ * @param homeserverBaseUrl - The `baseUrl` of the homeserver that the client should be configured to connect to.
15
+ * @param additionalConfig - Additional config to add to the default config.json.
16
+ * @param labsFlags - Lab flags to enable in the client.
17
+ * @param disablePresence - Whether to disable presence for the given homeserver.
18
+ */
19
+ export function buildConfigJson(
20
+ homeserverBaseUrl: string,
21
+ additionalConfig: Partial<Config> = {},
22
+ labsFlags: string[] = [],
23
+ disablePresence: boolean = false,
24
+ ): Partial<Config> {
25
+ const json = {
26
+ ...CONFIG_JSON,
27
+ ...additionalConfig,
28
+ default_server_config: {
29
+ "m.homeserver": {
30
+ base_url: homeserverBaseUrl,
31
+ },
32
+ ...additionalConfig.default_server_config,
33
+ },
34
+ };
35
+ json["features"] = {
36
+ ...json["features"],
37
+ // Enable the lab features
38
+ ...labsFlags.reduce<NonNullable<(typeof CONFIG_JSON)["features"]>>((obj, flag) => {
39
+ obj[flag] = true;
40
+ return obj;
41
+ }, {}),
42
+ };
43
+ if (disablePresence) {
44
+ json["enable_presence_by_hs_url"] = {
45
+ [homeserverBaseUrl]: false,
46
+ };
47
+ }
48
+ return json;
49
+ }
50
+
51
+ /**
52
+ * Add a route to the browser context/page which will serve a suitable config.json for the given homeserver.
53
+ *
54
+ * @param context - The browser context or page to route the config.json to.
55
+ * @param homeserverBaseUrl - The `baseUrl` of the homeserver that the client should be configured to connect to.
56
+ * @param additionalConfig - Additional config to add to the default config.json.
57
+ * @param labsFlags - Lab flags to enable in the client.
58
+ * @param disablePresence - Whether to disable presence for the given homeserver.
59
+ */
60
+ export async function routeConfigJson(
61
+ context: BrowserContext | Page,
62
+ homeserverBaseUrl: string,
63
+ additionalConfig: Partial<Config> = {},
64
+ labsFlags: string[] = [],
65
+ disablePresence: boolean = false,
66
+ ): Promise<void> {
67
+ await context.route(`http://localhost:8080/config.json*`, async (route) => {
68
+ const json = buildConfigJson(homeserverBaseUrl, additionalConfig, labsFlags, disablePresence);
69
+ await route.fulfill({ json });
70
+ });
71
+ }
@@ -0,0 +1,38 @@
1
+ /*
2
+ Copyright 2025 New Vector Ltd.
3
+
4
+ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
5
+ Please see LICENSE files in the repository root for full details.
6
+ */
7
+
8
+ import { Browser } from "playwright-core";
9
+ import { Page } from "@playwright/test";
10
+
11
+ import { Credentials } from "./api.js";
12
+ import { Config } from "../index.js";
13
+ import { routeConfigJson } from "./config_json.js";
14
+ import { populateLocalStorageWithCredentials } from "../fixtures/user.js";
15
+
16
+ /** Create a new instance of the application, in a separate browser context, using the given credentials.
17
+ *
18
+ * @param browser - the browser to use
19
+ * @param credentials - the credentials to use for the new instance
20
+ * @param additionalConfig - additional config for the `config.json` for the new instance
21
+ * @param labsFlags - additional labs flags for the `config.json` for the new instance
22
+ * @param disablePresence - whether to disable presence for the new instance
23
+ */
24
+ export async function createNewInstance(
25
+ browser: Browser,
26
+ credentials: Credentials,
27
+ additionalConfig: Partial<Config> = {},
28
+ labsFlags: string[] = [],
29
+ disablePresence: boolean = false,
30
+ ): Promise<Page> {
31
+ const context = await browser.newContext();
32
+ await routeConfigJson(context, credentials.homeserverBaseUrl, additionalConfig, labsFlags, disablePresence);
33
+ const page = await context.newPage();
34
+ await populateLocalStorageWithCredentials(page, credentials);
35
+ await page.goto("/");
36
+ await page.waitForSelector(".mx_MatrixChat", { timeout: 30000 });
37
+ return page;
38
+ }