@gtkx/testing 1.0.0-rc.3 → 1.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/README.md +8 -9
- package/dist/accessible-native.d.ts +16 -0
- package/dist/accessible-native.d.ts.map +1 -0
- package/dist/accessible-native.js +206 -0
- package/dist/accessible-native.js.map +1 -0
- package/dist/act.d.ts +2 -0
- package/dist/act.d.ts.map +1 -1
- package/dist/act.js.map +1 -1
- package/dist/build-queries.d.ts +27 -10
- package/dist/build-queries.d.ts.map +1 -1
- package/dist/build-queries.js +39 -30
- package/dist/build-queries.js.map +1 -1
- package/dist/cleanup-registry.d.ts +1 -1
- package/dist/cleanup-registry.d.ts.map +1 -1
- package/dist/cleanup-registry.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -3
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +10 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +12 -3
- package/dist/errors.js.map +1 -1
- package/dist/fire-event.d.ts +35 -6
- package/dist/fire-event.d.ts.map +1 -1
- package/dist/fire-event.js +23 -7
- 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 +15 -5
- package/dist/frame-sync.js.map +1 -1
- package/dist/harness-window.d.ts +4 -0
- package/dist/harness-window.d.ts.map +1 -0
- package/dist/harness-window.js +6 -0
- package/dist/harness-window.js.map +1 -0
- package/dist/index.d.ts +14 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -5
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +4 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +4 -0
- package/dist/internal.js.map +1 -0
- package/dist/matchers.d.ts +125 -39
- package/dist/matchers.d.ts.map +1 -1
- package/dist/matchers.js +156 -18
- package/dist/matchers.js.map +1 -1
- package/dist/pretty-format.d.ts +2 -0
- package/dist/pretty-format.d.ts.map +1 -0
- package/dist/pretty-format.js +2 -0
- package/dist/pretty-format.js.map +1 -0
- package/dist/pretty-widget.d.ts +7 -3
- package/dist/pretty-widget.d.ts.map +1 -1
- package/dist/pretty-widget.js +74 -57
- package/dist/pretty-widget.js.map +1 -1
- package/dist/production.d.ts +8 -0
- package/dist/production.d.ts.map +1 -0
- package/dist/production.js +34 -0
- package/dist/production.js.map +1 -0
- package/dist/queries.d.ts +99 -56
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +123 -83
- package/dist/queries.js.map +1 -1
- package/dist/query-helpers.d.ts +44 -0
- package/dist/query-helpers.d.ts.map +1 -0
- package/dist/query-helpers.js +57 -0
- package/dist/query-helpers.js.map +1 -0
- package/dist/render-children.d.ts +9 -0
- package/dist/render-children.d.ts.map +1 -0
- package/dist/render-children.js +11 -0
- package/dist/render-children.js.map +1 -0
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +13 -11
- package/dist/render.js.map +1 -1
- package/dist/role-helpers.d.ts +12 -3
- package/dist/role-helpers.d.ts.map +1 -1
- package/dist/role-helpers.js +13 -4
- package/dist/role-helpers.js.map +1 -1
- package/dist/role-naming.d.ts +5 -0
- package/dist/role-naming.d.ts.map +1 -0
- package/dist/role-naming.js +96 -0
- package/dist/role-naming.js.map +1 -0
- package/dist/screenshot.d.ts +12 -20
- package/dist/screenshot.d.ts.map +1 -1
- package/dist/screenshot.js +183 -91
- package/dist/screenshot.js.map +1 -1
- package/dist/suggestions.d.ts +3 -0
- package/dist/suggestions.d.ts.map +1 -1
- package/dist/suggestions.js.map +1 -1
- package/dist/traversal.d.ts +9 -1
- package/dist/traversal.d.ts.map +1 -1
- package/dist/traversal.js +26 -6
- package/dist/traversal.js.map +1 -1
- package/dist/types.d.ts +67 -17
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/user-event/adjustment.d.ts +16 -0
- package/dist/user-event/adjustment.d.ts.map +1 -1
- package/dist/user-event/adjustment.js +34 -2
- package/dist/user-event/adjustment.js.map +1 -1
- package/dist/user-event/click.d.ts +45 -3
- package/dist/user-event/click.d.ts.map +1 -1
- package/dist/user-event/click.js +177 -39
- package/dist/user-event/click.js.map +1 -1
- package/dist/user-event/column-header-click.d.ts +4 -0
- package/dist/user-event/column-header-click.d.ts.map +1 -0
- package/dist/user-event/column-header-click.js +65 -0
- package/dist/user-event/column-header-click.js.map +1 -0
- package/dist/user-event/controller.d.ts +29 -0
- package/dist/user-event/controller.d.ts.map +1 -1
- package/dist/user-event/controller.js +28 -0
- package/dist/user-event/controller.js.map +1 -1
- package/dist/user-event/event-wrapper.d.ts.map +1 -1
- package/dist/user-event/event-wrapper.js +2 -1
- package/dist/user-event/event-wrapper.js.map +1 -1
- package/dist/user-event/gesture.d.ts +51 -0
- package/dist/user-event/gesture.d.ts.map +1 -1
- package/dist/user-event/gesture.js +47 -4
- package/dist/user-event/gesture.js.map +1 -1
- package/dist/user-event/index.d.ts +70 -2
- package/dist/user-event/index.d.ts.map +1 -1
- package/dist/user-event/index.js +43 -26
- package/dist/user-event/index.js.map +1 -1
- package/dist/user-event/indexed-children.d.ts +10 -0
- package/dist/user-event/indexed-children.d.ts.map +1 -0
- package/dist/user-event/indexed-children.js +50 -0
- package/dist/user-event/indexed-children.js.map +1 -0
- package/dist/user-event/keyboard.d.ts +4 -2
- package/dist/user-event/keyboard.d.ts.map +1 -1
- package/dist/user-event/keyboard.js +46 -16
- package/dist/user-event/keyboard.js.map +1 -1
- package/dist/user-event/list-row-click.d.ts +4 -0
- package/dist/user-event/list-row-click.d.ts.map +1 -0
- package/dist/user-event/list-row-click.js +39 -0
- package/dist/user-event/list-row-click.js.map +1 -0
- package/dist/user-event/native-click.d.ts +6 -0
- package/dist/user-event/native-click.d.ts.map +1 -0
- package/dist/user-event/native-click.js +32 -0
- package/dist/user-event/native-click.js.map +1 -0
- package/dist/user-event/pointer.d.ts +1 -1
- package/dist/user-event/pointer.d.ts.map +1 -1
- package/dist/user-event/pointer.js +37 -13
- package/dist/user-event/pointer.js.map +1 -1
- package/dist/user-event/selection.d.ts +18 -0
- package/dist/user-event/selection.d.ts.map +1 -1
- package/dist/user-event/selection.js +56 -30
- package/dist/user-event/selection.js.map +1 -1
- package/dist/user-event/state.d.ts +1 -1
- package/dist/user-event/state.d.ts.map +1 -1
- package/dist/user-event/state.js +1 -1
- package/dist/user-event/state.js.map +1 -1
- package/dist/user-event/text.d.ts +34 -3
- package/dist/user-event/text.d.ts.map +1 -1
- package/dist/user-event/text.js +94 -17
- package/dist/user-event/text.js.map +1 -1
- package/dist/wait-for.d.ts +2 -0
- package/dist/wait-for.d.ts.map +1 -1
- package/dist/wait-for.js.map +1 -1
- package/dist/widget-accessible-properties.d.ts +14 -10
- package/dist/widget-accessible-properties.d.ts.map +1 -1
- package/dist/widget-accessible-properties.js +135 -173
- package/dist/widget-accessible-properties.js.map +1 -1
- package/dist/widget-getters.d.ts +8 -0
- package/dist/widget-getters.d.ts.map +1 -0
- package/dist/widget-getters.js +19 -0
- package/dist/widget-getters.js.map +1 -0
- package/dist/within.d.ts +3 -2
- package/dist/within.d.ts.map +1 -1
- package/dist/within.js +3 -2
- package/dist/within.js.map +1 -1
- package/package.json +13 -8
- package/src/accessible-native.ts +333 -0
- package/src/act.ts +2 -0
- package/src/build-queries.ts +66 -48
- package/src/cleanup-registry.ts +1 -1
- package/src/config.ts +4 -3
- package/src/errors.ts +14 -3
- package/src/fire-event.ts +61 -8
- package/src/frame-sync.ts +21 -5
- package/src/harness-window.ts +9 -0
- package/src/index.ts +18 -11
- package/src/internal.ts +11 -0
- package/src/matchers.ts +466 -64
- package/src/pretty-format.ts +1 -0
- package/src/pretty-widget.ts +100 -72
- package/src/production.ts +52 -0
- package/src/queries.ts +128 -89
- package/src/query-helpers.ts +97 -0
- package/src/render-children.ts +25 -0
- package/src/render.tsx +18 -13
- package/src/role-helpers.ts +14 -4
- package/src/role-naming.ts +99 -0
- package/src/screenshot.ts +272 -103
- package/src/suggestions.ts +3 -0
- package/src/traversal.ts +49 -6
- package/src/types.ts +69 -19
- package/src/user-event/adjustment.ts +42 -2
- package/src/user-event/click.ts +248 -46
- package/src/user-event/column-header-click.ts +90 -0
- package/src/user-event/controller.ts +29 -0
- package/src/user-event/event-wrapper.ts +3 -1
- package/src/user-event/gesture.ts +57 -6
- package/src/user-event/index.ts +119 -29
- package/src/user-event/indexed-children.ts +75 -0
- package/src/user-event/keyboard.ts +70 -20
- package/src/user-event/list-row-click.ts +57 -0
- package/src/user-event/native-click.ts +46 -0
- package/src/user-event/pointer.ts +52 -13
- package/src/user-event/selection.ts +74 -33
- package/src/user-event/state.ts +2 -2
- package/src/user-event/text.ts +121 -23
- package/src/wait-for.ts +2 -0
- package/src/widget-accessible-properties.ts +183 -214
- package/src/widget-getters.ts +32 -0
- package/src/within.ts +3 -2
package/src/queries.ts
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
getWidgetDescription,
|
|
18
18
|
getWidgetDisplayValue,
|
|
19
19
|
getWidgetExpandedState,
|
|
20
|
-
|
|
20
|
+
getWidgetExternalLabelText,
|
|
21
21
|
getWidgetLabelText,
|
|
22
22
|
getWidgetLevel,
|
|
23
23
|
getWidgetName,
|
|
@@ -25,18 +25,21 @@ import {
|
|
|
25
25
|
getWidgetPlaceholderText,
|
|
26
26
|
getWidgetPressedState,
|
|
27
27
|
getWidgetSelectedState,
|
|
28
|
-
|
|
28
|
+
getWidgetValueText,
|
|
29
29
|
isInaccessible,
|
|
30
30
|
isWidgetChecked,
|
|
31
|
+
isWidgetValueMatch,
|
|
32
|
+
namingLabelText,
|
|
33
|
+
type WidgetValueField,
|
|
31
34
|
} from "./widget-accessible-properties.js";
|
|
32
35
|
|
|
36
|
+
/** The built-in queries in their unbound form, each taking the container to search as its first argument. */
|
|
33
37
|
type BuiltinQueries = QueryFamilies<[container: Container]>;
|
|
34
38
|
|
|
35
39
|
const roleQueries = nameQueryFamily(
|
|
36
40
|
"Role",
|
|
37
41
|
queryAllByRole,
|
|
38
42
|
buildQueries<[role: Gtk.AccessibleRole, options?: ByRoleOptions]>(
|
|
39
|
-
"Role",
|
|
40
43
|
queryAllByRole,
|
|
41
44
|
(container, matches, role, options) =>
|
|
42
45
|
multipleFoundError(container, { queryType: "role", role, options }, matches),
|
|
@@ -48,7 +51,6 @@ const labelTextQueries = nameQueryFamily(
|
|
|
48
51
|
"LabelText",
|
|
49
52
|
queryAllByLabelText,
|
|
50
53
|
buildQueries<[text: Matcher, options?: MatcherOptions]>(
|
|
51
|
-
"LabelText",
|
|
52
54
|
queryAllByLabelText,
|
|
53
55
|
(container, matches, text) => multipleFoundError(container, { queryType: "labelText", text }, matches),
|
|
54
56
|
(container, text) => notFoundError(container, { queryType: "labelText", text }),
|
|
@@ -59,7 +61,6 @@ const textQueries = nameQueryFamily(
|
|
|
59
61
|
"Text",
|
|
60
62
|
queryAllByText,
|
|
61
63
|
buildQueries<[text: Matcher, options?: MatcherOptions]>(
|
|
62
|
-
"Text",
|
|
63
64
|
queryAllByText,
|
|
64
65
|
(container, matches, text) => multipleFoundError(container, { queryType: "text", text }, matches),
|
|
65
66
|
(container, text) => notFoundError(container, { queryType: "text", text }),
|
|
@@ -70,7 +71,6 @@ const nameQueries = nameQueryFamily(
|
|
|
70
71
|
"Name",
|
|
71
72
|
queryAllByName,
|
|
72
73
|
buildQueries<[name: Matcher, options?: MatcherOptions]>(
|
|
73
|
-
"Name",
|
|
74
74
|
queryAllByName,
|
|
75
75
|
(container, matches, name) => multipleFoundError(container, { queryType: "name", name }, matches),
|
|
76
76
|
(container, name) => notFoundError(container, { queryType: "name", name }),
|
|
@@ -81,7 +81,6 @@ const placeholderTextQueries = nameQueryFamily(
|
|
|
81
81
|
"PlaceholderText",
|
|
82
82
|
queryAllByPlaceholderText,
|
|
83
83
|
buildQueries<[text: Matcher, options?: MatcherOptions]>(
|
|
84
|
-
"PlaceholderText",
|
|
85
84
|
queryAllByPlaceholderText,
|
|
86
85
|
(container, matches, text) => multipleFoundError(container, { queryType: "placeholderText", text }, matches),
|
|
87
86
|
(container, text) => notFoundError(container, { queryType: "placeholderText", text }),
|
|
@@ -92,7 +91,6 @@ const displayValueQueries = nameQueryFamily(
|
|
|
92
91
|
"DisplayValue",
|
|
93
92
|
queryAllByDisplayValue,
|
|
94
93
|
buildQueries<[value: Matcher, options?: MatcherOptions]>(
|
|
95
|
-
"DisplayValue",
|
|
96
94
|
queryAllByDisplayValue,
|
|
97
95
|
(container, matches, value) => multipleFoundError(container, { queryType: "displayValue", value }, matches),
|
|
98
96
|
(container, value) => notFoundError(container, { queryType: "displayValue", value }),
|
|
@@ -109,120 +107,159 @@ const builtinQueries = {
|
|
|
109
107
|
} as BuiltinQueries;
|
|
110
108
|
|
|
111
109
|
/**
|
|
112
|
-
* Returns the single widget with a matching accessible role and options, or null when none
|
|
113
|
-
* Throws when more than one matches.
|
|
110
|
+
* Returns the single mapped widget with a matching accessible role and options, or null when none
|
|
111
|
+
* match. Widgets that are not mapped are never matched. Throws when more than one matches.
|
|
114
112
|
*/
|
|
115
113
|
const queryByRole: BuiltinQueries["queryByRole"] = builtinQueries.queryByRole;
|
|
116
|
-
/**
|
|
114
|
+
/**
|
|
115
|
+
* Returns every mapped widget with a matching accessible role and options. Widgets that are not
|
|
116
|
+
* mapped are never matched. Throws when none match.
|
|
117
|
+
*/
|
|
117
118
|
const getAllByRole: BuiltinQueries["getAllByRole"] = builtinQueries.getAllByRole;
|
|
118
119
|
/**
|
|
119
|
-
* Returns the single widget with a matching accessible role and options.
|
|
120
|
-
* Throws when none or more than one matches.
|
|
120
|
+
* Returns the single mapped widget with a matching accessible role and options. Widgets that are not
|
|
121
|
+
* mapped are never matched. Throws when none or more than one matches.
|
|
121
122
|
*/
|
|
122
123
|
const getByRole: BuiltinQueries["getByRole"] = builtinQueries.getByRole;
|
|
123
124
|
/**
|
|
124
|
-
* Waits for and returns every widget with a matching accessible role and options, retrying
|
|
125
|
-
* least one appears or the timeout elapses.
|
|
125
|
+
* Waits for and returns every mapped widget with a matching accessible role and options, retrying
|
|
126
|
+
* until at least one appears or the timeout elapses. Widgets that are not mapped are never matched.
|
|
126
127
|
*/
|
|
127
128
|
const findAllByRole: BuiltinQueries["findAllByRole"] = builtinQueries.findAllByRole;
|
|
128
129
|
/**
|
|
129
|
-
* Waits for and returns the single widget with a matching accessible role and options,
|
|
130
|
-
* until it appears or the timeout elapses.
|
|
130
|
+
* Waits for and returns the single mapped widget with a matching accessible role and options,
|
|
131
|
+
* retrying until it appears or the timeout elapses. Widgets that are not mapped are never matched.
|
|
132
|
+
* Rejects when none or more than one matches.
|
|
131
133
|
*/
|
|
132
134
|
const findByRole: BuiltinQueries["findByRole"] = builtinQueries.findByRole;
|
|
133
135
|
/**
|
|
134
|
-
* Returns the single widget with matching associated label text, or null when none match.
|
|
135
|
-
* Throws when more than one matches.
|
|
136
|
+
* Returns the single mapped widget with matching associated label text, or null when none match.
|
|
137
|
+
* Widgets that are not mapped are never matched. Throws when more than one matches.
|
|
136
138
|
*/
|
|
137
139
|
const queryByLabelText: BuiltinQueries["queryByLabelText"] = builtinQueries.queryByLabelText;
|
|
138
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* Returns every mapped widget with matching associated label text. Widgets that are not mapped are
|
|
142
|
+
* never matched. Throws when none match.
|
|
143
|
+
*/
|
|
139
144
|
const getAllByLabelText: BuiltinQueries["getAllByLabelText"] = builtinQueries.getAllByLabelText;
|
|
140
|
-
/**
|
|
145
|
+
/**
|
|
146
|
+
* Returns the single mapped widget with matching associated label text. Widgets that are not mapped
|
|
147
|
+
* are never matched. Throws when none or more than one matches.
|
|
148
|
+
*/
|
|
141
149
|
const getByLabelText: BuiltinQueries["getByLabelText"] = builtinQueries.getByLabelText;
|
|
142
150
|
/**
|
|
143
|
-
* Waits for and returns every widget with matching associated label text, retrying until at
|
|
144
|
-
* one appears or the timeout elapses.
|
|
151
|
+
* Waits for and returns every mapped widget with matching associated label text, retrying until at
|
|
152
|
+
* least one appears or the timeout elapses. Widgets that are not mapped are never matched.
|
|
145
153
|
*/
|
|
146
154
|
const findAllByLabelText: BuiltinQueries["findAllByLabelText"] = builtinQueries.findAllByLabelText;
|
|
147
155
|
/**
|
|
148
|
-
* Waits for and returns the single widget with matching associated label text, retrying until
|
|
149
|
-
* appears or the timeout elapses.
|
|
156
|
+
* Waits for and returns the single mapped widget with matching associated label text, retrying until
|
|
157
|
+
* it appears or the timeout elapses. Widgets that are not mapped are never matched. Rejects when
|
|
158
|
+
* none or more than one matches.
|
|
150
159
|
*/
|
|
151
160
|
const findByLabelText: BuiltinQueries["findByLabelText"] = builtinQueries.findByLabelText;
|
|
152
161
|
/**
|
|
153
|
-
* Returns the single widget with matching rendered text content, or null when none match.
|
|
154
|
-
* Throws when more than one matches.
|
|
162
|
+
* Returns the single mapped widget with matching rendered text content, or null when none match.
|
|
163
|
+
* Widgets that are not mapped are never matched. Throws when more than one matches.
|
|
155
164
|
*/
|
|
156
165
|
const queryByText: BuiltinQueries["queryByText"] = builtinQueries.queryByText;
|
|
157
|
-
/**
|
|
166
|
+
/**
|
|
167
|
+
* Returns every mapped widget with matching rendered text content. Widgets that are not mapped are
|
|
168
|
+
* never matched. Throws when none match.
|
|
169
|
+
*/
|
|
158
170
|
const getAllByText: BuiltinQueries["getAllByText"] = builtinQueries.getAllByText;
|
|
159
|
-
/**
|
|
171
|
+
/**
|
|
172
|
+
* Returns the single mapped widget with matching rendered text content. Widgets that are not mapped
|
|
173
|
+
* are never matched. Throws when none or more than one matches.
|
|
174
|
+
*/
|
|
160
175
|
const getByText: BuiltinQueries["getByText"] = builtinQueries.getByText;
|
|
161
176
|
/**
|
|
162
|
-
* Waits for and returns every widget with matching rendered text content, retrying until at
|
|
163
|
-
* one appears or the timeout elapses.
|
|
177
|
+
* Waits for and returns every mapped widget with matching rendered text content, retrying until at
|
|
178
|
+
* least one appears or the timeout elapses. Widgets that are not mapped are never matched.
|
|
164
179
|
*/
|
|
165
180
|
const findAllByText: BuiltinQueries["findAllByText"] = builtinQueries.findAllByText;
|
|
166
181
|
/**
|
|
167
|
-
* Waits for and returns the single widget with matching rendered text content, retrying until
|
|
168
|
-
* appears or the timeout elapses.
|
|
182
|
+
* Waits for and returns the single mapped widget with matching rendered text content, retrying until
|
|
183
|
+
* it appears or the timeout elapses. Widgets that are not mapped are never matched. Rejects when
|
|
184
|
+
* none or more than one matches.
|
|
169
185
|
*/
|
|
170
186
|
const findByText: BuiltinQueries["findByText"] = builtinQueries.findByText;
|
|
171
187
|
/**
|
|
172
|
-
* Returns the single widget with a matching widget name, or null when none match.
|
|
173
|
-
* Throws when more than one matches.
|
|
188
|
+
* Returns the single mapped widget with a matching widget name, or null when none match. Widgets
|
|
189
|
+
* that are not mapped are never matched. Throws when more than one matches.
|
|
174
190
|
*/
|
|
175
191
|
const queryByName: BuiltinQueries["queryByName"] = builtinQueries.queryByName;
|
|
176
|
-
/**
|
|
192
|
+
/**
|
|
193
|
+
* Returns every mapped widget with a matching widget name. Widgets that are not mapped are never
|
|
194
|
+
* matched. Throws when none match.
|
|
195
|
+
*/
|
|
177
196
|
const getAllByName: BuiltinQueries["getAllByName"] = builtinQueries.getAllByName;
|
|
178
|
-
/**
|
|
197
|
+
/**
|
|
198
|
+
* Returns the single mapped widget with a matching widget name. Widgets that are not mapped are
|
|
199
|
+
* never matched. Throws when none or more than one matches.
|
|
200
|
+
*/
|
|
179
201
|
const getByName: BuiltinQueries["getByName"] = builtinQueries.getByName;
|
|
180
202
|
/**
|
|
181
|
-
* Waits for and returns every widget with a matching widget name, retrying until at least one
|
|
182
|
-
* appears or the timeout elapses.
|
|
203
|
+
* Waits for and returns every mapped widget with a matching widget name, retrying until at least one
|
|
204
|
+
* appears or the timeout elapses. Widgets that are not mapped are never matched.
|
|
183
205
|
*/
|
|
184
206
|
const findAllByName: BuiltinQueries["findAllByName"] = builtinQueries.findAllByName;
|
|
185
207
|
/**
|
|
186
|
-
* Waits for and returns the single widget with a matching widget name, retrying until it
|
|
187
|
-
* the timeout elapses.
|
|
208
|
+
* Waits for and returns the single mapped widget with a matching widget name, retrying until it
|
|
209
|
+
* appears or the timeout elapses. Widgets that are not mapped are never matched. Rejects when none
|
|
210
|
+
* or more than one matches.
|
|
188
211
|
*/
|
|
189
212
|
const findByName: BuiltinQueries["findByName"] = builtinQueries.findByName;
|
|
190
213
|
/**
|
|
191
|
-
* Returns the single widget with matching placeholder text, or null when none match.
|
|
192
|
-
* Throws when more than one matches.
|
|
214
|
+
* Returns the single mapped widget with matching placeholder text, or null when none match. Widgets
|
|
215
|
+
* that are not mapped are never matched. Throws when more than one matches.
|
|
193
216
|
*/
|
|
194
217
|
const queryByPlaceholderText: BuiltinQueries["queryByPlaceholderText"] = builtinQueries.queryByPlaceholderText;
|
|
195
|
-
/**
|
|
218
|
+
/**
|
|
219
|
+
* Returns every mapped widget with matching placeholder text. Widgets that are not mapped are never
|
|
220
|
+
* matched. Throws when none match.
|
|
221
|
+
*/
|
|
196
222
|
const getAllByPlaceholderText: BuiltinQueries["getAllByPlaceholderText"] = builtinQueries.getAllByPlaceholderText;
|
|
197
|
-
/**
|
|
223
|
+
/**
|
|
224
|
+
* Returns the single mapped widget with matching placeholder text. Widgets that are not mapped are
|
|
225
|
+
* never matched. Throws when none or more than one matches.
|
|
226
|
+
*/
|
|
198
227
|
const getByPlaceholderText: BuiltinQueries["getByPlaceholderText"] = builtinQueries.getByPlaceholderText;
|
|
199
228
|
/**
|
|
200
|
-
* Waits for and returns every widget with matching placeholder text, retrying until at least
|
|
201
|
-
* appears or the timeout elapses.
|
|
229
|
+
* Waits for and returns every mapped widget with matching placeholder text, retrying until at least
|
|
230
|
+
* one appears or the timeout elapses. Widgets that are not mapped are never matched.
|
|
202
231
|
*/
|
|
203
232
|
const findAllByPlaceholderText: BuiltinQueries["findAllByPlaceholderText"] = builtinQueries.findAllByPlaceholderText;
|
|
204
233
|
/**
|
|
205
|
-
* Waits for and returns the single widget with matching placeholder text, retrying until it
|
|
206
|
-
* or the timeout elapses.
|
|
234
|
+
* Waits for and returns the single mapped widget with matching placeholder text, retrying until it
|
|
235
|
+
* appears or the timeout elapses. Widgets that are not mapped are never matched. Rejects when none
|
|
236
|
+
* or more than one matches.
|
|
207
237
|
*/
|
|
208
238
|
const findByPlaceholderText: BuiltinQueries["findByPlaceholderText"] = builtinQueries.findByPlaceholderText;
|
|
209
239
|
/**
|
|
210
|
-
* Returns the single widget with a matching display value, or null when none match.
|
|
211
|
-
* Throws when more than one matches.
|
|
240
|
+
* Returns the single mapped widget with a matching display value, or null when none match. Widgets
|
|
241
|
+
* that are not mapped are never matched. Throws when more than one matches.
|
|
212
242
|
*/
|
|
213
243
|
const queryByDisplayValue: BuiltinQueries["queryByDisplayValue"] = builtinQueries.queryByDisplayValue;
|
|
214
|
-
/**
|
|
244
|
+
/**
|
|
245
|
+
* Returns every mapped widget with a matching display value. Widgets that are not mapped are never
|
|
246
|
+
* matched. Throws when none match.
|
|
247
|
+
*/
|
|
215
248
|
const getAllByDisplayValue: BuiltinQueries["getAllByDisplayValue"] = builtinQueries.getAllByDisplayValue;
|
|
216
|
-
/**
|
|
249
|
+
/**
|
|
250
|
+
* Returns the single mapped widget with a matching display value. Widgets that are not mapped are
|
|
251
|
+
* never matched. Throws when none or more than one matches.
|
|
252
|
+
*/
|
|
217
253
|
const getByDisplayValue: BuiltinQueries["getByDisplayValue"] = builtinQueries.getByDisplayValue;
|
|
218
254
|
/**
|
|
219
|
-
* Waits for and returns every widget with a matching display value, retrying until at least
|
|
220
|
-
* appears or the timeout elapses.
|
|
255
|
+
* Waits for and returns every mapped widget with a matching display value, retrying until at least
|
|
256
|
+
* one appears or the timeout elapses. Widgets that are not mapped are never matched.
|
|
221
257
|
*/
|
|
222
258
|
const findAllByDisplayValue: BuiltinQueries["findAllByDisplayValue"] = builtinQueries.findAllByDisplayValue;
|
|
223
259
|
/**
|
|
224
|
-
* Waits for and returns the single widget with a matching display value, retrying until it
|
|
225
|
-
* or the timeout elapses.
|
|
260
|
+
* Waits for and returns the single mapped widget with a matching display value, retrying until it
|
|
261
|
+
* appears or the timeout elapses. Widgets that are not mapped are never matched. Rejects when none
|
|
262
|
+
* or more than one matches.
|
|
226
263
|
*/
|
|
227
264
|
const findByDisplayValue: BuiltinQueries["findByDisplayValue"] = builtinQueries.findByDisplayValue;
|
|
228
265
|
|
|
@@ -290,25 +327,23 @@ const hasMatchingAccessibleName = (widget: Gtk.Widget, options: ByRoleOptions):
|
|
|
290
327
|
return isTextMatch(text, options.name, widget, options);
|
|
291
328
|
};
|
|
292
329
|
|
|
293
|
-
const isNumericValueMatch = (
|
|
294
|
-
expected === undefined ||
|
|
330
|
+
const isNumericValueMatch = (widget: Gtk.Widget, field: WidgetValueField, expected: number | undefined): boolean =>
|
|
331
|
+
expected === undefined || isWidgetValueMatch(widget, field, expected);
|
|
295
332
|
|
|
296
333
|
const hasMatchingAccessibleValue = (widget: Gtk.Widget, value: ByRoleValue, options: ByRoleOptions): boolean => {
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
[
|
|
301
|
-
[value.min, actual.min],
|
|
302
|
-
[value.max, actual.max],
|
|
334
|
+
const numericChecks: [WidgetValueField, number | undefined][] = [
|
|
335
|
+
["now", value.now],
|
|
336
|
+
["min", value.min],
|
|
337
|
+
["max", value.max],
|
|
303
338
|
];
|
|
304
339
|
|
|
305
|
-
for (const [
|
|
306
|
-
if (!isNumericValueMatch(
|
|
340
|
+
for (const [field, expected] of numericChecks) {
|
|
341
|
+
if (!isNumericValueMatch(widget, field, expected)) {
|
|
307
342
|
return false;
|
|
308
343
|
}
|
|
309
344
|
}
|
|
310
345
|
|
|
311
|
-
return value.text === undefined || isTextMatch(
|
|
346
|
+
return value.text === undefined || isTextMatch(getWidgetValueText(widget), value.text, widget, options);
|
|
312
347
|
};
|
|
313
348
|
|
|
314
349
|
const hasMatchingBooleanStates = (widget: Gtk.Widget, options: ByRoleOptions): boolean => {
|
|
@@ -365,19 +400,22 @@ function nameQueryFamily<Args extends unknown[]>(
|
|
|
365
400
|
queryAllBy: QueryAllBy<Args>,
|
|
366
401
|
built: BuiltQueries<Args>,
|
|
367
402
|
): Record<string, unknown> {
|
|
403
|
+
const [queryBy, getAllBy, getBy, findAllBy, findBy] = built;
|
|
404
|
+
|
|
368
405
|
return {
|
|
369
|
-
[`queryBy${suffix}`]:
|
|
406
|
+
[`queryBy${suffix}`]: queryBy,
|
|
370
407
|
[`queryAllBy${suffix}`]: queryAllBy,
|
|
371
|
-
[`getBy${suffix}`]:
|
|
372
|
-
[`getAllBy${suffix}`]:
|
|
373
|
-
[`findBy${suffix}`]:
|
|
374
|
-
[`findAllBy${suffix}`]:
|
|
408
|
+
[`getBy${suffix}`]: getBy,
|
|
409
|
+
[`getAllBy${suffix}`]: getAllBy,
|
|
410
|
+
[`findBy${suffix}`]: findBy,
|
|
411
|
+
[`findAllBy${suffix}`]: findAllBy,
|
|
375
412
|
};
|
|
376
413
|
}
|
|
377
414
|
|
|
378
415
|
/**
|
|
379
416
|
* Finds every widget under the container whose accessible role matches `role` and that satisfies the given options.
|
|
380
|
-
* Widgets excluded from the accessibility tree are
|
|
417
|
+
* Widgets that are not mapped are never matched, and widgets excluded from the accessibility tree are
|
|
418
|
+
* skipped unless `options.hidden` is set.
|
|
381
419
|
* @param container Widget subtree to search.
|
|
382
420
|
* @param role Accessible role to match.
|
|
383
421
|
* @param options Additional accessible name, state, and value constraints.
|
|
@@ -410,7 +448,7 @@ const collectMnemonicMatch = (
|
|
|
410
448
|
return null;
|
|
411
449
|
}
|
|
412
450
|
|
|
413
|
-
const labelText = widget
|
|
451
|
+
const labelText = namingLabelText(widget);
|
|
414
452
|
|
|
415
453
|
if (!labelText || !isTextMatch(labelText, text, widget, options)) {
|
|
416
454
|
return null;
|
|
@@ -419,6 +457,12 @@ const collectMnemonicMatch = (
|
|
|
419
457
|
return widget.getMnemonicWidget();
|
|
420
458
|
};
|
|
421
459
|
|
|
460
|
+
const labellingText = (widget: Gtk.Widget): string | null => {
|
|
461
|
+
const ownLabel = widget.getAccessibleRole() === Gtk.AccessibleRole.LABEL ? null : getWidgetOwnLabel(widget);
|
|
462
|
+
|
|
463
|
+
return ownLabel ?? getWidgetExternalLabelText(widget);
|
|
464
|
+
};
|
|
465
|
+
|
|
422
466
|
const collectLabelMatches = (
|
|
423
467
|
results: Set<Gtk.Widget>,
|
|
424
468
|
widget: Gtk.Widget,
|
|
@@ -431,22 +475,16 @@ const collectLabelMatches = (
|
|
|
431
475
|
results.add(mnemonicTarget);
|
|
432
476
|
}
|
|
433
477
|
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
if (ownLabel !== null && isTextMatch(ownLabel, text, widget, options)) {
|
|
437
|
-
results.add(widget);
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
const labelledByText = getWidgetLabelledByText(widget);
|
|
478
|
+
const labelText = labellingText(widget);
|
|
441
479
|
|
|
442
|
-
if (
|
|
480
|
+
if (labelText !== null && isTextMatch(labelText, text, widget, options)) {
|
|
443
481
|
results.add(widget);
|
|
444
482
|
}
|
|
445
483
|
};
|
|
446
484
|
|
|
447
485
|
/**
|
|
448
486
|
* Finds every widget associated with a label whose text matches: a Gtk.Label mnemonic target, the
|
|
449
|
-
* widget's own accessible label, or its labelled-by relation.
|
|
487
|
+
* widget's own accessible label, or its labelled-by relation. Widgets that are not mapped are never matched.
|
|
450
488
|
* @param container Widget subtree to search.
|
|
451
489
|
* @param text Matcher for the label text.
|
|
452
490
|
* @param options Text matching options.
|
|
@@ -463,7 +501,7 @@ function queryAllByLabelText(container: Container, text: Matcher, options?: Matc
|
|
|
463
501
|
}
|
|
464
502
|
|
|
465
503
|
/**
|
|
466
|
-
* Finds every widget whose rendered text content matches.
|
|
504
|
+
* Finds every widget whose rendered text content matches. Widgets that are not mapped are never matched.
|
|
467
505
|
* @param container Widget subtree to search.
|
|
468
506
|
* @param text Matcher for the widget text.
|
|
469
507
|
* @param options Text matching options.
|
|
@@ -478,7 +516,7 @@ function queryAllByText(container: Container, text: Matcher, options?: MatcherOp
|
|
|
478
516
|
}
|
|
479
517
|
|
|
480
518
|
/**
|
|
481
|
-
* Finds every widget whose widget name matches.
|
|
519
|
+
* Finds every widget whose widget name matches. Widgets that are not mapped are never matched.
|
|
482
520
|
* @param container Widget subtree to search.
|
|
483
521
|
* @param name Matcher for the widget name.
|
|
484
522
|
* @param options Text matching options.
|
|
@@ -492,7 +530,7 @@ function queryAllByName(container: Container, name: Matcher, options?: MatcherOp
|
|
|
492
530
|
}
|
|
493
531
|
|
|
494
532
|
/**
|
|
495
|
-
* Finds every widget whose placeholder text matches.
|
|
533
|
+
* Finds every widget whose placeholder text matches. Widgets that are not mapped are never matched.
|
|
496
534
|
* @param container Widget subtree to search.
|
|
497
535
|
* @param text Matcher for the placeholder text.
|
|
498
536
|
* @param options Text matching options.
|
|
@@ -512,7 +550,7 @@ function queryAllByPlaceholderText(
|
|
|
512
550
|
}
|
|
513
551
|
|
|
514
552
|
/**
|
|
515
|
-
* Finds every widget whose current display value matches.
|
|
553
|
+
* Finds every widget whose current display value matches. Widgets that are not mapped are never matched.
|
|
516
554
|
* @param container Widget subtree to search.
|
|
517
555
|
* @param value Matcher for the display value.
|
|
518
556
|
* @param options Text matching options.
|
|
@@ -529,6 +567,8 @@ function queryAllByDisplayValue(container: Container, value: Matcher, options?:
|
|
|
529
567
|
|
|
530
568
|
export {
|
|
531
569
|
builtinQueries,
|
|
570
|
+
isMatchingWidgetType,
|
|
571
|
+
isTextMatch,
|
|
532
572
|
queryByRole,
|
|
533
573
|
getAllByRole,
|
|
534
574
|
getByRole,
|
|
@@ -565,5 +605,4 @@ export {
|
|
|
565
605
|
queryAllByName,
|
|
566
606
|
queryAllByPlaceholderText,
|
|
567
607
|
queryAllByDisplayValue,
|
|
568
|
-
type BuiltinQueries,
|
|
569
608
|
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type * as Gtk from "@gtkx/gi/gtk";
|
|
2
|
+
import { camelCase } from "@gtkx/utils";
|
|
3
|
+
import type { Matcher, MatcherOptions } from "./types.js";
|
|
4
|
+
import { buildQueries } from "./build-queries.js";
|
|
5
|
+
import { getElementError } from "./errors.js";
|
|
6
|
+
import { isMatchingWidgetType, isTextMatch } from "./queries.js";
|
|
7
|
+
import { type Container, findAll } from "./traversal.js";
|
|
8
|
+
|
|
9
|
+
/** The helpers used to build custom queries, bundled the way DOM Testing Library exposes them. */
|
|
10
|
+
type QueryHelpers = {
|
|
11
|
+
/** Derives a query family's variants from its `queryAllBy` function. */
|
|
12
|
+
buildQueries: typeof buildQueries;
|
|
13
|
+
/** Builds the error a failing query throws. */
|
|
14
|
+
getElementError: typeof getElementError;
|
|
15
|
+
/** Finds every widget whose GObject property matches. */
|
|
16
|
+
queryAllByObjectProperty: typeof queryAllByObjectProperty;
|
|
17
|
+
/** Finds the single widget whose GObject property matches. */
|
|
18
|
+
queryByObjectProperty: typeof queryByObjectProperty;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/** The query-building helpers, bundled so they can be reached under a single import. */
|
|
22
|
+
const queryHelpers: QueryHelpers = {
|
|
23
|
+
buildQueries,
|
|
24
|
+
getElementError,
|
|
25
|
+
queryAllByObjectProperty,
|
|
26
|
+
queryByObjectProperty,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const readObjectProperty = (widget: Gtk.Widget, property: string): string | null => {
|
|
30
|
+
const value: unknown = Reflect.get(widget, camelCase(property));
|
|
31
|
+
|
|
32
|
+
if (typeof value === "string") {
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
37
|
+
return String(value);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return null;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Finds every widget carrying a GObject property whose value matches, the counterpart of DOM Testing
|
|
45
|
+
* Library's `queryAllByAttribute`. The property name may be given in kebab-case or camelCase, and
|
|
46
|
+
* widgets that are not mapped are never matched.
|
|
47
|
+
*
|
|
48
|
+
* @param property Name of the GObject property to read.
|
|
49
|
+
* @param container Widget subtree to search.
|
|
50
|
+
* @param text Matcher for the property's value.
|
|
51
|
+
* @param options Text matching options.
|
|
52
|
+
* @returns Every matching widget, or an empty array when none match.
|
|
53
|
+
*/
|
|
54
|
+
function queryAllByObjectProperty(
|
|
55
|
+
property: string,
|
|
56
|
+
container: Container,
|
|
57
|
+
text: Matcher,
|
|
58
|
+
options?: MatcherOptions,
|
|
59
|
+
): Gtk.Widget[] {
|
|
60
|
+
return findAll(
|
|
61
|
+
container,
|
|
62
|
+
(widget) =>
|
|
63
|
+
isMatchingWidgetType(widget, options) &&
|
|
64
|
+
isTextMatch(readObjectProperty(widget, property), text, widget, options),
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Returns the single widget carrying a GObject property whose value matches, or null when none do,
|
|
70
|
+
* the counterpart of DOM Testing Library's `queryByAttribute`.
|
|
71
|
+
*
|
|
72
|
+
* @param property Name of the GObject property to read.
|
|
73
|
+
* @param container Widget subtree to search.
|
|
74
|
+
* @param text Matcher for the property's value.
|
|
75
|
+
* @param options Text matching options.
|
|
76
|
+
* @returns The matching widget, or null when none match.
|
|
77
|
+
* @throws When more than one widget matches.
|
|
78
|
+
*/
|
|
79
|
+
function queryByObjectProperty(
|
|
80
|
+
property: string,
|
|
81
|
+
container: Container,
|
|
82
|
+
text: Matcher,
|
|
83
|
+
options?: MatcherOptions,
|
|
84
|
+
): Gtk.Widget | null {
|
|
85
|
+
const matches = queryAllByObjectProperty(property, container, text, options);
|
|
86
|
+
|
|
87
|
+
if (matches.length > 1) {
|
|
88
|
+
throw getElementError(
|
|
89
|
+
`Found ${String(matches.length)} elements with the '${property}' property, but expected only one`,
|
|
90
|
+
container,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return matches[0] ?? null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export { queryAllByObjectProperty, queryByObjectProperty, queryHelpers, type QueryHelpers };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { RenderOptions } from "./types.js";
|
|
3
|
+
import { render } from "./render.js";
|
|
4
|
+
|
|
5
|
+
type ChildrenBuilder<T> = (items: T[]) => ReactNode;
|
|
6
|
+
|
|
7
|
+
type RenderChildrenResult<T> = {
|
|
8
|
+
rerender: (items: T[]) => Promise<void>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
async function renderChildren<T>(
|
|
12
|
+
initial: T[],
|
|
13
|
+
build: ChildrenBuilder<T>,
|
|
14
|
+
options?: RenderOptions,
|
|
15
|
+
): Promise<RenderChildrenResult<T>> {
|
|
16
|
+
const { rerender } = await render(build(initial), options);
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
rerender: async (items: T[]) => {
|
|
20
|
+
await rerender(build(items));
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { renderChildren, type ChildrenBuilder };
|
package/src/render.tsx
CHANGED
|
@@ -5,23 +5,28 @@ import {
|
|
|
5
5
|
isRootElement,
|
|
6
6
|
type ReconcilerRoot,
|
|
7
7
|
setReconcilerErrorHandler,
|
|
8
|
+
settleAccessible,
|
|
8
9
|
} from "@gtkx/react/internal";
|
|
9
10
|
import { type ErrorInfo, type ReactNode, StrictMode } from "react";
|
|
10
11
|
import type { RenderResult } from "./bound-queries.js";
|
|
11
|
-
import type { QueryMap, RenderOptions, ScreenshotOptions
|
|
12
|
+
import type { QueryMap, RenderOptions, ScreenshotOptions } from "./types.js";
|
|
12
13
|
import { runInAct } from "./act.js";
|
|
13
14
|
import { addToCleanupQueue, runCleanup } from "./cleanup-registry.js";
|
|
14
15
|
import { scheduleAfterLayout } from "./frame-sync.js";
|
|
16
|
+
import { createHarnessWindow } from "./harness-window.js";
|
|
15
17
|
import { logWidget, type PrettyWidgetOptions } from "./pretty-widget.js";
|
|
16
18
|
import { logRoles } from "./role-helpers.js";
|
|
17
19
|
import { clearScreen, setScreen } from "./screen.js";
|
|
18
|
-
import {
|
|
19
|
-
import { type Container,
|
|
20
|
+
import { captureScreen } from "./screenshot.js";
|
|
21
|
+
import { type Container, roots, TOPLEVELS } from "./traversal.js";
|
|
20
22
|
import { resetClipboard } from "./user-event/index.js";
|
|
21
23
|
import { within } from "./within.js";
|
|
22
24
|
|
|
25
|
+
/** A mounted render tracked so cleanup can unmount it. */
|
|
23
26
|
type ActiveRender = {
|
|
27
|
+
/** Root that rerenders drive and that cleanup tears the tree down through. */
|
|
24
28
|
root: ReconcilerRoot;
|
|
29
|
+
/** Harness window created for the render, null when it renders into a container the caller supplied. */
|
|
25
30
|
window: Gtk.Window | null;
|
|
26
31
|
};
|
|
27
32
|
|
|
@@ -37,12 +42,13 @@ type ReconcilerErrorState = {
|
|
|
37
42
|
|
|
38
43
|
const reconcilerErrors: ReconcilerErrorState = { lastError: null, isHandlerInstalled: false };
|
|
39
44
|
const activeRenders: Set<ActiveRender> = new Set();
|
|
40
|
-
const HARNESS_WINDOW_WIDTH = 800;
|
|
41
|
-
const HARNESS_WINDOW_HEIGHT = 600;
|
|
42
45
|
|
|
43
46
|
const flushLayout = (window: Gtk.Window | null): Promise<void> =>
|
|
44
|
-
new Promise((resolve) => {
|
|
45
|
-
scheduleAfterLayout(window,
|
|
47
|
+
new Promise<void>((resolve) => {
|
|
48
|
+
scheduleAfterLayout(window, () => {
|
|
49
|
+
settleAccessible();
|
|
50
|
+
resolve();
|
|
51
|
+
});
|
|
46
52
|
});
|
|
47
53
|
|
|
48
54
|
const update = async (element: ReactNode, root: ReconcilerRoot): Promise<void> => {
|
|
@@ -96,7 +102,7 @@ const resolveContainer = (container: RenderOptions["container"]): ResolvedContai
|
|
|
96
102
|
return { containerInfo: container, window: null };
|
|
97
103
|
}
|
|
98
104
|
|
|
99
|
-
const window =
|
|
105
|
+
const window = createHarnessWindow();
|
|
100
106
|
window.setDecorated(false);
|
|
101
107
|
|
|
102
108
|
return { containerInfo: window, window };
|
|
@@ -107,7 +113,7 @@ const firstToplevelWidget = (baseElement: Container): Gtk.Widget => {
|
|
|
107
113
|
return baseElement;
|
|
108
114
|
}
|
|
109
115
|
|
|
110
|
-
const [first] =
|
|
116
|
+
const [first] = roots(baseElement);
|
|
111
117
|
|
|
112
118
|
if (first) {
|
|
113
119
|
return first;
|
|
@@ -165,7 +171,7 @@ const render = async <Q extends QueryMap = Record<never, never>>(
|
|
|
165
171
|
options?: RenderOptions<Q>,
|
|
166
172
|
): Promise<RenderResult<Q>> => {
|
|
167
173
|
installErrorHandler();
|
|
168
|
-
applyEnableAnimations(options?.
|
|
174
|
+
applyEnableAnimations(options?.areAnimationsEnabled === true);
|
|
169
175
|
const baseElement: Container = options?.baseElement ?? TOPLEVELS;
|
|
170
176
|
const Wrapper = options?.wrapper;
|
|
171
177
|
const resolved = resolveContainer(options?.container);
|
|
@@ -184,7 +190,7 @@ const render = async <Q extends QueryMap = Record<never, never>>(
|
|
|
184
190
|
const wrap = (node: ReactNode): ReactNode => {
|
|
185
191
|
const wrapped = Wrapper ? <Wrapper>{node}</Wrapper> : node;
|
|
186
192
|
|
|
187
|
-
return options?.
|
|
193
|
+
return options?.isReactStrictMode ? <StrictMode>{wrapped}</StrictMode> : wrapped;
|
|
188
194
|
};
|
|
189
195
|
|
|
190
196
|
await update(wrap(element), root);
|
|
@@ -209,8 +215,7 @@ const render = async <Q extends QueryMap = Record<never, never>>(
|
|
|
209
215
|
logRoles: () => {
|
|
210
216
|
logRoles(baseElement);
|
|
211
217
|
},
|
|
212
|
-
screenshot: (
|
|
213
|
-
captureAndSaveScreenshot(selector, screenshotOptions),
|
|
218
|
+
screenshot: (screenshotOptions?: ScreenshotOptions) => captureScreen(screenshotOptions),
|
|
214
219
|
};
|
|
215
220
|
|
|
216
221
|
setScreen(result);
|