@element-hq/element-web-playwright-common 3.0.0 → 3.1.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.
- package/lib/fixtures/toasts.d.ts +64 -0
- package/lib/fixtures/toasts.d.ts.map +1 -0
- package/lib/fixtures/toasts.js +97 -0
- package/lib/fixtures/user.d.ts +11 -0
- package/lib/fixtures/user.d.ts.map +1 -1
- package/lib/fixtures/user.js +4 -1
- package/lib/index.d.ts +11 -0
- package/lib/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/project.json +7 -1
- package/src/fixtures/toasts.ts +109 -0
- package/src/fixtures/user.ts +4 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { type Locator, type Page } from "@playwright/test";
|
|
2
|
+
export declare const test: import("playwright/test").TestType<import("playwright/test").PlaywrightTestArgs & import("playwright/test").PlaywrightTestOptions & {
|
|
3
|
+
axe: import("@axe-core/playwright").AxeBuilder;
|
|
4
|
+
} & import("./services.js").TestFixtures & {
|
|
5
|
+
/**
|
|
6
|
+
* Convenience functions for handling toasts.
|
|
7
|
+
*/
|
|
8
|
+
toasts: Toasts;
|
|
9
|
+
}, import("playwright/test").PlaywrightWorkerArgs & import("playwright/test").PlaywrightWorkerOptions & import("./services.js").WorkerOptions & import("./services.js").Services>;
|
|
10
|
+
declare class Toasts {
|
|
11
|
+
readonly page: Page;
|
|
12
|
+
constructor(page: Page);
|
|
13
|
+
/**
|
|
14
|
+
* Assert that no toasts exist
|
|
15
|
+
*/
|
|
16
|
+
assertNoToasts(): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Assert that a toast with the given title exists, and return it
|
|
19
|
+
*
|
|
20
|
+
* @param title - Expected title of the toast
|
|
21
|
+
* @param timeout - Time to retry the assertion for in milliseconds.
|
|
22
|
+
* Defaults to `timeout` in `TestConfig.expect`.
|
|
23
|
+
* @returns the Locator for the matching toast
|
|
24
|
+
*/
|
|
25
|
+
getToast(title: string, timeout?: number): Promise<Locator>;
|
|
26
|
+
/**
|
|
27
|
+
* Find a toast with the given title, if it exists.
|
|
28
|
+
*
|
|
29
|
+
* @param title - Title of the toast.
|
|
30
|
+
* @returns the Locator for the matching toast, or an empty locator if it
|
|
31
|
+
* doesn't exist.
|
|
32
|
+
*/
|
|
33
|
+
getToastIfExists(title: string): Locator;
|
|
34
|
+
/**
|
|
35
|
+
* Accept a toast with the given title. Only works for the first toast in
|
|
36
|
+
* the stack.
|
|
37
|
+
*
|
|
38
|
+
* @param title - Expected title of the toast
|
|
39
|
+
*/
|
|
40
|
+
acceptToast(title: string): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Accept a toast with the given title, if it exists. Only works for the
|
|
43
|
+
* first toast in the stack.
|
|
44
|
+
*
|
|
45
|
+
* @param title - Title of the toast
|
|
46
|
+
*/
|
|
47
|
+
acceptToastIfExists(title: string): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Reject a toast with the given title. Only works for the first toast in
|
|
50
|
+
* the stack.
|
|
51
|
+
*
|
|
52
|
+
* @param title - Expected title of the toast
|
|
53
|
+
*/
|
|
54
|
+
rejectToast(title: string): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Reject a toast with the given title, if it exists. Only works for the
|
|
57
|
+
* first toast in the stack.
|
|
58
|
+
*
|
|
59
|
+
* @param title - Title of the toast
|
|
60
|
+
*/
|
|
61
|
+
rejectToastIfExists(title: string): Promise<void>;
|
|
62
|
+
}
|
|
63
|
+
export {};
|
|
64
|
+
//# sourceMappingURL=toasts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toasts.d.ts","sourceRoot":"","sources":["../../src/fixtures/toasts.ts"],"names":[],"mappings":"AAOA,OAAO,EAAU,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAQnE,eAAO,MAAM,IAAI;;;IACb;;OAEG;YACK,MAAM;iLAMhB,CAAC;AAEH,cAAM,MAAM;aAC2B,IAAI,EAAE,IAAI;gBAAV,IAAI,EAAE,IAAI;IAE7C;;OAEG;IACU,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5C;;;;;;;OAOG;IACU,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMxE;;;;;;OAMG;IACI,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAI/C;;;;;OAKG;IACU,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD;;;;;OAKG;IACU,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9D;;;;;OAKG;IACU,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtD;;;;;OAKG;IACU,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAMjE"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Element Creations Ltd.
|
|
3
|
+
*
|
|
4
|
+
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
|
5
|
+
* Please see LICENSE files in the repository root for full details.
|
|
6
|
+
*/
|
|
7
|
+
import { expect } from "@playwright/test";
|
|
8
|
+
// We want to avoid using `mergeTests` in index.ts because it drops useful type
|
|
9
|
+
// information about the fixtures. Instead, we add `services` into our fixture
|
|
10
|
+
// suite by using its `test` as a base, so that there is a linear hierarchy.
|
|
11
|
+
import { test as base } from "./services.js";
|
|
12
|
+
// This fixture provides convenient handling of Element Web's toasts.
|
|
13
|
+
export const test = base.extend({
|
|
14
|
+
toasts: async ({ page }, use) => {
|
|
15
|
+
const toasts = new Toasts(page);
|
|
16
|
+
await use(toasts);
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
class Toasts {
|
|
20
|
+
page;
|
|
21
|
+
constructor(page) {
|
|
22
|
+
this.page = page;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Assert that no toasts exist
|
|
26
|
+
*/
|
|
27
|
+
async assertNoToasts() {
|
|
28
|
+
await expect(this.page.locator(".mx_Toast_toast")).not.toBeVisible();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Assert that a toast with the given title exists, and return it
|
|
32
|
+
*
|
|
33
|
+
* @param title - Expected title of the toast
|
|
34
|
+
* @param timeout - Time to retry the assertion for in milliseconds.
|
|
35
|
+
* Defaults to `timeout` in `TestConfig.expect`.
|
|
36
|
+
* @returns the Locator for the matching toast
|
|
37
|
+
*/
|
|
38
|
+
async getToast(title, timeout) {
|
|
39
|
+
const toast = this.getToastIfExists(title);
|
|
40
|
+
await expect(toast).toBeVisible({ timeout });
|
|
41
|
+
return toast;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Find a toast with the given title, if it exists.
|
|
45
|
+
*
|
|
46
|
+
* @param title - Title of the toast.
|
|
47
|
+
* @returns the Locator for the matching toast, or an empty locator if it
|
|
48
|
+
* doesn't exist.
|
|
49
|
+
*/
|
|
50
|
+
getToastIfExists(title) {
|
|
51
|
+
return this.page.locator(".mx_Toast_toast", { hasText: title }).first();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Accept a toast with the given title. Only works for the first toast in
|
|
55
|
+
* the stack.
|
|
56
|
+
*
|
|
57
|
+
* @param title - Expected title of the toast
|
|
58
|
+
*/
|
|
59
|
+
async acceptToast(title) {
|
|
60
|
+
const toast = await this.getToast(title);
|
|
61
|
+
await toast.locator('.mx_Toast_buttons button[data-kind="primary"]').click();
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Accept a toast with the given title, if it exists. Only works for the
|
|
65
|
+
* first toast in the stack.
|
|
66
|
+
*
|
|
67
|
+
* @param title - Title of the toast
|
|
68
|
+
*/
|
|
69
|
+
async acceptToastIfExists(title) {
|
|
70
|
+
const toast = this.getToastIfExists(title).locator('.mx_Toast_buttons button[data-kind="primary"]');
|
|
71
|
+
if ((await toast.count()) > 0) {
|
|
72
|
+
await toast.click();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Reject a toast with the given title. Only works for the first toast in
|
|
77
|
+
* the stack.
|
|
78
|
+
*
|
|
79
|
+
* @param title - Expected title of the toast
|
|
80
|
+
*/
|
|
81
|
+
async rejectToast(title) {
|
|
82
|
+
const toast = await this.getToast(title);
|
|
83
|
+
await toast.locator('.mx_Toast_buttons button[data-kind="secondary"]').click();
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Reject a toast with the given title, if it exists. Only works for the
|
|
87
|
+
* first toast in the stack.
|
|
88
|
+
*
|
|
89
|
+
* @param title - Title of the toast
|
|
90
|
+
*/
|
|
91
|
+
async rejectToastIfExists(title) {
|
|
92
|
+
const toast = this.getToastIfExists(title).locator('.mx_Toast_buttons button[data-kind="secondary"]');
|
|
93
|
+
if ((await toast.count()) > 0) {
|
|
94
|
+
await toast.click();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
package/lib/fixtures/user.d.ts
CHANGED
|
@@ -5,6 +5,17 @@ export declare function populateLocalStorageWithCredentials(page: Page, credenti
|
|
|
5
5
|
export declare const test: import("playwright/test").TestType<import("playwright/test").PlaywrightTestArgs & import("playwright/test").PlaywrightTestOptions & {
|
|
6
6
|
axe: import("@axe-core/playwright").AxeBuilder;
|
|
7
7
|
} & import("./services.js").TestFixtures & {
|
|
8
|
+
toasts: {
|
|
9
|
+
readonly page: Page;
|
|
10
|
+
assertNoToasts(): Promise<void>;
|
|
11
|
+
getToast(title: string, timeout?: number): Promise<import("playwright-core").Locator>;
|
|
12
|
+
getToastIfExists(title: string): import("playwright-core").Locator;
|
|
13
|
+
acceptToast(title: string): Promise<void>;
|
|
14
|
+
acceptToastIfExists(title: string): Promise<void>;
|
|
15
|
+
rejectToast(title: string): Promise<void>;
|
|
16
|
+
rejectToastIfExists(title: string): Promise<void>;
|
|
17
|
+
};
|
|
18
|
+
} & {
|
|
8
19
|
/**
|
|
9
20
|
* The displayname to use for the user registered in {@link #credentials}.
|
|
10
21
|
*
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/fixtures/user.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAO7C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,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;iLA+BnB,CAAC"}
|
package/lib/fixtures/user.js
CHANGED
|
@@ -6,7 +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 { sample, uniqueId } from "lodash-es";
|
|
9
|
-
|
|
9
|
+
// We want to avoid using `mergeTests` in index.ts because it drops useful type
|
|
10
|
+
// information about the fixtures. Instead, we add `toasts` into our fixture
|
|
11
|
+
// suite by using its `test` as a base, so that there is a linear hierarchy.
|
|
12
|
+
import { test as base } from "./toasts.js";
|
|
10
13
|
/** Adds an initScript to the given page which will populate localStorage appropriately so that Element will use the given credentials. */
|
|
11
14
|
export async function populateLocalStorageWithCredentials(page, credentials) {
|
|
12
15
|
await page.addInitScript(({ credentials }) => {
|
package/lib/index.d.ts
CHANGED
|
@@ -41,6 +41,17 @@ export interface TestFixtures {
|
|
|
41
41
|
export declare const test: import("playwright/test").TestType<import("playwright/test").PlaywrightTestArgs & import("playwright/test").PlaywrightTestOptions & {
|
|
42
42
|
axe: import("@axe-core/playwright").AxeBuilder;
|
|
43
43
|
} & import("./fixtures/services.js").TestFixtures & {
|
|
44
|
+
toasts: {
|
|
45
|
+
readonly page: import("playwright-core").Page;
|
|
46
|
+
assertNoToasts(): Promise<void>;
|
|
47
|
+
getToast(title: string, timeout?: number): Promise<import("playwright-core").Locator>;
|
|
48
|
+
getToastIfExists(title: string): import("playwright-core").Locator;
|
|
49
|
+
acceptToast(title: string): Promise<void>;
|
|
50
|
+
acceptToastIfExists(title: string): Promise<void>;
|
|
51
|
+
rejectToast(title: string): Promise<void>;
|
|
52
|
+
rejectToastIfExists(title: string): Promise<void>;
|
|
53
|
+
};
|
|
54
|
+
} & {
|
|
44
55
|
displayName?: string;
|
|
45
56
|
credentials: import("./utils/api.js").Credentials;
|
|
46
57
|
pageWithCredentials: import("playwright-core").Page;
|
package/lib/index.d.ts.map
CHANGED
|
@@ -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;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;IACzB;;;;;;;;OAQG;IACH,kBAAkB,EAAE,OAAO,CAAC;CAC/B;AAED,eAAO,MAAM,IAAI
|
|
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;IACzB;;;;;;;;OAQG;IACH,kBAAkB,EAAE,OAAO,CAAC;CAC/B;AAED,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;kNAmBf,CAAC;AAEH,OAAO,EAAE,MAAM,EAAE,KAAK,wBAAwB,EAAE,MAAM,mBAAmB,CAAC"}
|
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": "3.
|
|
4
|
+
"version": "3.1.0",
|
|
5
5
|
"license": "SEE LICENSE IN README.md",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
21
|
"prepack": "nx build:playwright",
|
|
22
|
-
"lint:types": "
|
|
22
|
+
"lint:types": "nx lint:types"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@element-hq/element-web-module-api": "
|
|
25
|
+
"@element-hq/element-web-module-api": "workspace:*",
|
|
26
26
|
"@types/lodash-es": "^4.17.12",
|
|
27
27
|
"typescript": "^5.8.2",
|
|
28
28
|
"wait-on": "^9.0.4"
|
package/project.json
CHANGED
|
@@ -8,7 +8,13 @@
|
|
|
8
8
|
"command": "tsc",
|
|
9
9
|
"inputs": ["src"],
|
|
10
10
|
"outputs": ["{projectRoot}/lib"],
|
|
11
|
-
"options": { "cwd": "packages/playwright-common" }
|
|
11
|
+
"options": { "cwd": "packages/playwright-common" },
|
|
12
|
+
"dependsOn": ["^build"]
|
|
13
|
+
},
|
|
14
|
+
"lint:types": {
|
|
15
|
+
"command": "pnpm exec tsc --noEmit",
|
|
16
|
+
"options": { "cwd": "packages/playwright-common" },
|
|
17
|
+
"dependsOn": ["^build"]
|
|
12
18
|
},
|
|
13
19
|
"docker:prebuild": {
|
|
14
20
|
"cache": true,
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Element Creations Ltd.
|
|
3
|
+
*
|
|
4
|
+
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
|
5
|
+
* Please see LICENSE files in the repository root for full details.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { expect, type Locator, type Page } from "@playwright/test";
|
|
9
|
+
|
|
10
|
+
// We want to avoid using `mergeTests` in index.ts because it drops useful type
|
|
11
|
+
// information about the fixtures. Instead, we add `services` into our fixture
|
|
12
|
+
// suite by using its `test` as a base, so that there is a linear hierarchy.
|
|
13
|
+
import { test as base } from "./services.js";
|
|
14
|
+
|
|
15
|
+
// This fixture provides convenient handling of Element Web's toasts.
|
|
16
|
+
export const test = base.extend<{
|
|
17
|
+
/**
|
|
18
|
+
* Convenience functions for handling toasts.
|
|
19
|
+
*/
|
|
20
|
+
toasts: Toasts;
|
|
21
|
+
}>({
|
|
22
|
+
toasts: async ({ page }, use) => {
|
|
23
|
+
const toasts = new Toasts(page);
|
|
24
|
+
await use(toasts);
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
class Toasts {
|
|
29
|
+
public constructor(public readonly page: Page) {}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Assert that no toasts exist
|
|
33
|
+
*/
|
|
34
|
+
public async assertNoToasts(): Promise<void> {
|
|
35
|
+
await expect(this.page.locator(".mx_Toast_toast")).not.toBeVisible();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Assert that a toast with the given title exists, and return it
|
|
40
|
+
*
|
|
41
|
+
* @param title - Expected title of the toast
|
|
42
|
+
* @param timeout - Time to retry the assertion for in milliseconds.
|
|
43
|
+
* Defaults to `timeout` in `TestConfig.expect`.
|
|
44
|
+
* @returns the Locator for the matching toast
|
|
45
|
+
*/
|
|
46
|
+
public async getToast(title: string, timeout?: number): Promise<Locator> {
|
|
47
|
+
const toast = this.getToastIfExists(title);
|
|
48
|
+
await expect(toast).toBeVisible({ timeout });
|
|
49
|
+
return toast;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Find a toast with the given title, if it exists.
|
|
54
|
+
*
|
|
55
|
+
* @param title - Title of the toast.
|
|
56
|
+
* @returns the Locator for the matching toast, or an empty locator if it
|
|
57
|
+
* doesn't exist.
|
|
58
|
+
*/
|
|
59
|
+
public getToastIfExists(title: string): Locator {
|
|
60
|
+
return this.page.locator(".mx_Toast_toast", { hasText: title }).first();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Accept a toast with the given title. Only works for the first toast in
|
|
65
|
+
* the stack.
|
|
66
|
+
*
|
|
67
|
+
* @param title - Expected title of the toast
|
|
68
|
+
*/
|
|
69
|
+
public async acceptToast(title: string): Promise<void> {
|
|
70
|
+
const toast = await this.getToast(title);
|
|
71
|
+
await toast.locator('.mx_Toast_buttons button[data-kind="primary"]').click();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Accept a toast with the given title, if it exists. Only works for the
|
|
75
|
+
* first toast in the stack.
|
|
76
|
+
*
|
|
77
|
+
* @param title - Title of the toast
|
|
78
|
+
*/
|
|
79
|
+
public async acceptToastIfExists(title: string): Promise<void> {
|
|
80
|
+
const toast = this.getToastIfExists(title).locator('.mx_Toast_buttons button[data-kind="primary"]');
|
|
81
|
+
if ((await toast.count()) > 0) {
|
|
82
|
+
await toast.click();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Reject a toast with the given title. Only works for the first toast in
|
|
88
|
+
* the stack.
|
|
89
|
+
*
|
|
90
|
+
* @param title - Expected title of the toast
|
|
91
|
+
*/
|
|
92
|
+
public async rejectToast(title: string): Promise<void> {
|
|
93
|
+
const toast = await this.getToast(title);
|
|
94
|
+
await toast.locator('.mx_Toast_buttons button[data-kind="secondary"]').click();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Reject a toast with the given title, if it exists. Only works for the
|
|
99
|
+
* first toast in the stack.
|
|
100
|
+
*
|
|
101
|
+
* @param title - Title of the toast
|
|
102
|
+
*/
|
|
103
|
+
public async rejectToastIfExists(title: string): Promise<void> {
|
|
104
|
+
const toast = this.getToastIfExists(title).locator('.mx_Toast_buttons button[data-kind="secondary"]');
|
|
105
|
+
if ((await toast.count()) > 0) {
|
|
106
|
+
await toast.click();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
package/src/fixtures/user.ts
CHANGED
|
@@ -9,7 +9,10 @@ Please see LICENSE files in the repository root for full details.
|
|
|
9
9
|
import { type Page } from "@playwright/test";
|
|
10
10
|
import { sample, uniqueId } from "lodash-es";
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
// We want to avoid using `mergeTests` in index.ts because it drops useful type
|
|
13
|
+
// information about the fixtures. Instead, we add `toasts` into our fixture
|
|
14
|
+
// suite by using its `test` as a base, so that there is a linear hierarchy.
|
|
15
|
+
import { test as base } from "./toasts.js";
|
|
13
16
|
import { type Credentials } from "../utils/api.js";
|
|
14
17
|
|
|
15
18
|
/** Adds an initScript to the given page which will populate localStorage appropriately so that Element will use the given credentials. */
|