@gtkx/testing 1.0.0-rc.1 → 1.0.0-rc.2
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/dist/act.d.ts +6 -6
- package/dist/act.d.ts.map +1 -1
- package/dist/act.js +34 -26
- package/dist/act.js.map +1 -1
- package/dist/bound-queries.d.ts +4 -3
- package/dist/bound-queries.d.ts.map +1 -1
- package/dist/bound-queries.js.map +1 -1
- package/dist/build-queries.d.ts +5 -5
- package/dist/build-queries.d.ts.map +1 -1
- package/dist/build-queries.js +21 -9
- package/dist/build-queries.js.map +1 -1
- package/dist/cleanup-registry.d.ts +4 -3
- package/dist/cleanup-registry.d.ts.map +1 -1
- package/dist/cleanup-registry.js +13 -3
- package/dist/cleanup-registry.js.map +1 -1
- package/dist/config.d.ts +5 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +11 -9
- package/dist/config.js.map +1 -1
- package/dist/editable.d.ts +6 -5
- package/dist/editable.d.ts.map +1 -1
- package/dist/editable.js +7 -5
- package/dist/editable.js.map +1 -1
- package/dist/errors.d.ts +7 -6
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +64 -48
- package/dist/errors.js.map +1 -1
- package/dist/fire-event.d.ts +2 -1
- package/dist/fire-event.d.ts.map +1 -1
- package/dist/fire-event.js +2 -1
- package/dist/fire-event.js.map +1 -1
- package/dist/frame-sync.d.ts +2 -1
- package/dist/frame-sync.d.ts.map +1 -1
- package/dist/frame-sync.js +28 -21
- package/dist/frame-sync.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/matchers.d.ts +38 -34
- package/dist/matchers.d.ts.map +1 -1
- package/dist/matchers.js +72 -58
- package/dist/matchers.js.map +1 -1
- package/dist/pretty-widget.d.ts +6 -4
- package/dist/pretty-widget.d.ts.map +1 -1
- package/dist/pretty-widget.js +64 -24
- package/dist/pretty-widget.js.map +1 -1
- package/dist/queries.d.ts +143 -86
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +231 -147
- package/dist/queries.js.map +1 -1
- package/dist/register-test-hooks.js +2 -1
- package/dist/register-test-hooks.js.map +1 -1
- package/dist/render-hook.d.ts +3 -2
- package/dist/render-hook.d.ts.map +1 -1
- package/dist/render-hook.js +2 -1
- package/dist/render-hook.js.map +1 -1
- package/dist/render.d.ts +3 -2
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +24 -18
- package/dist/render.js.map +1 -1
- package/dist/role-helpers.d.ts +6 -5
- package/dist/role-helpers.d.ts.map +1 -1
- package/dist/role-helpers.js +16 -12
- package/dist/role-helpers.js.map +1 -1
- package/dist/screen.d.ts +4 -3
- package/dist/screen.d.ts.map +1 -1
- package/dist/screen.js +13 -11
- package/dist/screen.js.map +1 -1
- package/dist/screenshot.d.ts +4 -3
- package/dist/screenshot.d.ts.map +1 -1
- package/dist/screenshot.js +43 -36
- package/dist/screenshot.js.map +1 -1
- package/dist/suggestions.d.ts +11 -6
- package/dist/suggestions.d.ts.map +1 -1
- package/dist/suggestions.js +10 -5
- package/dist/suggestions.js.map +1 -1
- package/dist/traversal.d.ts +7 -7
- package/dist/traversal.d.ts.map +1 -1
- package/dist/traversal.js +17 -11
- package/dist/traversal.js.map +1 -1
- package/dist/types.d.ts +39 -24
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/user-event/adjustment.d.ts +5 -3
- package/dist/user-event/adjustment.d.ts.map +1 -1
- package/dist/user-event/adjustment.js +6 -4
- package/dist/user-event/adjustment.js.map +1 -1
- package/dist/user-event/click.d.ts +6 -5
- package/dist/user-event/click.d.ts.map +1 -1
- package/dist/user-event/click.js +29 -21
- package/dist/user-event/click.js.map +1 -1
- package/dist/user-event/controller.d.ts +6 -5
- package/dist/user-event/controller.d.ts.map +1 -1
- package/dist/user-event/controller.js +9 -6
- package/dist/user-event/controller.js.map +1 -1
- package/dist/user-event/dispatch.d.ts +3 -3
- package/dist/user-event/dispatch.d.ts.map +1 -1
- package/dist/user-event/dispatch.js +3 -2
- package/dist/user-event/dispatch.js.map +1 -1
- package/dist/user-event/event-wrapper.d.ts +2 -1
- package/dist/user-event/event-wrapper.d.ts.map +1 -1
- package/dist/user-event/event-wrapper.js +27 -16
- package/dist/user-event/event-wrapper.js.map +1 -1
- package/dist/user-event/gesture.d.ts +18 -14
- package/dist/user-event/gesture.d.ts.map +1 -1
- package/dist/user-event/gesture.js +70 -37
- package/dist/user-event/gesture.js.map +1 -1
- package/dist/user-event/index.d.ts +17 -10
- package/dist/user-event/index.d.ts.map +1 -1
- package/dist/user-event/index.js +7 -3
- package/dist/user-event/index.js.map +1 -1
- package/dist/user-event/keyboard.d.ts +4 -3
- package/dist/user-event/keyboard.d.ts.map +1 -1
- package/dist/user-event/keyboard.js +89 -58
- package/dist/user-event/keyboard.js.map +1 -1
- package/dist/user-event/pointer.d.ts +7 -3
- package/dist/user-event/pointer.d.ts.map +1 -1
- package/dist/user-event/pointer.js +4 -1
- package/dist/user-event/pointer.js.map +1 -1
- package/dist/user-event/selection.d.ts +3 -2
- package/dist/user-event/selection.d.ts.map +1 -1
- package/dist/user-event/selection.js +26 -27
- package/dist/user-event/selection.js.map +1 -1
- package/dist/user-event/state.d.ts +3 -2
- package/dist/user-event/state.d.ts.map +1 -1
- package/dist/user-event/state.js +2 -1
- package/dist/user-event/state.js.map +1 -1
- package/dist/user-event/text.d.ts +8 -7
- package/dist/user-event/text.d.ts.map +1 -1
- package/dist/user-event/text.js +39 -33
- package/dist/user-event/text.js.map +1 -1
- package/dist/wait-for.d.ts +5 -5
- package/dist/wait-for.d.ts.map +1 -1
- package/dist/wait-for.js +45 -30
- package/dist/wait-for.js.map +1 -1
- package/dist/widget-accessible-properties.d.ts +26 -25
- package/dist/widget-accessible-properties.d.ts.map +1 -1
- package/dist/widget-accessible-properties.js +106 -61
- package/dist/widget-accessible-properties.js.map +1 -1
- package/dist/within.d.ts +2 -1
- package/dist/within.d.ts.map +1 -1
- package/dist/within.js +2 -1
- package/dist/within.js.map +1 -1
- package/package.json +11 -9
- package/src/act.ts +44 -35
- package/src/bound-queries.ts +5 -4
- package/src/build-queries.ts +84 -43
- package/src/cleanup-registry.ts +18 -5
- package/src/config.ts +16 -12
- package/src/editable.ts +13 -6
- package/src/errors.ts +106 -45
- package/src/fire-event.ts +3 -1
- package/src/frame-sync.ts +38 -21
- package/src/index.ts +2 -1
- package/src/matchers.ts +158 -107
- package/src/pretty-widget.ts +114 -42
- package/src/queries.ts +422 -233
- package/src/register-test-hooks.ts +4 -1
- package/src/render-hook.tsx +10 -4
- package/src/render.tsx +58 -33
- package/src/role-helpers.ts +29 -16
- package/src/screen.ts +17 -12
- package/src/screenshot.ts +61 -38
- package/src/suggestions.ts +29 -10
- package/src/traversal.ts +35 -15
- package/src/types.ts +65 -32
- package/src/user-event/adjustment.ts +23 -10
- package/src/user-event/click.ts +49 -20
- package/src/user-event/controller.ts +21 -7
- package/src/user-event/dispatch.ts +4 -2
- package/src/user-event/event-wrapper.ts +42 -16
- package/src/user-event/gesture.ts +135 -50
- package/src/user-event/index.ts +19 -12
- package/src/user-event/keyboard.ts +147 -61
- package/src/user-event/pointer.ts +20 -8
- package/src/user-event/selection.ts +69 -32
- package/src/user-event/state.ts +4 -2
- package/src/user-event/text.ts +73 -38
- package/src/wait-for.ts +77 -36
- package/src/widget-accessible-properties.ts +218 -74
- package/src/within.ts +7 -4
package/src/user-event/text.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { formatRoleList } from "../role-helpers.js";
|
|
|
6
6
|
import { wrapEvent } from "./event-wrapper.js";
|
|
7
7
|
|
|
8
8
|
/** Options for {@link type}. */
|
|
9
|
-
|
|
9
|
+
type TypeOptions = {
|
|
10
10
|
/** Do not focus the widget before typing. */
|
|
11
11
|
skipClick?: boolean | undefined;
|
|
12
12
|
/** Select from this offset before typing, replacing the selected range with the typed text. */
|
|
@@ -20,11 +20,15 @@ const EDITABLE_REQUIRED = `expected editable widget (${formatRoleList(EDITABLE_R
|
|
|
20
20
|
const insertEditableText = (widget: EditableTarget, text: string): void => {
|
|
21
21
|
if (widget instanceof Gtk.TextView) {
|
|
22
22
|
widget.emit("insert-at-cursor", text);
|
|
23
|
+
|
|
23
24
|
return;
|
|
24
25
|
}
|
|
26
|
+
|
|
25
27
|
const target = getEditableDelegate(widget) ?? widget;
|
|
28
|
+
|
|
26
29
|
if (target instanceof Gtk.Text) {
|
|
27
30
|
target.emit("insert-at-cursor", text);
|
|
31
|
+
|
|
28
32
|
return;
|
|
29
33
|
}
|
|
30
34
|
|
|
@@ -37,101 +41,132 @@ const readSelection = (widget: EditableTarget): string => {
|
|
|
37
41
|
if (widget instanceof Gtk.TextView) {
|
|
38
42
|
const buffer = widget.getBuffer();
|
|
39
43
|
const [hasSelection, start, end] = buffer.getSelectionBounds();
|
|
44
|
+
|
|
40
45
|
return hasSelection ? buffer.getText(start, end, true) : "";
|
|
41
46
|
}
|
|
47
|
+
|
|
42
48
|
const [hasSelection, start, end] = widget.getSelectionBounds();
|
|
49
|
+
|
|
43
50
|
return hasSelection ? widget.getChars(start, end) : "";
|
|
44
51
|
};
|
|
45
52
|
|
|
46
53
|
const deleteSelection = (widget: EditableTarget): void => {
|
|
47
54
|
if (widget instanceof Gtk.TextView) {
|
|
48
55
|
widget.getBuffer().deleteSelection(false, true);
|
|
56
|
+
|
|
49
57
|
return;
|
|
50
58
|
}
|
|
59
|
+
|
|
51
60
|
widget.deleteSelection();
|
|
52
61
|
};
|
|
53
62
|
|
|
54
63
|
const setEditableText = (widget: EditableTarget, text: string): void => {
|
|
55
64
|
if (widget instanceof Gtk.TextView) {
|
|
56
65
|
widget.getBuffer().setText(text, text.length);
|
|
66
|
+
|
|
57
67
|
return;
|
|
58
68
|
}
|
|
69
|
+
|
|
59
70
|
widget.setText(text);
|
|
60
71
|
};
|
|
61
72
|
|
|
73
|
+
const applyTextViewSelection = (widget: Gtk.TextView, start: number, end: number): void => {
|
|
74
|
+
const buffer = widget.getBuffer();
|
|
75
|
+
buffer.selectRange(buffer.getIterAtOffset(start), buffer.getIterAtOffset(end));
|
|
76
|
+
|
|
77
|
+
if (end !== start) {
|
|
78
|
+
deleteSelection(widget);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const applyEditableSelection = (widget: Gtk.Editable, start: number, end: number): void => {
|
|
83
|
+
widget.selectRegion(start, end);
|
|
84
|
+
|
|
85
|
+
if (end !== start) {
|
|
86
|
+
widget.deleteSelection();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
widget.setPosition(start);
|
|
90
|
+
};
|
|
91
|
+
|
|
62
92
|
const applyInitialSelection = (widget: EditableTarget, options: TypeOptions): void => {
|
|
63
|
-
if (options.initialSelectionStart === undefined)
|
|
93
|
+
if (options.initialSelectionStart === undefined) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
64
97
|
const start = options.initialSelectionStart;
|
|
65
98
|
const end = options.initialSelectionEnd ?? start;
|
|
99
|
+
|
|
66
100
|
if (widget instanceof Gtk.TextView) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (end !== start) deleteSelection(widget);
|
|
101
|
+
applyTextViewSelection(widget, start, end);
|
|
102
|
+
|
|
70
103
|
return;
|
|
71
104
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
widget.setPosition(start);
|
|
105
|
+
|
|
106
|
+
applyEditableSelection(widget, start, end);
|
|
75
107
|
};
|
|
76
108
|
|
|
77
109
|
const writeClipboardText = (widget: Gtk.Widget, text: string): void => {
|
|
78
|
-
const value = GObject.buildValue(GObject.TYPE_STRING, (v) =>
|
|
110
|
+
const value = GObject.buildValue(GObject.TYPE_STRING, (v) => {
|
|
111
|
+
v.setString(text);
|
|
112
|
+
});
|
|
113
|
+
|
|
79
114
|
widget.getClipboard().set(value);
|
|
80
115
|
};
|
|
81
116
|
|
|
82
|
-
|
|
117
|
+
const resetClipboard = (): void => {
|
|
83
118
|
Gdk.Display.getDefault()?.getClipboard().setContent(null);
|
|
84
119
|
};
|
|
85
120
|
|
|
86
|
-
|
|
121
|
+
const runEditableEvent = (
|
|
122
|
+
widget: Gtk.Widget,
|
|
123
|
+
failure: string,
|
|
124
|
+
action: (editable: EditableTarget) => void,
|
|
125
|
+
): Promise<void> =>
|
|
87
126
|
wrapEvent(widget, () => {
|
|
88
127
|
if (!isEditable(widget)) {
|
|
89
|
-
throw new Error(
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (!options?.skipClick) {
|
|
93
|
-
widget.grabFocus();
|
|
128
|
+
throw new Error(`${failure}: ${EDITABLE_REQUIRED}`);
|
|
94
129
|
}
|
|
95
130
|
|
|
96
|
-
|
|
97
|
-
insertEditableText(widget, text);
|
|
131
|
+
action(widget);
|
|
98
132
|
});
|
|
99
133
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (!
|
|
103
|
-
|
|
134
|
+
const type = (widget: Gtk.Widget, text: string, options?: TypeOptions): Promise<void> =>
|
|
135
|
+
runEditableEvent(widget, "Cannot type into element", (editable) => {
|
|
136
|
+
if (!options?.skipClick) {
|
|
137
|
+
editable.grabFocus();
|
|
104
138
|
}
|
|
105
139
|
|
|
106
|
-
|
|
140
|
+
applyInitialSelection(editable, options ?? {});
|
|
141
|
+
insertEditableText(editable, text);
|
|
107
142
|
});
|
|
108
143
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
throw new Error(`Cannot copy: ${EDITABLE_REQUIRED}`);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
writeClipboardText(widget, readSelection(widget));
|
|
144
|
+
const clear = (widget: Gtk.Widget): Promise<void> =>
|
|
145
|
+
runEditableEvent(widget, "Cannot clear element", (editable) => {
|
|
146
|
+
setEditableText(editable, "");
|
|
116
147
|
});
|
|
117
148
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
149
|
+
const copy = (widget: Gtk.Widget): Promise<void> =>
|
|
150
|
+
runEditableEvent(widget, "Cannot copy", (editable) => {
|
|
151
|
+
writeClipboardText(editable, readSelection(editable));
|
|
152
|
+
});
|
|
123
153
|
|
|
124
|
-
|
|
125
|
-
|
|
154
|
+
const cut = (widget: Gtk.Widget): Promise<void> =>
|
|
155
|
+
runEditableEvent(widget, "Cannot cut", (editable) => {
|
|
156
|
+
writeClipboardText(editable, readSelection(editable));
|
|
157
|
+
deleteSelection(editable);
|
|
126
158
|
});
|
|
127
159
|
|
|
128
|
-
|
|
160
|
+
const paste = async (widget: Gtk.Widget, text?: string): Promise<void> => {
|
|
129
161
|
if (!isEditable(widget)) {
|
|
130
162
|
throw new Error(`Cannot paste: ${EDITABLE_REQUIRED}`);
|
|
131
163
|
}
|
|
132
164
|
|
|
133
165
|
const content = text ?? (await widget.getClipboard().readTextAsync(null)) ?? "";
|
|
166
|
+
|
|
134
167
|
await wrapEvent(widget, () => {
|
|
135
168
|
insertEditableText(widget, content);
|
|
136
169
|
});
|
|
137
170
|
};
|
|
171
|
+
|
|
172
|
+
export { resetClipboard, type, clear, copy, cut, paste, type TypeOptions };
|
package/src/wait-for.ts
CHANGED
|
@@ -1,17 +1,70 @@
|
|
|
1
1
|
import type * as Gtk from "@gtkx/gi/gtk";
|
|
2
|
+
import type { WaitForOptions } from "./types.js";
|
|
2
3
|
import { runWithActEnvironment } from "./act.js";
|
|
3
4
|
import { getConfig } from "./config.js";
|
|
4
5
|
import { timeoutError } from "./errors.js";
|
|
5
|
-
|
|
6
|
+
|
|
7
|
+
type PollResult<T> = { status: "resolved"; value: T } | { status: "timedout"; lastError: Error | null };
|
|
8
|
+
type RemovalTarget = Gtk.Widget | Gtk.Widget[] | null;
|
|
9
|
+
type ElementOrCallback = Gtk.Widget | Gtk.Widget[] | (() => RemovalTarget);
|
|
6
10
|
|
|
7
11
|
const DEFAULT_INTERVAL = 50;
|
|
12
|
+
const ELEMENT_NOT_REMOVED = new Error("Element not yet removed");
|
|
8
13
|
|
|
9
14
|
const delay = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));
|
|
10
15
|
|
|
11
16
|
const copyStackTrace = (target: Error, source: Error): void => {
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
const { stack } = source;
|
|
18
|
+
|
|
19
|
+
if (stack === undefined) {
|
|
20
|
+
return;
|
|
14
21
|
}
|
|
22
|
+
|
|
23
|
+
const index = stack.indexOf(source.message);
|
|
24
|
+
|
|
25
|
+
if (index === -1) {
|
|
26
|
+
target.stack = stack;
|
|
27
|
+
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
target.stack = stack.slice(0, index) + target.message + stack.slice(index + source.message.length);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const pollUntilSuccess = async <T>(
|
|
35
|
+
callback: () => T | Promise<T>,
|
|
36
|
+
timeout: number,
|
|
37
|
+
interval: number,
|
|
38
|
+
): Promise<PollResult<T>> => {
|
|
39
|
+
const startTime = Date.now();
|
|
40
|
+
let lastError: Error | null = null;
|
|
41
|
+
|
|
42
|
+
while (Date.now() - startTime < timeout) {
|
|
43
|
+
try {
|
|
44
|
+
const result = await callback();
|
|
45
|
+
await delay(0);
|
|
46
|
+
|
|
47
|
+
return { status: "resolved", value: result };
|
|
48
|
+
} catch (error) {
|
|
49
|
+
lastError = error as Error;
|
|
50
|
+
await delay(interval);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return { status: "timedout", lastError };
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const buildTimeoutError = (
|
|
58
|
+
timeout: number,
|
|
59
|
+
lastError: Error | null,
|
|
60
|
+
stackTraceError: Error,
|
|
61
|
+
onTimeout: ((error: Error) => Error) | undefined,
|
|
62
|
+
): Error => {
|
|
63
|
+
const error = timeoutError(timeout, lastError);
|
|
64
|
+
const finalError = onTimeout ? onTimeout(error) : error;
|
|
65
|
+
copyStackTrace(finalError, stackTraceError);
|
|
66
|
+
|
|
67
|
+
return finalError;
|
|
15
68
|
};
|
|
16
69
|
|
|
17
70
|
/**
|
|
@@ -22,7 +75,7 @@ const copyStackTrace = (target: Error, source: Error): void => {
|
|
|
22
75
|
* @param options Optional timeout, interval, and timeout error customization.
|
|
23
76
|
* @returns The callback's result once it succeeds.
|
|
24
77
|
*/
|
|
25
|
-
|
|
78
|
+
const waitFor = <T>(callback: () => T | Promise<T>, options?: WaitForOptions): Promise<T> => {
|
|
26
79
|
if (typeof callback !== "function") {
|
|
27
80
|
throw new TypeError("Received `callback` arg must be a function");
|
|
28
81
|
}
|
|
@@ -33,41 +86,24 @@ export const waitFor = <T>(callback: () => T | Promise<T>, options?: WaitForOpti
|
|
|
33
86
|
runWithActEnvironment(false, async () => {
|
|
34
87
|
const config = getConfig();
|
|
35
88
|
const { timeout = config.asyncUtilTimeout, interval = DEFAULT_INTERVAL, onTimeout } = options ?? {};
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
const result = await callback();
|
|
42
|
-
await delay(0);
|
|
43
|
-
return result;
|
|
44
|
-
} catch (error) {
|
|
45
|
-
lastError = error as Error;
|
|
46
|
-
await delay(interval);
|
|
47
|
-
}
|
|
89
|
+
const result = await pollUntilSuccess(callback, timeout, interval);
|
|
90
|
+
|
|
91
|
+
if (result.status === "resolved") {
|
|
92
|
+
return result.value;
|
|
48
93
|
}
|
|
49
94
|
|
|
50
|
-
|
|
51
|
-
const finalError = onTimeout ? onTimeout(error) : error;
|
|
52
|
-
copyStackTrace(finalError, stackTraceError);
|
|
53
|
-
throw finalError;
|
|
95
|
+
throw buildTimeoutError(timeout, result.lastError, stackTraceError, onTimeout);
|
|
54
96
|
}),
|
|
55
97
|
);
|
|
56
98
|
};
|
|
57
99
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
type ElementOrCallback = Gtk.Widget | Gtk.Widget[] | (() => RemovalTarget);
|
|
61
|
-
|
|
62
|
-
const getTarget = (elementOrCallback: ElementOrCallback): RemovalTarget => {
|
|
63
|
-
if (typeof elementOrCallback === "function") {
|
|
64
|
-
return elementOrCallback();
|
|
65
|
-
}
|
|
66
|
-
return elementOrCallback;
|
|
67
|
-
};
|
|
100
|
+
const getTarget = (elementOrCallback: ElementOrCallback): RemovalTarget =>
|
|
101
|
+
typeof elementOrCallback === "function" ? elementOrCallback() : elementOrCallback;
|
|
68
102
|
|
|
69
103
|
const isWidgetRemoved = (widget: Gtk.Widget | null): boolean => {
|
|
70
|
-
if (widget === null)
|
|
104
|
+
if (widget === null) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
71
107
|
|
|
72
108
|
try {
|
|
73
109
|
return widget.getRoot() === null;
|
|
@@ -78,13 +114,12 @@ const isWidgetRemoved = (widget: Gtk.Widget | null): boolean => {
|
|
|
78
114
|
|
|
79
115
|
const isTargetRemoved = (target: RemovalTarget): boolean => {
|
|
80
116
|
if (Array.isArray(target)) {
|
|
81
|
-
return target.
|
|
117
|
+
return target.every((widget) => isWidgetRemoved(widget));
|
|
82
118
|
}
|
|
119
|
+
|
|
83
120
|
return isWidgetRemoved(target);
|
|
84
121
|
};
|
|
85
122
|
|
|
86
|
-
const ELEMENT_NOT_REMOVED = new Error("Element not yet removed");
|
|
87
|
-
|
|
88
123
|
/**
|
|
89
124
|
* Waits until the given widget or widgets are detached from the tree. Rejects
|
|
90
125
|
* immediately if the target is already absent when called.
|
|
@@ -93,11 +128,12 @@ const ELEMENT_NOT_REMOVED = new Error("Element not yet removed");
|
|
|
93
128
|
* returning them to observe for removal.
|
|
94
129
|
* @param options Optional timeout and interval settings.
|
|
95
130
|
*/
|
|
96
|
-
|
|
131
|
+
const waitForElementToBeRemoved = (
|
|
97
132
|
elementOrCallback: ElementOrCallback,
|
|
98
133
|
options?: WaitForOptions,
|
|
99
134
|
): Promise<void> => {
|
|
100
135
|
const stackTraceError = new Error("STACK_TRACE_MESSAGE");
|
|
136
|
+
|
|
101
137
|
if (isTargetRemoved(getTarget(elementOrCallback))) {
|
|
102
138
|
return Promise.reject(
|
|
103
139
|
new Error(
|
|
@@ -105,10 +141,15 @@ export const waitForElementToBeRemoved = (
|
|
|
105
141
|
),
|
|
106
142
|
);
|
|
107
143
|
}
|
|
144
|
+
|
|
108
145
|
return waitFor(
|
|
109
146
|
() => {
|
|
110
|
-
if (!isTargetRemoved(getTarget(elementOrCallback)))
|
|
147
|
+
if (!isTargetRemoved(getTarget(elementOrCallback))) {
|
|
148
|
+
throw ELEMENT_NOT_REMOVED;
|
|
149
|
+
}
|
|
111
150
|
},
|
|
112
151
|
{ ...options, stackTraceError },
|
|
113
152
|
);
|
|
114
153
|
};
|
|
154
|
+
|
|
155
|
+
export { waitFor, waitForElementToBeRemoved };
|