@element-hq/element-web-playwright-common 3.1.0 → 4.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.
- package/Dockerfile +8 -1
- package/lib/fixtures/toasts.d.ts +35 -26
- package/lib/fixtures/toasts.d.ts.map +1 -1
- package/lib/fixtures/toasts.js +73 -46
- package/lib/fixtures/user.d.ts +2 -2
- package/lib/index.d.ts +2 -2
- package/package.json +3 -3
- package/playwright-screenshots.sh +7 -4
- package/src/fixtures/toasts.ts +98 -44
- package/tsconfig.json +1 -0
package/Dockerfile
CHANGED
|
@@ -6,10 +6,17 @@ ARG PLAYWRIGHT_VERSION
|
|
|
6
6
|
WORKDIR /work
|
|
7
7
|
|
|
8
8
|
# fonts-dejavu is needed for the same RTL rendering as on CI
|
|
9
|
-
RUN apt-get update &&
|
|
9
|
+
RUN apt-get update && \
|
|
10
|
+
apt-get -y install docker.io fonts-dejavu && \
|
|
11
|
+
apt-get purge -y --auto-remove && \
|
|
12
|
+
rm -rf /var/lib/apt/lists/*
|
|
13
|
+
|
|
10
14
|
# Install the matching playwright runtime, the docker image only includes browsers
|
|
11
15
|
RUN npm i -g playwright@${PLAYWRIGHT_VERSION}
|
|
12
16
|
|
|
17
|
+
# switch to pwuser
|
|
18
|
+
USER 1001:1001
|
|
19
|
+
|
|
13
20
|
COPY docker-entrypoint.sh /docker-entrypoint.sh
|
|
14
21
|
|
|
15
22
|
# We use `docker-init` as PID 1, which means that the container shuts down correctly on SIGTERM.
|
package/lib/fixtures/toasts.d.ts
CHANGED
|
@@ -11,52 +11,61 @@ declare class Toasts {
|
|
|
11
11
|
readonly page: Page;
|
|
12
12
|
constructor(page: Page);
|
|
13
13
|
/**
|
|
14
|
-
* Assert that no toasts exist
|
|
14
|
+
* Assert that no toasts exist.
|
|
15
15
|
*/
|
|
16
16
|
assertNoToasts(): Promise<void>;
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* Return the toast with the supplied title. Fail or return null if it does
|
|
19
|
+
* not exist.
|
|
19
20
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
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.
|
|
21
|
+
* If `required` is false, you should supply a relatively short `timeout`
|
|
22
|
+
* (e.g. 2000, meaning 2 seconds) to prevent your test taking too long.
|
|
28
23
|
*
|
|
29
|
-
* @param title -
|
|
30
|
-
* @
|
|
31
|
-
*
|
|
24
|
+
* @param title - Expected title of the toast.
|
|
25
|
+
* @param timeout - Time in ms before we give up and decide the toast does
|
|
26
|
+
* not exist. If `required` is true, defaults to `timeout`
|
|
27
|
+
* in `TestConfig.expect`. Otherwise, defaults to 2000 (2
|
|
28
|
+
* seconds).
|
|
29
|
+
* @param required - If true, fail the test (throw an exception) if the
|
|
30
|
+
* toast is not visible. Otherwise, just return null if
|
|
31
|
+
* the toast is not visible.
|
|
32
|
+
* @returns the Locator for the matching toast, or null if it is not
|
|
33
|
+
* visible. (null will only be returned if `required` is false.)
|
|
32
34
|
*/
|
|
33
|
-
|
|
35
|
+
getToast(title: string, timeout?: number, required?: true): Promise<Locator>;
|
|
36
|
+
getToast(title: string, timeout: number | undefined, required: false): Promise<Locator | null>;
|
|
34
37
|
/**
|
|
35
|
-
* Accept
|
|
36
|
-
*
|
|
38
|
+
* Accept the toast with the supplied title, or fail if it does not exist.
|
|
39
|
+
*
|
|
40
|
+
* Only works if this toast is at the top of the stack of toasts.
|
|
37
41
|
*
|
|
38
|
-
* @param title - Expected title of the toast
|
|
42
|
+
* @param title - Expected title of the toast.
|
|
39
43
|
*/
|
|
40
44
|
acceptToast(title: string): Promise<void>;
|
|
41
45
|
/**
|
|
42
|
-
* Accept
|
|
43
|
-
*
|
|
46
|
+
* Accept the toast with the supplied title, if it exists, or return after 2
|
|
47
|
+
* seconds if it is not found.
|
|
44
48
|
*
|
|
45
|
-
*
|
|
49
|
+
* Only works if this toast is at the top of the stack of toasts.
|
|
50
|
+
*
|
|
51
|
+
* @param title - Expected title of the toast.
|
|
46
52
|
*/
|
|
47
53
|
acceptToastIfExists(title: string): Promise<void>;
|
|
48
54
|
/**
|
|
49
|
-
* Reject
|
|
50
|
-
*
|
|
55
|
+
* Reject the toast with the supplied title, or fail if it does not exist.
|
|
56
|
+
*
|
|
57
|
+
* Only works if this toast is at the top of the stack of toasts.
|
|
51
58
|
*
|
|
52
|
-
* @param title - Expected title of the toast
|
|
59
|
+
* @param title - Expected title of the toast.
|
|
53
60
|
*/
|
|
54
61
|
rejectToast(title: string): Promise<void>;
|
|
55
62
|
/**
|
|
56
|
-
* Reject
|
|
57
|
-
*
|
|
63
|
+
* Reject the toast with the supplied title, if it exists, or return after 2
|
|
64
|
+
* seconds if it is not found.
|
|
65
|
+
*
|
|
66
|
+
* Only works if this toast is at the top of the stack of toasts.
|
|
58
67
|
*
|
|
59
|
-
* @param title -
|
|
68
|
+
* @param title - Expected title of the toast.
|
|
60
69
|
*/
|
|
61
70
|
rejectToastIfExists(title: string): Promise<void>;
|
|
62
71
|
}
|
|
@@ -1 +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
|
|
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;;;;;;;;;;;;;;;;;OAiBG;IACU,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;IAC5E,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAqB3G;;;;;;OAMG;IACU,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD;;;;;;;OAOG;IACU,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D;;;;;;OAMG;IACU,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD;;;;;;;OAOG;IACU,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGjE"}
|
package/lib/fixtures/toasts.js
CHANGED
|
@@ -22,76 +22,103 @@ class Toasts {
|
|
|
22
22
|
this.page = page;
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
|
-
* Assert that no toasts exist
|
|
25
|
+
* Assert that no toasts exist.
|
|
26
26
|
*/
|
|
27
27
|
async assertNoToasts() {
|
|
28
28
|
await expect(this.page.locator(".mx_Toast_toast")).not.toBeVisible();
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
async getToast(title, timeout, required = true) {
|
|
31
|
+
const toast = this.page.locator(".mx_Toast_toast", { hasText: title }).first();
|
|
32
|
+
if (required) {
|
|
33
|
+
await expect(toast).toBeVisible({ timeout });
|
|
34
|
+
return toast;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// If we don't set a timeout, waitFor will wait forever. Since
|
|
38
|
+
// required is false, we definitely don't want to wait forever.
|
|
39
|
+
timeout = timeout ?? 2000;
|
|
40
|
+
try {
|
|
41
|
+
await toast.waitFor({ state: "visible", timeout });
|
|
42
|
+
return toast;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
42
48
|
}
|
|
43
49
|
/**
|
|
44
|
-
*
|
|
50
|
+
* Accept the toast with the supplied title, or fail if it does not exist.
|
|
45
51
|
*
|
|
46
|
-
*
|
|
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.
|
|
52
|
+
* Only works if this toast is at the top of the stack of toasts.
|
|
56
53
|
*
|
|
57
|
-
* @param title - Expected title of the toast
|
|
54
|
+
* @param title - Expected title of the toast.
|
|
58
55
|
*/
|
|
59
56
|
async acceptToast(title) {
|
|
60
|
-
|
|
61
|
-
await toast.locator('.mx_Toast_buttons button[data-kind="primary"]').click();
|
|
57
|
+
return await clickToastButton(this, title, "primary");
|
|
62
58
|
}
|
|
63
59
|
/**
|
|
64
|
-
* Accept
|
|
65
|
-
*
|
|
60
|
+
* Accept the toast with the supplied title, if it exists, or return after 2
|
|
61
|
+
* seconds if it is not found.
|
|
62
|
+
*
|
|
63
|
+
* Only works if this toast is at the top of the stack of toasts.
|
|
66
64
|
*
|
|
67
|
-
* @param title -
|
|
65
|
+
* @param title - Expected title of the toast.
|
|
68
66
|
*/
|
|
69
67
|
async acceptToastIfExists(title) {
|
|
70
|
-
|
|
71
|
-
if ((await toast.count()) > 0) {
|
|
72
|
-
await toast.click();
|
|
73
|
-
}
|
|
68
|
+
return await clickToastButton(this, title, "primary", 2000, false);
|
|
74
69
|
}
|
|
75
70
|
/**
|
|
76
|
-
* Reject
|
|
77
|
-
*
|
|
71
|
+
* Reject the toast with the supplied title, or fail if it does not exist.
|
|
72
|
+
*
|
|
73
|
+
* Only works if this toast is at the top of the stack of toasts.
|
|
78
74
|
*
|
|
79
|
-
* @param title - Expected title of the toast
|
|
75
|
+
* @param title - Expected title of the toast.
|
|
80
76
|
*/
|
|
81
77
|
async rejectToast(title) {
|
|
82
|
-
|
|
83
|
-
await toast.locator('.mx_Toast_buttons button[data-kind="secondary"]').click();
|
|
78
|
+
return await clickToastButton(this, title, "secondary");
|
|
84
79
|
}
|
|
85
80
|
/**
|
|
86
|
-
* Reject
|
|
87
|
-
*
|
|
81
|
+
* Reject the toast with the supplied title, if it exists, or return after 2
|
|
82
|
+
* seconds if it is not found.
|
|
88
83
|
*
|
|
89
|
-
*
|
|
84
|
+
* Only works if this toast is at the top of the stack of toasts.
|
|
85
|
+
*
|
|
86
|
+
* @param title - Expected title of the toast.
|
|
90
87
|
*/
|
|
91
88
|
async rejectToastIfExists(title) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
return await clickToastButton(this, title, "secondary", 2000, false);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Find the toast with the supplied title and click a button on it.
|
|
94
|
+
*
|
|
95
|
+
* Only works if this toast is at the top of the stack of toasts.
|
|
96
|
+
*
|
|
97
|
+
* If `required` is false, you should supply a relatively short `timeout`
|
|
98
|
+
* (e.g. 2000, meaning 2 seconds) to prevent your test taking too long.
|
|
99
|
+
*
|
|
100
|
+
* @param toasts - A Toasts instance.
|
|
101
|
+
* @param title - Expected title of the toast.
|
|
102
|
+
* @param button - Which button to click on the toast. Allowed values are
|
|
103
|
+
* "primary", which will accept the toast, or "secondary",
|
|
104
|
+
* which will reject it.
|
|
105
|
+
* @param timeout - Time in ms before we give up and decide the toast does
|
|
106
|
+
* not exist. If `required` is true, defaults to `timeout`
|
|
107
|
+
* in `TestConfig.expect`. Otherwise, defaults to 2000 (2
|
|
108
|
+
* seconds).
|
|
109
|
+
* @param required - If true, fail the test (throw an exception) if the
|
|
110
|
+
* toast is not visible. Otherwise, just return after
|
|
111
|
+
* `timeout` if the toast is not visible.
|
|
112
|
+
*/
|
|
113
|
+
async function clickToastButton(toasts, title, button, timeout, required = true) {
|
|
114
|
+
let toast;
|
|
115
|
+
if (required) {
|
|
116
|
+
toast = await toasts.getToast(title, timeout, true);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
toast = await toasts.getToast(title, timeout, false);
|
|
120
|
+
}
|
|
121
|
+
if (toast) {
|
|
122
|
+
await toast.locator(`.mx_Toast_buttons button[data-kind="${button}"]`).click();
|
|
96
123
|
}
|
|
97
124
|
}
|
package/lib/fixtures/user.d.ts
CHANGED
|
@@ -8,8 +8,8 @@ export declare const test: import("playwright/test").TestType<import("playwright
|
|
|
8
8
|
toasts: {
|
|
9
9
|
readonly page: Page;
|
|
10
10
|
assertNoToasts(): Promise<void>;
|
|
11
|
-
getToast(title: string, timeout?: number): Promise<import("playwright-core").Locator>;
|
|
12
|
-
|
|
11
|
+
getToast(title: string, timeout?: number, required?: true): Promise<import("playwright-core").Locator>;
|
|
12
|
+
getToast(title: string, timeout: number | undefined, required: false): Promise<import("playwright-core").Locator | null>;
|
|
13
13
|
acceptToast(title: string): Promise<void>;
|
|
14
14
|
acceptToastIfExists(title: string): Promise<void>;
|
|
15
15
|
rejectToast(title: string): Promise<void>;
|
package/lib/index.d.ts
CHANGED
|
@@ -44,8 +44,8 @@ export declare const test: import("playwright/test").TestType<import("playwright
|
|
|
44
44
|
toasts: {
|
|
45
45
|
readonly page: import("playwright-core").Page;
|
|
46
46
|
assertNoToasts(): Promise<void>;
|
|
47
|
-
getToast(title: string, timeout?: number): Promise<import("playwright-core").Locator>;
|
|
48
|
-
|
|
47
|
+
getToast(title: string, timeout?: number, required?: true): Promise<import("playwright-core").Locator>;
|
|
48
|
+
getToast(title: string, timeout: number | undefined, required: false): Promise<import("playwright-core").Locator | null>;
|
|
49
49
|
acceptToast(title: string): Promise<void>;
|
|
50
50
|
acceptToastIfExists(title: string): Promise<void>;
|
|
51
51
|
rejectToast(title: string): Promise<void>;
|
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": "
|
|
4
|
+
"version": "4.0.0",
|
|
5
5
|
"license": "SEE LICENSE IN README.md",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -24,8 +24,7 @@
|
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@element-hq/element-web-module-api": "workspace:*",
|
|
26
26
|
"@types/lodash-es": "^4.17.12",
|
|
27
|
-
"typescript": "^
|
|
28
|
-
"wait-on": "^9.0.4"
|
|
27
|
+
"typescript": "^6.0.0"
|
|
29
28
|
},
|
|
30
29
|
"dependencies": {
|
|
31
30
|
"@axe-core/playwright": "^4.10.1",
|
|
@@ -35,6 +34,7 @@
|
|
|
35
34
|
"mailpit-api": "^1.2.0",
|
|
36
35
|
"strip-ansi": "^7.1.0",
|
|
37
36
|
"testcontainers": "^11.0.0",
|
|
37
|
+
"wait-on": "^9.0.4",
|
|
38
38
|
"yaml": "^2.7.0"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
@@ -9,7 +9,7 @@ SCRIPT_DIR=$(dirname "$SCRIPT_PATH")
|
|
|
9
9
|
function build_image() {
|
|
10
10
|
local IMAGE_NAME="$1"
|
|
11
11
|
|
|
12
|
-
echo "Building $IMAGE_NAME image in $SCRIPT_DIR"
|
|
12
|
+
echo "playwright-screenshots: Building $IMAGE_NAME image in $SCRIPT_DIR"
|
|
13
13
|
docker build -t "$IMAGE_NAME" --build-arg "PLAYWRIGHT_VERSION=${IMAGE_NAME#*:}" "$SCRIPT_DIR"
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -34,16 +34,19 @@ CONTAINER=$(docker run --network=host -v /tmp:/tmp --rm -d -e PORT="$WS_PORT" "$
|
|
|
34
34
|
# Set up an exit trap to clean up the docker container
|
|
35
35
|
clean_up() {
|
|
36
36
|
ARG=$?
|
|
37
|
-
echo "Stopping playwright-server"
|
|
37
|
+
echo "playwright-screenshots: Stopping playwright-server"
|
|
38
38
|
docker stop "$CONTAINER" > /dev/null
|
|
39
39
|
exit $ARG
|
|
40
40
|
}
|
|
41
41
|
trap clean_up EXIT
|
|
42
42
|
|
|
43
43
|
# Wait for playwright-server to be ready
|
|
44
|
-
echo "Waiting for playwright-server"
|
|
44
|
+
echo "playwright-screenshots: Waiting for playwright-server"
|
|
45
45
|
pnpm --dir "$SCRIPT_DIR" exec wait-on "tcp:$WS_PORT"
|
|
46
46
|
|
|
47
|
+
# Playwright seems to overwrite the last line from the console, so add an
|
|
48
|
+
# extra newline to make sure this doesn't get lost.
|
|
49
|
+
echo -e "playwright-screenshots: Running '$@'\n"
|
|
50
|
+
|
|
47
51
|
# Run the test we were given, setting PW_TEST_CONNECT_WS_ENDPOINT accordingly
|
|
48
|
-
echo "Running '$@'"
|
|
49
52
|
PW_TEST_CONNECT_WS_ENDPOINT="http://localhost:$WS_PORT" "$@"
|
package/src/fixtures/toasts.ts
CHANGED
|
@@ -29,81 +29,135 @@ class Toasts {
|
|
|
29
29
|
public constructor(public readonly page: Page) {}
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* Assert that no toasts exist
|
|
32
|
+
* Assert that no toasts exist.
|
|
33
33
|
*/
|
|
34
34
|
public async assertNoToasts(): Promise<void> {
|
|
35
35
|
await expect(this.page.locator(".mx_Toast_toast")).not.toBeVisible();
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
*
|
|
39
|
+
* Return the toast with the supplied title. Fail or return null if it does
|
|
40
|
+
* not exist.
|
|
40
41
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
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.
|
|
42
|
+
* If `required` is false, you should supply a relatively short `timeout`
|
|
43
|
+
* (e.g. 2000, meaning 2 seconds) to prevent your test taking too long.
|
|
54
44
|
*
|
|
55
|
-
* @param title -
|
|
56
|
-
* @
|
|
57
|
-
*
|
|
45
|
+
* @param title - Expected title of the toast.
|
|
46
|
+
* @param timeout - Time in ms before we give up and decide the toast does
|
|
47
|
+
* not exist. If `required` is true, defaults to `timeout`
|
|
48
|
+
* in `TestConfig.expect`. Otherwise, defaults to 2000 (2
|
|
49
|
+
* seconds).
|
|
50
|
+
* @param required - If true, fail the test (throw an exception) if the
|
|
51
|
+
* toast is not visible. Otherwise, just return null if
|
|
52
|
+
* the toast is not visible.
|
|
53
|
+
* @returns the Locator for the matching toast, or null if it is not
|
|
54
|
+
* visible. (null will only be returned if `required` is false.)
|
|
58
55
|
*/
|
|
59
|
-
public
|
|
60
|
-
|
|
56
|
+
public async getToast(title: string, timeout?: number, required?: true): Promise<Locator>;
|
|
57
|
+
public async getToast(title: string, timeout: number | undefined, required: false): Promise<Locator | null>;
|
|
58
|
+
public async getToast(title: string, timeout?: number, required = true): Promise<Locator | null> {
|
|
59
|
+
const toast = this.page.locator(".mx_Toast_toast", { hasText: title }).first();
|
|
60
|
+
|
|
61
|
+
if (required) {
|
|
62
|
+
await expect(toast).toBeVisible({ timeout });
|
|
63
|
+
return toast;
|
|
64
|
+
} else {
|
|
65
|
+
// If we don't set a timeout, waitFor will wait forever. Since
|
|
66
|
+
// required is false, we definitely don't want to wait forever.
|
|
67
|
+
timeout = timeout ?? 2000;
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
await toast.waitFor({ state: "visible", timeout });
|
|
71
|
+
return toast;
|
|
72
|
+
} catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
61
76
|
}
|
|
62
77
|
|
|
63
78
|
/**
|
|
64
|
-
* Accept
|
|
65
|
-
*
|
|
79
|
+
* Accept the toast with the supplied title, or fail if it does not exist.
|
|
80
|
+
*
|
|
81
|
+
* Only works if this toast is at the top of the stack of toasts.
|
|
66
82
|
*
|
|
67
|
-
* @param title - Expected title of the toast
|
|
83
|
+
* @param title - Expected title of the toast.
|
|
68
84
|
*/
|
|
69
85
|
public async acceptToast(title: string): Promise<void> {
|
|
70
|
-
|
|
71
|
-
await toast.locator('.mx_Toast_buttons button[data-kind="primary"]').click();
|
|
86
|
+
return await clickToastButton(this, title, "primary");
|
|
72
87
|
}
|
|
88
|
+
|
|
73
89
|
/**
|
|
74
|
-
* Accept
|
|
75
|
-
*
|
|
90
|
+
* Accept the toast with the supplied title, if it exists, or return after 2
|
|
91
|
+
* seconds if it is not found.
|
|
76
92
|
*
|
|
77
|
-
*
|
|
93
|
+
* Only works if this toast is at the top of the stack of toasts.
|
|
94
|
+
*
|
|
95
|
+
* @param title - Expected title of the toast.
|
|
78
96
|
*/
|
|
79
97
|
public async acceptToastIfExists(title: string): Promise<void> {
|
|
80
|
-
|
|
81
|
-
if ((await toast.count()) > 0) {
|
|
82
|
-
await toast.click();
|
|
83
|
-
}
|
|
98
|
+
return await clickToastButton(this, title, "primary", 2000, false);
|
|
84
99
|
}
|
|
85
100
|
|
|
86
101
|
/**
|
|
87
|
-
* Reject
|
|
88
|
-
*
|
|
102
|
+
* Reject the toast with the supplied title, or fail if it does not exist.
|
|
103
|
+
*
|
|
104
|
+
* Only works if this toast is at the top of the stack of toasts.
|
|
89
105
|
*
|
|
90
|
-
* @param title - Expected title of the toast
|
|
106
|
+
* @param title - Expected title of the toast.
|
|
91
107
|
*/
|
|
92
108
|
public async rejectToast(title: string): Promise<void> {
|
|
93
|
-
|
|
94
|
-
await toast.locator('.mx_Toast_buttons button[data-kind="secondary"]').click();
|
|
109
|
+
return await clickToastButton(this, title, "secondary");
|
|
95
110
|
}
|
|
96
111
|
|
|
97
112
|
/**
|
|
98
|
-
* Reject
|
|
99
|
-
*
|
|
113
|
+
* Reject the toast with the supplied title, if it exists, or return after 2
|
|
114
|
+
* seconds if it is not found.
|
|
100
115
|
*
|
|
101
|
-
*
|
|
116
|
+
* Only works if this toast is at the top of the stack of toasts.
|
|
117
|
+
*
|
|
118
|
+
* @param title - Expected title of the toast.
|
|
102
119
|
*/
|
|
103
120
|
public async rejectToastIfExists(title: string): Promise<void> {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
121
|
+
return await clickToastButton(this, title, "secondary", 2000, false);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Find the toast with the supplied title and click a button on it.
|
|
127
|
+
*
|
|
128
|
+
* Only works if this toast is at the top of the stack of toasts.
|
|
129
|
+
*
|
|
130
|
+
* If `required` is false, you should supply a relatively short `timeout`
|
|
131
|
+
* (e.g. 2000, meaning 2 seconds) to prevent your test taking too long.
|
|
132
|
+
*
|
|
133
|
+
* @param toasts - A Toasts instance.
|
|
134
|
+
* @param title - Expected title of the toast.
|
|
135
|
+
* @param button - Which button to click on the toast. Allowed values are
|
|
136
|
+
* "primary", which will accept the toast, or "secondary",
|
|
137
|
+
* which will reject it.
|
|
138
|
+
* @param timeout - Time in ms before we give up and decide the toast does
|
|
139
|
+
* not exist. If `required` is true, defaults to `timeout`
|
|
140
|
+
* in `TestConfig.expect`. Otherwise, defaults to 2000 (2
|
|
141
|
+
* seconds).
|
|
142
|
+
* @param required - If true, fail the test (throw an exception) if the
|
|
143
|
+
* toast is not visible. Otherwise, just return after
|
|
144
|
+
* `timeout` if the toast is not visible.
|
|
145
|
+
*/
|
|
146
|
+
async function clickToastButton(
|
|
147
|
+
toasts: Toasts,
|
|
148
|
+
title: string,
|
|
149
|
+
button: "primary" | "secondary",
|
|
150
|
+
timeout?: number,
|
|
151
|
+
required = true,
|
|
152
|
+
): Promise<void> {
|
|
153
|
+
let toast: Locator | null;
|
|
154
|
+
if (required) {
|
|
155
|
+
toast = await toasts.getToast(title, timeout, true);
|
|
156
|
+
} else {
|
|
157
|
+
toast = await toasts.getToast(title, timeout, false);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (toast) {
|
|
161
|
+
await toast.locator(`.mx_Toast_buttons button[data-kind="${button}"]`).click();
|
|
108
162
|
}
|
|
109
163
|
}
|