@gtkx/testing 1.0.0-rc.4 → 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.
Files changed (182) hide show
  1. package/README.md +5 -5
  2. package/dist/accessible-native.d.ts +16 -0
  3. package/dist/accessible-native.d.ts.map +1 -0
  4. package/dist/accessible-native.js +206 -0
  5. package/dist/accessible-native.js.map +1 -0
  6. package/dist/build-queries.d.ts +27 -10
  7. package/dist/build-queries.d.ts.map +1 -1
  8. package/dist/build-queries.js +22 -24
  9. package/dist/build-queries.js.map +1 -1
  10. package/dist/cleanup-registry.d.ts +1 -1
  11. package/dist/cleanup-registry.d.ts.map +1 -1
  12. package/dist/cleanup-registry.js.map +1 -1
  13. package/dist/errors.d.ts +10 -1
  14. package/dist/errors.d.ts.map +1 -1
  15. package/dist/errors.js +10 -1
  16. package/dist/errors.js.map +1 -1
  17. package/dist/fire-event.d.ts +35 -6
  18. package/dist/fire-event.d.ts.map +1 -1
  19. package/dist/fire-event.js +23 -7
  20. package/dist/fire-event.js.map +1 -1
  21. package/dist/frame-sync.d.ts +2 -1
  22. package/dist/frame-sync.d.ts.map +1 -1
  23. package/dist/frame-sync.js +15 -5
  24. package/dist/frame-sync.js.map +1 -1
  25. package/dist/harness-window.d.ts +4 -0
  26. package/dist/harness-window.d.ts.map +1 -0
  27. package/dist/harness-window.js +6 -0
  28. package/dist/harness-window.js.map +1 -0
  29. package/dist/index.d.ts +14 -7
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +9 -5
  32. package/dist/index.js.map +1 -1
  33. package/dist/internal.d.ts +4 -0
  34. package/dist/internal.d.ts.map +1 -0
  35. package/dist/internal.js +4 -0
  36. package/dist/internal.js.map +1 -0
  37. package/dist/matchers.d.ts +88 -46
  38. package/dist/matchers.d.ts.map +1 -1
  39. package/dist/matchers.js +156 -18
  40. package/dist/matchers.js.map +1 -1
  41. package/dist/pretty-format.d.ts +2 -0
  42. package/dist/pretty-format.d.ts.map +1 -0
  43. package/dist/pretty-format.js +2 -0
  44. package/dist/pretty-format.js.map +1 -0
  45. package/dist/pretty-widget.d.ts +5 -2
  46. package/dist/pretty-widget.d.ts.map +1 -1
  47. package/dist/pretty-widget.js +73 -56
  48. package/dist/pretty-widget.js.map +1 -1
  49. package/dist/production.d.ts +8 -0
  50. package/dist/production.d.ts.map +1 -0
  51. package/dist/production.js +34 -0
  52. package/dist/production.js.map +1 -0
  53. package/dist/queries.d.ts +98 -56
  54. package/dist/queries.d.ts.map +1 -1
  55. package/dist/queries.js +123 -83
  56. package/dist/queries.js.map +1 -1
  57. package/dist/query-helpers.d.ts +44 -0
  58. package/dist/query-helpers.d.ts.map +1 -0
  59. package/dist/query-helpers.js +57 -0
  60. package/dist/query-helpers.js.map +1 -0
  61. package/dist/render-children.d.ts +9 -0
  62. package/dist/render-children.d.ts.map +1 -0
  63. package/dist/render-children.js +11 -0
  64. package/dist/render-children.js.map +1 -0
  65. package/dist/render.d.ts.map +1 -1
  66. package/dist/render.js +11 -9
  67. package/dist/render.js.map +1 -1
  68. package/dist/role-helpers.d.ts +12 -3
  69. package/dist/role-helpers.d.ts.map +1 -1
  70. package/dist/role-helpers.js +13 -4
  71. package/dist/role-helpers.js.map +1 -1
  72. package/dist/role-naming.d.ts +5 -0
  73. package/dist/role-naming.d.ts.map +1 -0
  74. package/dist/role-naming.js +96 -0
  75. package/dist/role-naming.js.map +1 -0
  76. package/dist/screenshot.d.ts +12 -20
  77. package/dist/screenshot.d.ts.map +1 -1
  78. package/dist/screenshot.js +183 -91
  79. package/dist/screenshot.js.map +1 -1
  80. package/dist/traversal.d.ts +4 -1
  81. package/dist/traversal.d.ts.map +1 -1
  82. package/dist/traversal.js +25 -6
  83. package/dist/traversal.js.map +1 -1
  84. package/dist/types.d.ts +26 -14
  85. package/dist/types.d.ts.map +1 -1
  86. package/dist/types.js.map +1 -1
  87. package/dist/user-event/adjustment.d.ts +3 -0
  88. package/dist/user-event/adjustment.d.ts.map +1 -1
  89. package/dist/user-event/adjustment.js +23 -2
  90. package/dist/user-event/adjustment.js.map +1 -1
  91. package/dist/user-event/click.d.ts +43 -8
  92. package/dist/user-event/click.d.ts.map +1 -1
  93. package/dist/user-event/click.js +175 -44
  94. package/dist/user-event/click.js.map +1 -1
  95. package/dist/user-event/column-header-click.d.ts +4 -0
  96. package/dist/user-event/column-header-click.d.ts.map +1 -0
  97. package/dist/user-event/column-header-click.js +65 -0
  98. package/dist/user-event/column-header-click.js.map +1 -0
  99. package/dist/user-event/event-wrapper.d.ts.map +1 -1
  100. package/dist/user-event/event-wrapper.js +2 -1
  101. package/dist/user-event/event-wrapper.js.map +1 -1
  102. package/dist/user-event/index.d.ts +51 -10
  103. package/dist/user-event/index.d.ts.map +1 -1
  104. package/dist/user-event/index.js +43 -26
  105. package/dist/user-event/index.js.map +1 -1
  106. package/dist/user-event/indexed-children.d.ts +10 -0
  107. package/dist/user-event/indexed-children.d.ts.map +1 -0
  108. package/dist/user-event/indexed-children.js +50 -0
  109. package/dist/user-event/indexed-children.js.map +1 -0
  110. package/dist/user-event/keyboard.d.ts.map +1 -1
  111. package/dist/user-event/keyboard.js +33 -4
  112. package/dist/user-event/keyboard.js.map +1 -1
  113. package/dist/user-event/list-row-click.d.ts +4 -0
  114. package/dist/user-event/list-row-click.d.ts.map +1 -0
  115. package/dist/user-event/list-row-click.js +39 -0
  116. package/dist/user-event/list-row-click.js.map +1 -0
  117. package/dist/user-event/native-click.d.ts +6 -0
  118. package/dist/user-event/native-click.d.ts.map +1 -0
  119. package/dist/user-event/native-click.js +32 -0
  120. package/dist/user-event/native-click.js.map +1 -0
  121. package/dist/user-event/pointer.d.ts +1 -1
  122. package/dist/user-event/pointer.d.ts.map +1 -1
  123. package/dist/user-event/pointer.js +33 -9
  124. package/dist/user-event/pointer.js.map +1 -1
  125. package/dist/user-event/selection.d.ts +11 -8
  126. package/dist/user-event/selection.d.ts.map +1 -1
  127. package/dist/user-event/selection.js +49 -38
  128. package/dist/user-event/selection.js.map +1 -1
  129. package/dist/user-event/text.d.ts +6 -2
  130. package/dist/user-event/text.d.ts.map +1 -1
  131. package/dist/user-event/text.js +68 -18
  132. package/dist/user-event/text.js.map +1 -1
  133. package/dist/widget-accessible-properties.d.ts +14 -26
  134. package/dist/widget-accessible-properties.d.ts.map +1 -1
  135. package/dist/widget-accessible-properties.js +135 -190
  136. package/dist/widget-accessible-properties.js.map +1 -1
  137. package/dist/widget-getters.d.ts +8 -0
  138. package/dist/widget-getters.d.ts.map +1 -0
  139. package/dist/widget-getters.js +19 -0
  140. package/dist/widget-getters.js.map +1 -0
  141. package/dist/within.d.ts +3 -2
  142. package/dist/within.d.ts.map +1 -1
  143. package/dist/within.js +3 -2
  144. package/dist/within.js.map +1 -1
  145. package/package.json +12 -7
  146. package/src/accessible-native.ts +333 -0
  147. package/src/build-queries.ts +47 -41
  148. package/src/cleanup-registry.ts +1 -1
  149. package/src/errors.ts +12 -1
  150. package/src/fire-event.ts +61 -8
  151. package/src/frame-sync.ts +21 -5
  152. package/src/harness-window.ts +9 -0
  153. package/src/index.ts +18 -11
  154. package/src/internal.ts +11 -0
  155. package/src/matchers.ts +428 -70
  156. package/src/pretty-format.ts +1 -0
  157. package/src/pretty-widget.ts +97 -70
  158. package/src/production.ts +52 -0
  159. package/src/queries.ts +127 -89
  160. package/src/query-helpers.ts +97 -0
  161. package/src/render-children.ts +25 -0
  162. package/src/render.tsx +16 -11
  163. package/src/role-helpers.ts +14 -4
  164. package/src/role-naming.ts +99 -0
  165. package/src/screenshot.ts +272 -103
  166. package/src/traversal.ts +44 -6
  167. package/src/types.ts +28 -16
  168. package/src/user-event/adjustment.ts +29 -2
  169. package/src/user-event/click.ts +247 -52
  170. package/src/user-event/column-header-click.ts +90 -0
  171. package/src/user-event/event-wrapper.ts +3 -1
  172. package/src/user-event/index.ts +100 -37
  173. package/src/user-event/indexed-children.ts +75 -0
  174. package/src/user-event/keyboard.ts +52 -4
  175. package/src/user-event/list-row-click.ts +57 -0
  176. package/src/user-event/native-click.ts +46 -0
  177. package/src/user-event/pointer.ts +48 -9
  178. package/src/user-event/selection.ts +67 -41
  179. package/src/user-event/text.ts +92 -21
  180. package/src/widget-accessible-properties.ts +183 -230
  181. package/src/widget-getters.ts +32 -0
  182. package/src/within.ts +3 -2
@@ -3,56 +3,55 @@ import type { Container } from "./traversal.js";
3
3
  import type { MatcherOptions, WaitForOptions } from "./types.js";
4
4
  import { getConfig } from "./config.js";
5
5
  import { runWithExpensiveErrorDiagnosticsDisabled, suggestionError } from "./errors.js";
6
- import { getSuggestedQuery, type Method, type Variant } from "./suggestions.js";
6
+ import { getSuggestedQuery, type Variant } from "./suggestions.js";
7
7
  import { waitFor } from "./wait-for.js";
8
8
 
9
+ /**
10
+ * The `queryAllBy` function a query family is built from, taking the scope to search followed by the
11
+ * family's own matcher arguments. Its name determines the family name, so `queryAllByTestId` builds
12
+ * a `TestId` family.
13
+ */
9
14
  type QueryAllBy<Args extends unknown[]> = (container: Container, ...args: Args) => Gtk.Widget[];
10
15
 
16
+ /** Builds the error thrown when a single-match query finds more than one widget. */
11
17
  type MultipleErrorBuilder<Args extends unknown[]> = (
12
18
  container: Container,
13
19
  matches: Gtk.Widget[],
14
20
  ...args: Args
15
21
  ) => Error;
16
22
 
23
+ /** Builds the error thrown when a query that requires a match finds none. */
17
24
  type MissingErrorBuilder<Args extends unknown[]> = (container: Container, ...args: Args) => Error;
18
25
 
19
- type BuiltQueries<Args extends unknown[]> = {
20
- queryBy: (container: Container, ...args: Args) => Gtk.Widget | null;
21
- getAllBy: QueryAllBy<Args>;
22
- getBy: (container: Container, ...args: Args) => Gtk.Widget;
23
- findAllBy: (container: Container, ...args: Args) => Promise<Gtk.Widget[]>;
24
- findBy: (container: Container, ...args: Args) => Promise<Gtk.Widget>;
25
- };
26
+ /** The variants derived from one `queryAllBy` function, in the order DOM Testing Library returns them. */
27
+ type BuiltQueries<Args extends unknown[]> = [
28
+ queryBy: (container: Container, ...args: Args) => Gtk.Widget | null,
29
+ getAllBy: QueryAllBy<Args>,
30
+ getBy: (container: Container, ...args: Args) => Gtk.Widget,
31
+ findAllBy: (container: Container, ...args: Args) => Promise<Gtk.Widget[]>,
32
+ findBy: (container: Container, ...args: Args) => Promise<Gtk.Widget>,
33
+ ];
26
34
 
27
35
  type FindQuery<Args extends unknown[]> = (container: Container, ...args: Args) => unknown;
28
36
  type SingleQuery<Args extends unknown[]> = (container: Container, ...args: Args) => Gtk.Widget | null;
29
37
 
30
- const extractWaitForOptions = (args: unknown[]): WaitForOptions => {
31
- const last = args.at(-1);
32
-
33
- if (last && typeof last === "object" && !(last instanceof RegExp)) {
34
- const { timeout, interval, onTimeout } = last as WaitForOptions;
35
-
36
- return { timeout, interval, onTimeout };
37
- }
38
-
39
- return {};
40
- };
41
-
42
- const extractShouldSuggest = (args: unknown[]): boolean | undefined => {
38
+ const getTrailingOptions = (args: unknown[]): MatcherOptions | undefined => {
43
39
  const last = args.at(-1);
44
40
 
45
41
  if (last && typeof last === "object" && !(last instanceof RegExp)) {
46
- return (last as MatcherOptions).suggest;
42
+ return last;
47
43
  }
48
44
 
49
45
  return undefined;
50
46
  };
51
47
 
48
+ const extractShouldSuggest = (args: unknown[]): boolean | undefined => getTrailingOptions(args)?.suggest;
49
+ const getQueryFamily = (queryAllBy: { name: string }): string => queryAllBy.name.replace(/^queryAllBy/, "");
50
+
52
51
  const maybeThrowSuggestion = (options: {
53
52
  container: Container;
54
53
  match: Gtk.Widget;
55
- queryName: Method;
54
+ queryName: string;
56
55
  variant: Variant;
57
56
  shouldSuggest: boolean | undefined;
58
57
  }): void => {
@@ -91,16 +90,13 @@ const findOptions = <Args extends unknown[]>(
91
90
  container: Container,
92
91
  args: Args,
93
92
  ): WaitForOptions => {
94
- const userOptions = extractWaitForOptions(args);
95
-
96
- const onTimeout =
97
- userOptions.onTimeout ?? ((fallback: Error) => reRunForDiagnostics(query, container, args, fallback));
93
+ const { timeout, interval, onTimeout } = getTrailingOptions(args) ?? {};
98
94
 
99
95
  return {
100
96
  stackTraceError: new Error("STACK_TRACE_MESSAGE"),
101
- onTimeout,
102
- timeout: userOptions.timeout,
103
- interval: userOptions.interval,
97
+ onTimeout: onTimeout ?? ((fallback: Error) => reRunForDiagnostics(query, container, args, fallback)),
98
+ timeout,
99
+ interval,
104
100
  };
105
101
  };
106
102
 
@@ -135,7 +131,7 @@ const allOrThrow =
135
131
  };
136
132
 
137
133
  const wrapSingleWithSuggestion =
138
- <Args extends unknown[]>(query: SingleQuery<Args>, queryName: Method, variant: Variant): SingleQuery<Args> =>
134
+ <Args extends unknown[]>(query: SingleQuery<Args>, queryName: string, variant: Variant): SingleQuery<Args> =>
139
135
  (container, ...args) => {
140
136
  const match = query(container, ...args);
141
137
 
@@ -153,7 +149,7 @@ const wrapSingleWithSuggestion =
153
149
  };
154
150
 
155
151
  const wrapAllWithSuggestion =
156
- <Args extends unknown[]>(query: QueryAllBy<Args>, queryName: Method, variant: Variant): QueryAllBy<Args> =>
152
+ <Args extends unknown[]>(query: QueryAllBy<Args>, queryName: string, variant: Variant): QueryAllBy<Args> =>
157
153
  (container, ...args) => {
158
154
  const matches = query(container, ...args);
159
155
  const [first] = matches;
@@ -183,12 +179,22 @@ const requireSingle =
183
179
  return match;
184
180
  };
185
181
 
182
+ /**
183
+ * Derives the `queryBy`, `getAllBy`, `getBy`, `findAllBy`, and `findBy` variants of a query family
184
+ * from the family's `queryAllBy` function, mirroring DOM Testing Library's `buildQueries`. The family
185
+ * name used when suggesting a better query comes from `queryAllBy.name`.
186
+ *
187
+ * @param queryAllBy Finds every widget the family matches.
188
+ * @param getMultipleError Builds the error thrown when a single-match variant finds more than one widget.
189
+ * @param getMissingError Builds the error thrown when a required match is missing.
190
+ * @returns The five variants, in the order `[queryBy, getAllBy, getBy, findAllBy, findBy]`.
191
+ */
186
192
  const buildQueries = <Args extends unknown[]>(
187
- queryName: Method,
188
193
  queryAllBy: QueryAllBy<Args>,
189
194
  getMultipleError: MultipleErrorBuilder<Args>,
190
195
  getMissingError: MissingErrorBuilder<Args>,
191
196
  ): BuiltQueries<Args> => {
197
+ const queryName = getQueryFamily(queryAllBy);
192
198
  const getAllBy = allOrThrow(queryAllBy, getMissingError);
193
199
  const getBy = requireSingle(singleFrom(getAllBy, getMultipleError), getMissingError);
194
200
 
@@ -226,13 +232,13 @@ const buildQueries = <Args extends unknown[]>(
226
232
  findOptions(getByWithSuggestion, container, args),
227
233
  );
228
234
 
229
- return {
230
- queryBy: queryByWithSuggestion,
231
- getAllBy: getAllByWithSuggestion,
232
- getBy: getByWithSuggestion,
233
- findAllBy,
234
- findBy,
235
- };
235
+ return [queryByWithSuggestion, getAllByWithSuggestion, getByWithSuggestion, findAllBy, findBy];
236
236
  };
237
237
 
238
- export { buildQueries, type QueryAllBy, type BuiltQueries };
238
+ export {
239
+ buildQueries,
240
+ type BuiltQueries,
241
+ type MissingErrorBuilder,
242
+ type MultipleErrorBuilder,
243
+ type QueryAllBy,
244
+ };
@@ -24,4 +24,4 @@ const runCleanup = async (): Promise<void> => {
24
24
  }
25
25
  };
26
26
 
27
- export { addToCleanupQueue, runCleanup, type CleanupFunction };
27
+ export { addToCleanupQueue, runCleanup };
package/src/errors.ts CHANGED
@@ -130,6 +130,17 @@ const buildElementError = (container: Container, headLines: string[]): Error =>
130
130
  return config.getElementError(lines.join("\n"), container);
131
131
  };
132
132
 
133
+ /**
134
+ * Builds the error a failing query throws, appending the container's widget tree to the message the
135
+ * way the built-in queries do.
136
+ *
137
+ * @param message The failure message.
138
+ * @param container The scope whose widget tree is appended; omitted, only the message is used.
139
+ * @returns The error produced by the configured `getElementError`.
140
+ */
141
+ const getElementError = (message: string, container?: Container): Error =>
142
+ container === undefined ? getConfig().getElementError(message) : buildElementError(container, [message]);
143
+
133
144
  const notFoundError = (container: Container, descriptor: QueryDescriptor): Error => {
134
145
  const description = formatQueryDescription(descriptor);
135
146
  const headLines = [`Unable to find an element with ${description}`];
@@ -183,9 +194,9 @@ const timeoutError = (timeout: number, lastError: Error | null): Error => {
183
194
 
184
195
  export {
185
196
  runWithExpensiveErrorDiagnosticsDisabled,
197
+ getElementError,
186
198
  notFoundError,
187
199
  multipleFoundError,
188
200
  suggestionError,
189
201
  timeoutError,
190
- type QueryDescriptor,
191
202
  };
package/src/fire-event.ts CHANGED
@@ -1,18 +1,71 @@
1
- import type * as GObject from "@gtkx/gi/gobject";
1
+ import * as GObject from "@gtkx/gi/gobject";
2
2
  import { runInAct } from "./act.js";
3
3
 
4
4
  /**
5
- * Emits a GObject signal on a widget or object inside React's act environment,
6
- * so any resulting state updates are flushed before the promise resolves.
5
+ * A signal emission built but not yet delivered. GObject has no event object to construct, so this
6
+ * records the target, signal, and arguments {@link fireEvent} will emit.
7
+ */
8
+ type WidgetEvent = {
9
+ /** The GObject instance the signal is emitted on. */
10
+ target: GObject.Object;
11
+ /** Name of the signal to emit. */
12
+ signalName: string;
13
+ /** Arguments passed to the signal handlers. */
14
+ args: unknown[];
15
+ };
16
+
17
+ /**
18
+ * Records a signal emission without delivering it, so it can be inspected or held and passed to
19
+ * {@link fireEvent} later.
7
20
  *
8
- * @param element The GObject instance to emit the signal on.
21
+ * @param target The GObject instance the signal would be emitted on.
9
22
  * @param signalName Name of the signal to emit.
10
- * @param args Arguments passed to the signal handlers.
23
+ * @param args Arguments to pass to the signal handlers.
24
+ * @returns The recorded emission.
11
25
  */
12
- const fireEvent = async (element: GObject.Object, signalName: string, ...args: unknown[]): Promise<void> => {
26
+ const createEvent = (target: GObject.Object, signalName: string, ...args: unknown[]): WidgetEvent => ({
27
+ target,
28
+ signalName,
29
+ args,
30
+ });
31
+
32
+ const dispatchEvent = async (event: WidgetEvent): Promise<void> => {
13
33
  await runInAct(() => {
14
- element.emit(signalName, ...args);
34
+ event.target.emit(event.signalName, ...event.args);
15
35
  });
16
36
  };
17
37
 
18
- export { fireEvent };
38
+ /**
39
+ * Emits a recorded signal emission inside React's act environment, so any resulting state updates are
40
+ * flushed before the promise resolves.
41
+ *
42
+ * @param event An emission built by {@link createEvent}.
43
+ */
44
+ function fireEvent(event: WidgetEvent): Promise<void>;
45
+ /**
46
+ * Emits a GObject signal on a widget or object inside React's act environment, so any resulting state
47
+ * updates are flushed before the promise resolves.
48
+ *
49
+ * @param target The GObject instance to emit the signal on.
50
+ * @param signalName Name of the signal to emit.
51
+ * @param args Arguments passed to the signal handlers.
52
+ */
53
+ function fireEvent(target: GObject.Object, signalName: string, ...args: unknown[]): Promise<void>;
54
+
55
+ function fireEvent(
56
+ eventOrTarget: WidgetEvent | GObject.Object,
57
+ signalName?: string,
58
+ ...args: unknown[]
59
+ ): Promise<void> {
60
+ if (!(eventOrTarget instanceof GObject.Object)) {
61
+ return dispatchEvent(eventOrTarget);
62
+ }
63
+
64
+ if (signalName === undefined) {
65
+ throw new Error("Unable to fire an event: pass a signal name, or an event built by createEvent.");
66
+ }
67
+
68
+ return dispatchEvent(createEvent(eventOrTarget, signalName, ...args));
69
+ }
70
+
71
+ export { createEvent, fireEvent, type WidgetEvent };
package/src/frame-sync.ts CHANGED
@@ -16,7 +16,10 @@ const once = (callback: () => void): (() => void) => {
16
16
  };
17
17
  };
18
18
 
19
- const runWhenSized = (widget: Gtk.Widget, finish: () => void): void => {
19
+ const hasFrameClock = (widget: Gtk.Widget | null): widget is Gtk.Widget => widget?.getFrameClock() != null;
20
+ const isSized = (widget: Gtk.Widget): boolean => widget.getWidth() > 0;
21
+
22
+ const runUntilReady = (widget: Gtk.Widget, isReady: () => boolean, finish: () => void): void => {
20
23
  let tickId = 0;
21
24
 
22
25
  const fallback = setTimeout(() => {
@@ -25,7 +28,7 @@ const runWhenSized = (widget: Gtk.Widget, finish: () => void): void => {
25
28
  }, CLOCK_STALL_FALLBACK_MS);
26
29
 
27
30
  tickId = widget.addTickCallback(() => {
28
- if (widget.getWidth() === 0) {
31
+ if (!isReady()) {
29
32
  return GLib.SOURCE_CONTINUE;
30
33
  }
31
34
 
@@ -36,16 +39,29 @@ const runWhenSized = (widget: Gtk.Widget, finish: () => void): void => {
36
39
  });
37
40
  };
38
41
 
42
+ const scheduleNextFrame = (widget: Gtk.Widget): Promise<void> =>
43
+ new Promise((resolve) => {
44
+ const finish = once(resolve);
45
+
46
+ if (!hasFrameClock(widget)) {
47
+ queueMicrotask(finish);
48
+
49
+ return;
50
+ }
51
+
52
+ runUntilReady(widget, () => true, finish);
53
+ });
54
+
39
55
  const scheduleAfterLayout = (widget: Gtk.Widget | null, callback: () => void): void => {
40
56
  const finish = once(callback);
41
57
 
42
- if (widget?.getFrameClock() == null || widget.getWidth() > 0) {
58
+ if (!hasFrameClock(widget) || isSized(widget)) {
43
59
  queueMicrotask(finish);
44
60
 
45
61
  return;
46
62
  }
47
63
 
48
- runWhenSized(widget, finish);
64
+ runUntilReady(widget, () => isSized(widget), finish);
49
65
  };
50
66
 
51
- export { scheduleAfterLayout };
67
+ export { scheduleAfterLayout, scheduleNextFrame };
@@ -0,0 +1,9 @@
1
+ import * as Gtk from "@gtkx/gi/gtk";
2
+
3
+ const HARNESS_WINDOW_WIDTH = 800;
4
+ const HARNESS_WINDOW_HEIGHT = 600;
5
+
6
+ const createHarnessWindow = (): Gtk.Window =>
7
+ new Gtk.Window({ defaultWidth: HARNESS_WINDOW_WIDTH, defaultHeight: HARNESS_WINDOW_HEIGHT });
8
+
9
+ export { createHarnessWindow };
package/src/index.ts CHANGED
@@ -2,12 +2,22 @@ import "./register-test-hooks.js";
2
2
 
3
3
  export { act } from "./act.js";
4
4
  export type { BoundQueries, RenderResult, Screen } from "./bound-queries.js";
5
+ export type {
6
+ BuiltQueries,
7
+ MissingErrorBuilder,
8
+ MultipleErrorBuilder,
9
+ QueryAllBy,
10
+ } from "./build-queries.js";
11
+ export { buildQueries } from "./build-queries.js";
5
12
  export type { Config, ConfigFn } from "./config.js";
6
13
  export { configure, getConfig } from "./config.js";
7
- export { fireEvent } from "./fire-event.js";
14
+ export { getElementError } from "./errors.js";
15
+ export type { WidgetEvent } from "./fire-event.js";
16
+ export { createEvent, fireEvent } from "./fire-event.js";
8
17
  export type { ClassExpectation, TextContentOptions, TextExpectation } from "./matchers.js";
9
18
  export { matchers, registerMatchers } from "./matchers.js";
10
19
  export { getDefaultNormalizer } from "./normalize.js";
20
+ export { prettyFormat } from "./pretty-format.js";
11
21
  export type { PrettyWidgetOptions } from "./pretty-widget.js";
12
22
  export { logWidget, prettyWidget } from "./pretty-widget.js";
13
23
  export {
@@ -48,11 +58,13 @@ export {
48
58
  queryByRole,
49
59
  queryByText,
50
60
  } from "./queries.js";
61
+ export type { QueryHelpers } from "./query-helpers.js";
62
+ export { queryAllByObjectProperty, queryByObjectProperty, queryHelpers } from "./query-helpers.js";
51
63
  export { renderHook } from "./render-hook.js";
52
64
  export { cleanup, render } from "./render.js";
53
- export { formatRole, getRoles, logRoles, prettyRoles } from "./role-helpers.js";
65
+ export { computeHeadingLevel, formatRole, getRoles, logRoles, prettyRoles } from "./role-helpers.js";
54
66
  export { screen } from "./screen.js";
55
- export { captureAndSaveScreenshot, logScreenshotPath, screenshot } from "./screenshot.js";
67
+ export { screenshot } from "./screenshot.js";
56
68
  export type { Method, Suggestion, Variant } from "./suggestions.js";
57
69
  export { getSuggestedQuery } from "./suggestions.js";
58
70
  export type { Container } from "./traversal.js";
@@ -71,7 +83,6 @@ export type {
71
83
  ScreenshotOptions,
72
84
  ScreenshotResult,
73
85
  WaitForOptions,
74
- WindowSelector,
75
86
  WrapperComponent,
76
87
  } from "./types.js";
77
88
  export type { ControllerConstructor } from "./user-event/controller.js";
@@ -91,13 +102,9 @@ export type {
91
102
  TabOptions,
92
103
  TypeOptions,
93
104
  UserEvent,
105
+ UserEventOptions,
94
106
  } from "./user-event/index.js";
95
107
  export { userEvent } from "./user-event/index.js";
96
108
  export { waitFor, waitForElementToBeRemoved } from "./wait-for.js";
97
- export {
98
- getWidgetErrorMessage,
99
- getWidgetInvalidState,
100
- getWidgetNodeText,
101
- getWidgetTextContent,
102
- } from "./widget-accessible-properties.js";
103
- export { within } from "./within.js";
109
+ export { getWidgetText, isInaccessible } from "./widget-accessible-properties.js";
110
+ export { getQueriesForElement, within } from "./within.js";
@@ -0,0 +1,11 @@
1
+ export {
2
+ readAccessibleBooleanProperty,
3
+ readAccessibleFlag,
4
+ readAccessibleInt,
5
+ readAccessibleNumber,
6
+ readAccessibleRelation,
7
+ readAccessibleState,
8
+ readAccessibleString,
9
+ } from "./accessible-native.js";
10
+ export { cleanup, render } from "./production.js";
11
+ export { renderChildren, type ChildrenBuilder } from "./render-children.js";