@gtkx/testing 0.21.0 → 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.
Files changed (216) hide show
  1. package/README.md +137 -34
  2. package/dist/act.d.ts +19 -0
  3. package/dist/act.d.ts.map +1 -0
  4. package/dist/act.js +56 -0
  5. package/dist/act.js.map +1 -0
  6. package/dist/bound-queries.d.ts +33 -0
  7. package/dist/bound-queries.d.ts.map +1 -0
  8. package/dist/bound-queries.js +2 -0
  9. package/dist/bound-queries.js.map +1 -0
  10. package/dist/build-queries.d.ts +16 -0
  11. package/dist/build-queries.d.ts.map +1 -0
  12. package/dist/build-queries.js +115 -0
  13. package/dist/build-queries.js.map +1 -0
  14. package/dist/cleanup-registry.d.ts +5 -0
  15. package/dist/cleanup-registry.d.ts.map +1 -0
  16. package/dist/cleanup-registry.js +21 -0
  17. package/dist/cleanup-registry.js.map +1 -0
  18. package/dist/config.d.ts +20 -52
  19. package/dist/config.d.ts.map +1 -1
  20. package/dist/config.js +17 -46
  21. package/dist/config.js.map +1 -1
  22. package/dist/editable.d.ts +8 -0
  23. package/dist/editable.d.ts.map +1 -0
  24. package/dist/editable.js +26 -0
  25. package/dist/editable.js.map +1 -0
  26. package/dist/errors.d.ts +30 -0
  27. package/dist/errors.d.ts.map +1 -0
  28. package/dist/errors.js +135 -0
  29. package/dist/errors.js.map +1 -0
  30. package/dist/fire-event.d.ts +8 -25
  31. package/dist/fire-event.d.ts.map +1 -1
  32. package/dist/fire-event.js +11 -30
  33. package/dist/fire-event.js.map +1 -1
  34. package/dist/frame-sync.d.ts +4 -0
  35. package/dist/frame-sync.d.ts.map +1 -0
  36. package/dist/frame-sync.js +37 -0
  37. package/dist/frame-sync.js.map +1 -0
  38. package/dist/index.d.ts +17 -12
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +11 -7
  41. package/dist/index.js.map +1 -1
  42. package/dist/matchers.d.ts +59 -0
  43. package/dist/matchers.d.ts.map +1 -0
  44. package/dist/matchers.js +117 -0
  45. package/dist/matchers.js.map +1 -0
  46. package/dist/pretty-widget.d.ts +24 -26
  47. package/dist/pretty-widget.d.ts.map +1 -1
  48. package/dist/pretty-widget.js +111 -117
  49. package/dist/pretty-widget.js.map +1 -1
  50. package/dist/queries.d.ts +190 -180
  51. package/dist/queries.d.ts.map +1 -1
  52. package/dist/queries.js +291 -320
  53. package/dist/queries.js.map +1 -1
  54. package/dist/register-test-hooks.d.ts +2 -0
  55. package/dist/register-test-hooks.d.ts.map +1 -0
  56. package/dist/register-test-hooks.js +16 -0
  57. package/dist/register-test-hooks.js.map +1 -0
  58. package/dist/render-hook.d.ts +15 -35
  59. package/dist/render-hook.d.ts.map +1 -1
  60. package/dist/render-hook.js +9 -45
  61. package/dist/render-hook.js.map +1 -1
  62. package/dist/render.d.ts +13 -42
  63. package/dist/render.d.ts.map +1 -1
  64. package/dist/render.js +138 -121
  65. package/dist/render.js.map +1 -1
  66. package/dist/role-helpers.d.ts +19 -53
  67. package/dist/role-helpers.d.ts.map +1 -1
  68. package/dist/role-helpers.js +48 -63
  69. package/dist/role-helpers.js.map +1 -1
  70. package/dist/screen.d.ts +7 -63
  71. package/dist/screen.d.ts.map +1 -1
  72. package/dist/screen.js +24 -110
  73. package/dist/screen.js.map +1 -1
  74. package/dist/screenshot.d.ts +21 -23
  75. package/dist/screenshot.d.ts.map +1 -1
  76. package/dist/screenshot.js +98 -50
  77. package/dist/screenshot.js.map +1 -1
  78. package/dist/suggestions.d.ts +27 -0
  79. package/dist/suggestions.d.ts.map +1 -0
  80. package/dist/suggestions.js +61 -0
  81. package/dist/suggestions.js.map +1 -0
  82. package/dist/traversal.d.ts +12 -10
  83. package/dist/traversal.d.ts.map +1 -1
  84. package/dist/traversal.js +36 -15
  85. package/dist/traversal.js.map +1 -1
  86. package/dist/types.d.ts +115 -169
  87. package/dist/types.d.ts.map +1 -1
  88. package/dist/types.js.map +1 -1
  89. package/dist/user-event/adjustment.d.ts +10 -0
  90. package/dist/user-event/adjustment.d.ts.map +1 -0
  91. package/dist/user-event/adjustment.js +35 -0
  92. package/dist/user-event/adjustment.js.map +1 -0
  93. package/dist/user-event/click.d.ts +8 -0
  94. package/dist/user-event/click.d.ts.map +1 -0
  95. package/dist/user-event/click.js +73 -0
  96. package/dist/user-event/click.js.map +1 -0
  97. package/dist/user-event/controller.d.ts +8 -0
  98. package/dist/user-event/controller.d.ts.map +1 -0
  99. package/dist/user-event/controller.js +31 -0
  100. package/dist/user-event/controller.js.map +1 -0
  101. package/dist/user-event/dispatch.d.ts +7 -0
  102. package/dist/user-event/dispatch.d.ts.map +1 -0
  103. package/dist/user-event/dispatch.js +11 -0
  104. package/dist/user-event/dispatch.js.map +1 -0
  105. package/dist/user-event/event-wrapper.d.ts +4 -0
  106. package/dist/user-event/event-wrapper.d.ts.map +1 -0
  107. package/dist/user-event/event-wrapper.js +59 -0
  108. package/dist/user-event/event-wrapper.js.map +1 -0
  109. package/dist/user-event/gesture.d.ts +35 -0
  110. package/dist/user-event/gesture.d.ts.map +1 -0
  111. package/dist/user-event/gesture.js +138 -0
  112. package/dist/user-event/gesture.js.map +1 -0
  113. package/dist/user-event/index.d.ts +51 -0
  114. package/dist/user-event/index.d.ts.map +1 -0
  115. package/dist/user-event/index.js +42 -0
  116. package/dist/user-event/index.js.map +1 -0
  117. package/dist/user-event/keyboard.d.ts +10 -0
  118. package/dist/user-event/keyboard.d.ts.map +1 -0
  119. package/dist/user-event/keyboard.js +204 -0
  120. package/dist/user-event/keyboard.js.map +1 -0
  121. package/dist/user-event/pointer.d.ts +10 -0
  122. package/dist/user-event/pointer.d.ts.map +1 -0
  123. package/dist/user-event/pointer.js +30 -0
  124. package/dist/user-event/pointer.js.map +1 -0
  125. package/dist/user-event/selection.d.ts +5 -0
  126. package/dist/user-event/selection.d.ts.map +1 -0
  127. package/dist/user-event/selection.js +105 -0
  128. package/dist/user-event/selection.js.map +1 -0
  129. package/dist/user-event/state.d.ts +7 -0
  130. package/dist/user-event/state.d.ts.map +1 -0
  131. package/dist/user-event/state.js +3 -0
  132. package/dist/user-event/state.js.map +1 -0
  133. package/dist/user-event/text.d.ts +18 -0
  134. package/dist/user-event/text.d.ts.map +1 -0
  135. package/dist/user-event/text.js +113 -0
  136. package/dist/user-event/text.js.map +1 -0
  137. package/dist/wait-for.d.ts +16 -36
  138. package/dist/wait-for.d.ts.map +1 -1
  139. package/dist/wait-for.js +74 -70
  140. package/dist/wait-for.js.map +1 -1
  141. package/dist/widget-accessible-properties.d.ts +34 -0
  142. package/dist/widget-accessible-properties.d.ts.map +1 -0
  143. package/dist/widget-accessible-properties.js +260 -0
  144. package/dist/widget-accessible-properties.js.map +1 -0
  145. package/dist/within.d.ts +10 -26
  146. package/dist/within.d.ts.map +1 -1
  147. package/dist/within.js +16 -25
  148. package/dist/within.js.map +1 -1
  149. package/package.json +23 -12
  150. package/src/act.ts +77 -0
  151. package/src/bound-queries.ts +37 -0
  152. package/src/build-queries.ts +226 -0
  153. package/src/cleanup-registry.ts +27 -0
  154. package/src/config.ts +35 -62
  155. package/src/editable.ts +37 -0
  156. package/src/errors.ts +191 -0
  157. package/src/fire-event.ts +13 -38
  158. package/src/frame-sync.ts +51 -0
  159. package/src/index.ts +58 -15
  160. package/src/matchers.ts +251 -0
  161. package/src/pretty-widget.ts +163 -130
  162. package/src/queries.ts +485 -396
  163. package/src/register-test-hooks.ts +19 -0
  164. package/src/render-hook.tsx +38 -45
  165. package/src/render.tsx +192 -155
  166. package/src/role-helpers.ts +65 -72
  167. package/src/screen.ts +26 -114
  168. package/src/screenshot.ts +128 -56
  169. package/src/suggestions.ts +106 -0
  170. package/src/traversal.ts +56 -22
  171. package/src/types.ts +144 -172
  172. package/src/user-event/adjustment.ts +62 -0
  173. package/src/user-event/click.ts +99 -0
  174. package/src/user-event/controller.ts +58 -0
  175. package/src/user-event/dispatch.ts +25 -0
  176. package/src/user-event/event-wrapper.ts +80 -0
  177. package/src/user-event/gesture.ts +239 -0
  178. package/src/user-event/index.ts +81 -0
  179. package/src/user-event/keyboard.ts +290 -0
  180. package/src/user-event/pointer.ts +46 -0
  181. package/src/user-event/selection.ts +159 -0
  182. package/src/user-event/state.ts +8 -0
  183. package/src/user-event/text.ts +172 -0
  184. package/src/wait-for.ts +117 -78
  185. package/src/widget-accessible-properties.ts +388 -0
  186. package/src/within.ts +29 -27
  187. package/dist/bind-queries.d.ts +0 -14
  188. package/dist/bind-queries.d.ts.map +0 -1
  189. package/dist/bind-queries.js +0 -29
  190. package/dist/bind-queries.js.map +0 -1
  191. package/dist/error-builder.d.ts +0 -28
  192. package/dist/error-builder.d.ts.map +0 -1
  193. package/dist/error-builder.js +0 -81
  194. package/dist/error-builder.js.map +0 -1
  195. package/dist/timing.d.ts +0 -18
  196. package/dist/timing.d.ts.map +0 -1
  197. package/dist/timing.js +0 -18
  198. package/dist/timing.js.map +0 -1
  199. package/dist/user-event.d.ts +0 -138
  200. package/dist/user-event.d.ts.map +0 -1
  201. package/dist/user-event.js +0 -411
  202. package/dist/user-event.js.map +0 -1
  203. package/dist/widget-text.d.ts +0 -69
  204. package/dist/widget-text.d.ts.map +0 -1
  205. package/dist/widget-text.js +0 -177
  206. package/dist/widget-text.js.map +0 -1
  207. package/dist/widget.d.ts +0 -3
  208. package/dist/widget.d.ts.map +0 -1
  209. package/dist/widget.js +0 -13
  210. package/dist/widget.js.map +0 -1
  211. package/src/bind-queries.ts +0 -52
  212. package/src/error-builder.ts +0 -102
  213. package/src/timing.ts +0 -17
  214. package/src/user-event.ts +0 -492
  215. package/src/widget-text.ts +0 -202
  216. package/src/widget.ts +0 -15
package/dist/config.d.ts CHANGED
@@ -1,65 +1,33 @@
1
1
  import type { Container } from "./traversal.js";
2
2
  /**
3
- * Configuration options for the testing library.
3
+ * Global configuration for the testing harness, controlling query behavior,
4
+ * error formatting, and the timeouts used by async utilities and actionability
5
+ * checks.
4
6
  */
5
- export type Config = {
6
- /**
7
- * Whether to show role suggestions in error messages when elements are not found.
8
- * @default true
9
- */
10
- showSuggestions: boolean;
11
- /**
12
- * Custom error factory for query failures.
13
- * Allows customizing how errors are constructed.
14
- */
15
- getElementError: (message: string, container: Container) => Error;
16
- /**
17
- * Default timeout in milliseconds for async utilities (waitFor, findBy* queries).
18
- * @default 1000
19
- */
7
+ type Config = {
8
+ throwSuggestions: boolean;
9
+ /** Builds the error thrown when a query fails, given a message and optional container. */
10
+ getElementError: (message: string, container?: Container) => Error;
11
+ /** Default timeout in milliseconds for async utilities such as waitFor. */
20
12
  asyncUtilTimeout: number;
13
+ /** Timeout in milliseconds for waiting on a widget to become actionable. */
14
+ actionabilityTimeout: number;
21
15
  };
22
16
  /**
23
- * Returns the current testing library configuration.
24
- *
25
- * @returns The current configuration object
26
- *
27
- * @example
28
- * ```tsx
29
- * import { getConfig } from "@gtkx/testing";
30
- *
31
- * const config = getConfig();
32
- * console.log(config.showSuggestions);
33
- * ```
17
+ * Function form of a configuration update: receives the current config and
18
+ * returns the fields to override.
34
19
  */
35
- export declare const getConfig: () => Readonly<Config>;
20
+ type ConfigFn = (existingConfig: Config) => Partial<Config>;
36
21
  /**
37
- * Configures the testing library behavior.
38
- *
39
- * Accepts either a partial configuration object or a function that receives
40
- * the current configuration and returns updates.
41
- *
42
- * @param newConfig - Partial configuration or updater function
43
- *
44
- * @example
45
- * ```tsx
46
- * import { configure } from "@gtkx/testing";
47
- *
48
- * // Disable role suggestions
49
- * configure({ showSuggestions: false });
50
- *
51
- * // Use updater function
52
- * configure((current) => ({
53
- * showSuggestions: !current.showSuggestions,
54
- * }));
55
- * ```
22
+ * Returns the current global testing configuration.
56
23
  */
57
- export declare const configure: (newConfig: Partial<Config> | ((current: Config) => Partial<Config>)) => void;
24
+ declare const getConfig: () => Config;
58
25
  /**
59
- * Resets configuration to defaults.
60
- * Primarily used for testing.
26
+ * Merges the given overrides into the global testing configuration.
61
27
  *
62
- * @internal
28
+ * @param newConfig Either a partial config object or a function that receives
29
+ * the current config and returns the fields to override.
63
30
  */
64
- export declare const resetConfig: () => void;
31
+ declare const configure: (newConfig: Partial<Config> | ConfigFn) => void;
32
+ export { getConfig, configure, type Config, type ConfigFn };
65
33
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG;IACjB;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,KAAK,KAAK,CAAC;IAElE;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAcF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,SAAS,QAAO,QAAQ,CAAC,MAAM,CAE3C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,SAAS,GAAI,WAAW,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,KAAG,IAG/F,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,QAAO,IAE9B,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;GAIG;AACH,KAAK,MAAM,GAAG;IACV,gBAAgB,EAAE,OAAO,CAAC;IAE1B,0FAA0F;IAC1F,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS,KAAK,KAAK,CAAC;IAEnE,2EAA2E;IAC3E,gBAAgB,EAAE,MAAM,CAAC;IAEzB,4EAA4E;IAC5E,oBAAoB,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF;;;GAGG;AACH,KAAK,QAAQ,GAAG,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAe5D;;GAEG;AACH,QAAA,MAAM,SAAS,QAAO,MAErB,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,SAAS,GAAI,WAAW,OAAO,CAAC,MAAM,CAAC,GAAG,QAAQ,KAAG,IAG1D,CAAC;AAMF,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,CAAC"}
package/dist/config.js CHANGED
@@ -1,60 +1,31 @@
1
- const defaultGetElementError = (message, _container) => {
2
- return new Error(message);
3
- };
4
1
  const defaultConfig = {
5
- showSuggestions: true,
2
+ throwSuggestions: false,
6
3
  getElementError: defaultGetElementError,
7
4
  asyncUtilTimeout: 1000,
5
+ actionabilityTimeout: 500,
8
6
  };
9
- let currentConfig = { ...defaultConfig };
7
+ const currentConfig = { ...defaultConfig };
8
+ function defaultGetElementError(message) {
9
+ return new GtkxElementError(message);
10
+ }
10
11
  /**
11
- * Returns the current testing library configuration.
12
- *
13
- * @returns The current configuration object
14
- *
15
- * @example
16
- * ```tsx
17
- * import { getConfig } from "@gtkx/testing";
18
- *
19
- * const config = getConfig();
20
- * console.log(config.showSuggestions);
21
- * ```
12
+ * Returns the current global testing configuration.
22
13
  */
23
- export const getConfig = () => {
14
+ const getConfig = () => {
24
15
  return currentConfig;
25
16
  };
26
17
  /**
27
- * Configures the testing library behavior.
28
- *
29
- * Accepts either a partial configuration object or a function that receives
30
- * the current configuration and returns updates.
31
- *
32
- * @param newConfig - Partial configuration or updater function
18
+ * Merges the given overrides into the global testing configuration.
33
19
  *
34
- * @example
35
- * ```tsx
36
- * import { configure } from "@gtkx/testing";
37
- *
38
- * // Disable role suggestions
39
- * configure({ showSuggestions: false });
40
- *
41
- * // Use updater function
42
- * configure((current) => ({
43
- * showSuggestions: !current.showSuggestions,
44
- * }));
45
- * ```
20
+ * @param newConfig Either a partial config object or a function that receives
21
+ * the current config and returns the fields to override.
46
22
  */
47
- export const configure = (newConfig) => {
23
+ const configure = (newConfig) => {
48
24
  const updates = typeof newConfig === "function" ? newConfig(currentConfig) : newConfig;
49
- currentConfig = { ...currentConfig, ...updates };
50
- };
51
- /**
52
- * Resets configuration to defaults.
53
- * Primarily used for testing.
54
- *
55
- * @internal
56
- */
57
- export const resetConfig = () => {
58
- currentConfig = { ...defaultConfig };
25
+ Object.assign(currentConfig, updates);
59
26
  };
27
+ class GtkxElementError extends Error {
28
+ name = "GtkxElementError";
29
+ }
30
+ export { getConfig, configure };
60
31
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAyBA,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAE,UAAqB,EAAS,EAAE;IAC7E,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC,CAAC;AAEF,MAAM,aAAa,GAAW;IAC1B,eAAe,EAAE,IAAI;IACrB,eAAe,EAAE,sBAAsB;IACvC,gBAAgB,EAAE,IAAI;CACzB,CAAC;AAEF,IAAI,aAAa,GAAW,EAAE,GAAG,aAAa,EAAE,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,GAAqB,EAAE;IAC5C,OAAO,aAAa,CAAC;AACzB,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,SAAmE,EAAQ,EAAE;IACnG,MAAM,OAAO,GAAG,OAAO,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvF,aAAa,GAAG,EAAE,GAAG,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;AACrD,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,GAAS,EAAE;IAClC,aAAa,GAAG,EAAE,GAAG,aAAa,EAAE,CAAC;AACzC,CAAC,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AA0BA,MAAM,aAAa,GAAW;IAC1B,gBAAgB,EAAE,KAAK;IACvB,eAAe,EAAE,sBAAsB;IACvC,gBAAgB,EAAE,IAAI;IACtB,oBAAoB,EAAE,GAAG;CAC5B,CAAC;AAEF,MAAM,aAAa,GAAW,EAAE,GAAG,aAAa,EAAE,CAAC;AAEnD,SAAS,sBAAsB,CAAC,OAAe;IAC3C,OAAO,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,SAAS,GAAG,GAAW,EAAE;IAC3B,OAAO,aAAa,CAAC;AACzB,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,SAAS,GAAG,CAAC,SAAqC,EAAQ,EAAE;IAC9D,MAAM,OAAO,GAAG,OAAO,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvF,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC,CAAC;AAEF,MAAM,gBAAiB,SAAQ,KAAK;IACvB,IAAI,GAAG,kBAAkB,CAAC;CACtC;AAED,OAAO,EAAE,SAAS,EAAE,SAAS,EAA8B,CAAC","sourcesContent":["import type { Container } from \"./traversal.js\";\n\n/**\n * Global configuration for the testing harness, controlling query behavior,\n * error formatting, and the timeouts used by async utilities and actionability\n * checks.\n */\ntype Config = {\n throwSuggestions: boolean;\n\n /** Builds the error thrown when a query fails, given a message and optional container. */\n getElementError: (message: string, container?: Container) => Error;\n\n /** Default timeout in milliseconds for async utilities such as waitFor. */\n asyncUtilTimeout: number;\n\n /** Timeout in milliseconds for waiting on a widget to become actionable. */\n actionabilityTimeout: number;\n};\n\n/**\n * Function form of a configuration update: receives the current config and\n * returns the fields to override.\n */\ntype ConfigFn = (existingConfig: Config) => Partial<Config>;\n\nconst defaultConfig: Config = {\n throwSuggestions: false,\n getElementError: defaultGetElementError,\n asyncUtilTimeout: 1000,\n actionabilityTimeout: 500,\n};\n\nconst currentConfig: Config = { ...defaultConfig };\n\nfunction defaultGetElementError(message: string): Error {\n return new GtkxElementError(message);\n}\n\n/**\n * Returns the current global testing configuration.\n */\nconst getConfig = (): Config => {\n return currentConfig;\n};\n\n/**\n * Merges the given overrides into the global testing configuration.\n *\n * @param newConfig Either a partial config object or a function that receives\n * the current config and returns the fields to override.\n */\nconst configure = (newConfig: Partial<Config> | ConfigFn): void => {\n const updates = typeof newConfig === \"function\" ? newConfig(currentConfig) : newConfig;\n Object.assign(currentConfig, updates);\n};\n\nclass GtkxElementError extends Error {\n override name = \"GtkxElementError\";\n}\n\nexport { getConfig, configure, type Config, type ConfigFn };\n"]}
@@ -0,0 +1,8 @@
1
+ import * as Gtk from "@gtkx/gi/gtk";
2
+ type EditableTarget = Gtk.Editable | Gtk.TextView;
3
+ declare const EDITABLE_ROLES: Set<Gtk.AccessibleRole>;
4
+ declare const isEditable: (widget: unknown) => widget is EditableTarget;
5
+ declare const getEditableDelegate: (widget: Gtk.Widget) => Gtk.Widget | null;
6
+ declare const readEditableText: (widget: EditableTarget) => string;
7
+ export { EDITABLE_ROLES, isEditable, getEditableDelegate, readEditableText, type EditableTarget };
8
+ //# sourceMappingURL=editable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editable.d.ts","sourceRoot":"","sources":["../src/editable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AAEpC,KAAK,cAAc,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;AAElD,QAAA,MAAM,cAAc,EAAE,GAAG,CAAC,GAAG,CAAC,cAAc,CAI1C,CAAC;AAEH,QAAA,MAAM,UAAU,GAAI,QAAQ,OAAO,KAAG,MAAM,IAAI,cACoB,CAAC;AAErE,QAAA,MAAM,mBAAmB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,GAAG,CAAC,MAAM,GAAG,IAM9D,CAAC;AASF,QAAA,MAAM,gBAAgB,GAAI,QAAQ,cAAc,KAAG,MAMlD,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,KAAK,cAAc,EAAE,CAAC"}
@@ -0,0 +1,26 @@
1
+ import * as Gtk from "@gtkx/gi/gtk";
2
+ const EDITABLE_ROLES = new Set([
3
+ Gtk.AccessibleRole.TEXT_BOX,
4
+ Gtk.AccessibleRole.SEARCH_BOX,
5
+ Gtk.AccessibleRole.SPIN_BUTTON,
6
+ ]);
7
+ const isEditable = (widget) => widget instanceof Gtk.Editable || widget instanceof Gtk.TextView;
8
+ const getEditableDelegate = (widget) => {
9
+ if (!(widget instanceof Gtk.Editable)) {
10
+ return null;
11
+ }
12
+ return widget.getDelegate();
13
+ };
14
+ const readTextViewBufferText = (widget) => {
15
+ const buffer = widget.getBuffer();
16
+ const [start, end] = buffer.getBounds();
17
+ return buffer.getText(start, end, true);
18
+ };
19
+ const readEditableText = (widget) => {
20
+ if (widget instanceof Gtk.TextView) {
21
+ return readTextViewBufferText(widget);
22
+ }
23
+ return widget.getText();
24
+ };
25
+ export { EDITABLE_ROLES, isEditable, getEditableDelegate, readEditableText };
26
+ //# sourceMappingURL=editable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editable.js","sourceRoot":"","sources":["../src/editable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AAIpC,MAAM,cAAc,GAA4B,IAAI,GAAG,CAAqB;IACxE,GAAG,CAAC,cAAc,CAAC,QAAQ;IAC3B,GAAG,CAAC,cAAc,CAAC,UAAU;IAC7B,GAAG,CAAC,cAAc,CAAC,WAAW;CACjC,CAAC,CAAC;AAEH,MAAM,UAAU,GAAG,CAAC,MAAe,EAA4B,EAAE,CAC7D,MAAM,YAAY,GAAG,CAAC,QAAQ,IAAI,MAAM,YAAY,GAAG,CAAC,QAAQ,CAAC;AAErE,MAAM,mBAAmB,GAAG,CAAC,MAAkB,EAAqB,EAAE;IAClE,IAAI,CAAC,CAAC,MAAM,YAAY,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC;AAChC,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG,CAAC,MAAoB,EAAU,EAAE;IAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;IAClC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;IAExC,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AAC5C,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,MAAsB,EAAU,EAAE;IACxD,IAAI,MAAM,YAAY,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjC,OAAO,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,MAAM,CAAC,OAAO,EAAE,CAAC;AAC5B,CAAC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,mBAAmB,EAAE,gBAAgB,EAAuB,CAAC","sourcesContent":["import * as Gtk from \"@gtkx/gi/gtk\";\n\ntype EditableTarget = Gtk.Editable | Gtk.TextView;\n\nconst EDITABLE_ROLES: Set<Gtk.AccessibleRole> = new Set<Gtk.AccessibleRole>([\n Gtk.AccessibleRole.TEXT_BOX,\n Gtk.AccessibleRole.SEARCH_BOX,\n Gtk.AccessibleRole.SPIN_BUTTON,\n]);\n\nconst isEditable = (widget: unknown): widget is EditableTarget =>\n widget instanceof Gtk.Editable || widget instanceof Gtk.TextView;\n\nconst getEditableDelegate = (widget: Gtk.Widget): Gtk.Widget | null => {\n if (!(widget instanceof Gtk.Editable)) {\n return null;\n }\n\n return widget.getDelegate();\n};\n\nconst readTextViewBufferText = (widget: Gtk.TextView): string => {\n const buffer = widget.getBuffer();\n const [start, end] = buffer.getBounds();\n\n return buffer.getText(start, end, true);\n};\n\nconst readEditableText = (widget: EditableTarget): string => {\n if (widget instanceof Gtk.TextView) {\n return readTextViewBufferText(widget);\n }\n\n return widget.getText();\n};\n\nexport { EDITABLE_ROLES, isEditable, getEditableDelegate, readEditableText, type EditableTarget };\n"]}
@@ -0,0 +1,30 @@
1
+ import type * as Gtk from "@gtkx/gi/gtk";
2
+ import type { Container } from "./traversal.js";
3
+ import type { ByRoleOptions, Matcher } from "./types.js";
4
+ type QueryDescriptor = {
5
+ queryType: "role";
6
+ role: Gtk.AccessibleRole;
7
+ options?: ByRoleOptions | undefined;
8
+ } | {
9
+ queryType: "text";
10
+ text: Matcher;
11
+ } | {
12
+ queryType: "labelText";
13
+ text: Matcher;
14
+ } | {
15
+ queryType: "name";
16
+ name: Matcher;
17
+ } | {
18
+ queryType: "placeholderText";
19
+ text: Matcher;
20
+ } | {
21
+ queryType: "displayValue";
22
+ value: Matcher;
23
+ };
24
+ declare const runWithExpensiveErrorDiagnosticsDisabled: <T>(callback: () => T) => T;
25
+ declare const notFoundError: (container: Container, descriptor: QueryDescriptor) => Error;
26
+ declare const multipleFoundError: (container: Container, descriptor: QueryDescriptor, matches: Gtk.Widget[]) => Error;
27
+ declare const suggestionError: (suggestion: string, container: Container) => Error;
28
+ declare const timeoutError: (timeout: number, lastError: Error | null) => Error;
29
+ export { runWithExpensiveErrorDiagnosticsDisabled, notFoundError, multipleFoundError, suggestionError, timeoutError, type QueryDescriptor, };
30
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAe,OAAO,EAAE,MAAM,YAAY,CAAC;AAKtE,KAAK,eAAe,GACd;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,GAAG,CAAC,cAAc,CAAC;IAAC,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAA;CAAE,GACtF;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GACpC;IAAE,SAAS,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GACzC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GACpC;IAAE,SAAS,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC/C;IAAE,SAAS,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAkGlD,QAAA,MAAM,wCAAwC,GAAI,CAAC,EAAE,UAAU,MAAM,CAAC,KAAG,CASxE,CAAC;AAYF,QAAA,MAAM,aAAa,GAAI,WAAW,SAAS,EAAE,YAAY,eAAe,KAAG,KAS1E,CAAC;AAWF,QAAA,MAAM,kBAAkB,GAAI,WAAW,SAAS,EAAE,YAAY,eAAe,EAAE,SAAS,GAAG,CAAC,MAAM,EAAE,KAAG,KAetG,CAAC;AAEF,QAAA,MAAM,eAAe,GAAI,YAAY,MAAM,EAAE,WAAW,SAAS,KAAG,KAKnE,CAAC;AAEF,QAAA,MAAM,YAAY,GAAI,SAAS,MAAM,EAAE,WAAW,KAAK,GAAG,IAAI,KAAG,KAKhE,CAAC;AAEF,OAAO,EACH,wCAAwC,EACxC,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,KAAK,eAAe,GACvB,CAAC"}
package/dist/errors.js ADDED
@@ -0,0 +1,135 @@
1
+ import { getConfig } from "./config.js";
2
+ import { prettyWidget } from "./pretty-widget.js";
3
+ import { formatRole, prettyRoles } from "./role-helpers.js";
4
+ const roleOptionFormatters = [
5
+ (o) => (o.name ? `name ${formatTextMatcher(o.name)}` : null),
6
+ (o) => (o.checked === undefined ? null : `checked=${String(o.checked)}`),
7
+ (o) => (o.pressed === undefined ? null : `pressed=${String(o.pressed)}`),
8
+ (o) => (o.selected === undefined ? null : `selected=${String(o.selected)}`),
9
+ (o) => (o.expanded === undefined ? null : `expanded=${String(o.expanded)}`),
10
+ (o) => (o.level === undefined ? null : `level=${String(o.level)}`),
11
+ (o) => (o.busy === undefined ? null : `busy=${String(o.busy)}`),
12
+ (o) => (o.description ? `description ${formatTextMatcher(o.description)}` : null),
13
+ (o) => (o.value ? `value ${formatByRoleValue(o.value)}` : null),
14
+ (o) => (o.hidden === undefined ? null : `hidden=${String(o.hidden)}`),
15
+ ];
16
+ const expensiveErrorDiagnostics = { isDisabled: false };
17
+ const formatTextMatcher = (text) => {
18
+ if (typeof text === "function") {
19
+ return "custom function";
20
+ }
21
+ if (text instanceof RegExp) {
22
+ return text.toString();
23
+ }
24
+ return `'${String(text)}'`;
25
+ };
26
+ const formatByRoleValue = (value) => {
27
+ const parts = [];
28
+ if (value.now !== undefined) {
29
+ parts.push(`now=${String(value.now)}`);
30
+ }
31
+ if (value.min !== undefined) {
32
+ parts.push(`min=${String(value.min)}`);
33
+ }
34
+ if (value.max !== undefined) {
35
+ parts.push(`max=${String(value.max)}`);
36
+ }
37
+ if (value.text !== undefined) {
38
+ parts.push(`text ${formatTextMatcher(value.text)}`);
39
+ }
40
+ return parts.join(", ");
41
+ };
42
+ const roleOptionParts = (options) => {
43
+ const parts = [];
44
+ for (const formatter of roleOptionFormatters) {
45
+ const part = formatter(options);
46
+ if (part !== null) {
47
+ parts.push(part);
48
+ }
49
+ }
50
+ return parts;
51
+ };
52
+ const formatByRoleDescription = (role, options) => {
53
+ const parts = [`role '${formatRole(role).toUpperCase()}'`];
54
+ if (options) {
55
+ parts.push(...roleOptionParts(options));
56
+ }
57
+ return parts.join(" and ");
58
+ };
59
+ const formatQueryDescription = (descriptor) => {
60
+ switch (descriptor.queryType) {
61
+ case "role": {
62
+ return formatByRoleDescription(descriptor.role, descriptor.options);
63
+ }
64
+ case "text": {
65
+ return `text ${formatTextMatcher(descriptor.text)}`;
66
+ }
67
+ case "labelText": {
68
+ return `label text ${formatTextMatcher(descriptor.text)}`;
69
+ }
70
+ case "name": {
71
+ return `name ${formatTextMatcher(descriptor.name)}`;
72
+ }
73
+ case "placeholderText": {
74
+ return `placeholder text ${formatTextMatcher(descriptor.text)}`;
75
+ }
76
+ case "displayValue": {
77
+ return `display value ${formatTextMatcher(descriptor.value)}`;
78
+ }
79
+ }
80
+ };
81
+ const runWithExpensiveErrorDiagnosticsDisabled = (callback) => {
82
+ const isPrevious = expensiveErrorDiagnostics.isDisabled;
83
+ expensiveErrorDiagnostics.isDisabled = true;
84
+ try {
85
+ return callback();
86
+ }
87
+ finally {
88
+ expensiveErrorDiagnostics.isDisabled = isPrevious;
89
+ }
90
+ };
91
+ const buildElementError = (container, headLines) => {
92
+ const config = getConfig();
93
+ const lines = expensiveErrorDiagnostics.isDisabled
94
+ ? headLines
95
+ : [...headLines, "", prettyWidget(container, { highlight: false })];
96
+ return config.getElementError(lines.join("\n"), container);
97
+ };
98
+ const notFoundError = (container, descriptor) => {
99
+ const description = formatQueryDescription(descriptor);
100
+ const headLines = [`Unable to find an element with ${description}`];
101
+ if (!expensiveErrorDiagnostics.isDisabled && descriptor.queryType === "role") {
102
+ headLines.push("", "Here are the accessible roles:", "", prettyRoles(container));
103
+ }
104
+ return buildElementError(container, headLines);
105
+ };
106
+ const allByVariantHint = (descriptor) => {
107
+ const variant = descriptor.queryType === "role" ? "getAllByRole" : "getAllBy*";
108
+ return ("(If this is intentional, use the *AllBy* variant of the query, " +
109
+ `e.g. queryAllBy*/getAllBy*/findAllBy*, such as ${variant}.)`);
110
+ };
111
+ const multipleFoundError = (container, descriptor, matches) => {
112
+ const description = formatQueryDescription(descriptor);
113
+ const headLines = [
114
+ `Found ${String(matches.length)} elements with ${description}, but expected only one`,
115
+ "",
116
+ allByVariantHint(descriptor),
117
+ ];
118
+ if (!expensiveErrorDiagnostics.isDisabled) {
119
+ const renderedMatches = matches.map((widget) => prettyWidget(widget, { highlight: false }));
120
+ headLines.push("", "Here are the matching elements:", "", ...renderedMatches);
121
+ }
122
+ return buildElementError(container, headLines);
123
+ };
124
+ const suggestionError = (suggestion, container) => {
125
+ const config = getConfig();
126
+ const message = `A better query is available, try this:\n${suggestion}\n`;
127
+ return config.getElementError(message, container);
128
+ };
129
+ const timeoutError = (timeout, lastError) => {
130
+ const baseMessage = `Timed out after ${String(timeout)}ms`;
131
+ const message = lastError ? `${baseMessage}.\n\n${lastError.message}` : baseMessage;
132
+ return getConfig().getElementError(message);
133
+ };
134
+ export { runWithExpensiveErrorDiagnosticsDisabled, notFoundError, multipleFoundError, suggestionError, timeoutError, };
135
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\nimport type { Container } from \"./traversal.js\";\nimport type { ByRoleOptions, ByRoleValue, Matcher } from \"./types.js\";\nimport { getConfig } from \"./config.js\";\nimport { prettyWidget } from \"./pretty-widget.js\";\nimport { formatRole, prettyRoles } from \"./role-helpers.js\";\n\ntype QueryDescriptor =\n | { queryType: \"role\"; role: Gtk.AccessibleRole; options?: ByRoleOptions | undefined } |\n { queryType: \"text\"; text: Matcher } |\n { queryType: \"labelText\"; text: Matcher } |\n { queryType: \"name\"; name: Matcher } |\n { queryType: \"placeholderText\"; text: Matcher } |\n { queryType: \"displayValue\"; value: Matcher };\n\nconst roleOptionFormatters: ((options: ByRoleOptions) => string | null)[] = [\n (o) => (o.name ? `name ${formatTextMatcher(o.name)}` : null),\n (o) => (o.checked === undefined ? null : `checked=${String(o.checked)}`),\n (o) => (o.pressed === undefined ? null : `pressed=${String(o.pressed)}`),\n (o) => (o.selected === undefined ? null : `selected=${String(o.selected)}`),\n (o) => (o.expanded === undefined ? null : `expanded=${String(o.expanded)}`),\n (o) => (o.level === undefined ? null : `level=${String(o.level)}`),\n (o) => (o.busy === undefined ? null : `busy=${String(o.busy)}`),\n (o) => (o.description ? `description ${formatTextMatcher(o.description)}` : null),\n (o) => (o.value ? `value ${formatByRoleValue(o.value)}` : null),\n (o) => (o.hidden === undefined ? null : `hidden=${String(o.hidden)}`),\n];\n\nconst expensiveErrorDiagnostics = { isDisabled: false };\n\nconst formatTextMatcher = (text: Matcher): string => {\n if (typeof text === \"function\") {\n return \"custom function\";\n }\n\n if (text instanceof RegExp) {\n return text.toString();\n }\n\n return `'${String(text)}'`;\n};\n\nconst formatByRoleValue = (value: ByRoleValue): string => {\n const parts: string[] = [];\n\n if (value.now !== undefined) {\n parts.push(`now=${String(value.now)}`);\n }\n\n if (value.min !== undefined) {\n parts.push(`min=${String(value.min)}`);\n }\n\n if (value.max !== undefined) {\n parts.push(`max=${String(value.max)}`);\n }\n\n if (value.text !== undefined) {\n parts.push(`text ${formatTextMatcher(value.text)}`);\n }\n\n return parts.join(\", \");\n};\n\nconst roleOptionParts = (options: ByRoleOptions): string[] => {\n const parts: string[] = [];\n\n for (const formatter of roleOptionFormatters) {\n const part = formatter(options);\n\n if (part !== null) {\n parts.push(part);\n }\n }\n\n return parts;\n};\n\nconst formatByRoleDescription = (role: Gtk.AccessibleRole, options?: ByRoleOptions): string => {\n const parts = [`role '${formatRole(role).toUpperCase()}'`];\n\n if (options) {\n parts.push(...roleOptionParts(options));\n }\n\n return parts.join(\" and \");\n};\n\nconst formatQueryDescription = (descriptor: QueryDescriptor): string => {\n switch (descriptor.queryType) {\n case \"role\": {\n return formatByRoleDescription(descriptor.role, descriptor.options);\n }\n case \"text\": {\n return `text ${formatTextMatcher(descriptor.text)}`;\n }\n case \"labelText\": {\n return `label text ${formatTextMatcher(descriptor.text)}`;\n }\n case \"name\": {\n return `name ${formatTextMatcher(descriptor.name)}`;\n }\n case \"placeholderText\": {\n return `placeholder text ${formatTextMatcher(descriptor.text)}`;\n }\n case \"displayValue\": {\n return `display value ${formatTextMatcher(descriptor.value)}`;\n }\n }\n};\n\nconst runWithExpensiveErrorDiagnosticsDisabled = <T>(callback: () => T): T => {\n const isPrevious = expensiveErrorDiagnostics.isDisabled;\n expensiveErrorDiagnostics.isDisabled = true;\n\n try {\n return callback();\n } finally {\n expensiveErrorDiagnostics.isDisabled = isPrevious;\n }\n};\n\nconst buildElementError = (container: Container, headLines: string[]): Error => {\n const config = getConfig();\n\n const lines = expensiveErrorDiagnostics.isDisabled\n ? headLines\n : [...headLines, \"\", prettyWidget(container, { highlight: false })];\n\n return config.getElementError(lines.join(\"\\n\"), container);\n};\n\nconst notFoundError = (container: Container, descriptor: QueryDescriptor): Error => {\n const description = formatQueryDescription(descriptor);\n const headLines = [`Unable to find an element with ${description}`];\n\n if (!expensiveErrorDiagnostics.isDisabled && descriptor.queryType === \"role\") {\n headLines.push(\"\", \"Here are the accessible roles:\", \"\", prettyRoles(container));\n }\n\n return buildElementError(container, headLines);\n};\n\nconst allByVariantHint = (descriptor: QueryDescriptor): string => {\n const variant = descriptor.queryType === \"role\" ? \"getAllByRole\" : \"getAllBy*\";\n\n return (\n \"(If this is intentional, use the *AllBy* variant of the query, \" +\n `e.g. queryAllBy*/getAllBy*/findAllBy*, such as ${variant}.)`\n );\n};\n\nconst multipleFoundError = (container: Container, descriptor: QueryDescriptor, matches: Gtk.Widget[]): Error => {\n const description = formatQueryDescription(descriptor);\n\n const headLines = [\n `Found ${String(matches.length)} elements with ${description}, but expected only one`,\n \"\",\n allByVariantHint(descriptor),\n ];\n\n if (!expensiveErrorDiagnostics.isDisabled) {\n const renderedMatches = matches.map((widget) => prettyWidget(widget, { highlight: false }));\n headLines.push(\"\", \"Here are the matching elements:\", \"\", ...renderedMatches);\n }\n\n return buildElementError(container, headLines);\n};\n\nconst suggestionError = (suggestion: string, container: Container): Error => {\n const config = getConfig();\n const message = `A better query is available, try this:\\n${suggestion}\\n`;\n\n return config.getElementError(message, container);\n};\n\nconst timeoutError = (timeout: number, lastError: Error | null): Error => {\n const baseMessage = `Timed out after ${String(timeout)}ms`;\n const message = lastError ? `${baseMessage}.\\n\\n${lastError.message}` : baseMessage;\n\n return getConfig().getElementError(message);\n};\n\nexport {\n runWithExpensiveErrorDiagnosticsDisabled,\n notFoundError,\n multipleFoundError,\n suggestionError,\n timeoutError,\n type QueryDescriptor,\n};\n"]}
@@ -1,29 +1,12 @@
1
- import { Value } from "@gtkx/ffi/gobject";
2
- import type * as Gtk from "@gtkx/ffi/gtk";
1
+ import type * as GObject from "@gtkx/gi/gobject";
3
2
  /**
4
- * Emits a GTK signal on a widget or event controller.
3
+ * Emits a GObject signal on a widget or object inside React's act environment,
4
+ * so any resulting state updates are flushed before the promise resolves.
5
5
  *
6
- * Low-level utility for triggering signals directly. Prefer {@link userEvent}
7
- * for common interactions like clicking and typing.
8
- *
9
- * @param element - The widget or event controller to emit the signal on
10
- * @param signalName - GTK signal name (e.g., "clicked", "activate", "drag-begin")
11
- * @param args - Additional signal arguments as GValues
12
- *
13
- * @example
14
- * ```tsx
15
- * import { fireEvent } from "@gtkx/testing";
16
- * import { Value } from "@gtkx/ffi/gobject";
17
- *
18
- * // Emit signal on widget
19
- * await fireEvent(widget, "clicked");
20
- *
21
- * // Emit signal on gesture controller
22
- * const gesture = widget.observeControllers().getObject(0) as Gtk.GestureDrag;
23
- * await fireEvent(gesture, "drag-begin", Value.newFromDouble(100), Value.newFromDouble(100));
24
- * ```
25
- *
26
- * @see {@link userEvent} for high-level user interactions
6
+ * @param element The GObject instance to emit the signal on.
7
+ * @param signalName Name of the signal to emit.
8
+ * @param args Arguments passed to the signal handlers.
27
9
  */
28
- export declare const fireEvent: (element: Gtk.Widget | Gtk.EventController, signalName: string, ...args: Value[]) => Promise<void>;
10
+ declare const fireEvent: (element: GObject.Object, signalName: string, ...args: unknown[]) => Promise<void>;
11
+ export { fireEvent };
29
12
  //# sourceMappingURL=fire-event.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fire-event.d.ts","sourceRoot":"","sources":["../src/fire-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC3G,OAAO,KAAK,KAAK,GAAG,MAAM,eAAe,CAAC;AAG1C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,SAAS,GAClB,SAAS,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,eAAe,EACzC,YAAY,MAAM,EAClB,GAAG,MAAM,KAAK,EAAE,KACjB,OAAO,CAAC,IAAI,CASd,CAAC"}
1
+ {"version":3,"file":"fire-event.d.ts","sourceRoot":"","sources":["../src/fire-event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAGjD;;;;;;;GAOG;AACH,QAAA,MAAM,SAAS,GAAU,SAAS,OAAO,CAAC,MAAM,EAAE,YAAY,MAAM,EAAE,GAAG,MAAM,OAAO,EAAE,KAAG,OAAO,CAAC,IAAI,CAItG,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -1,35 +1,16 @@
1
- import { signalEmitv, signalLookup, typeFromName, Value } from "@gtkx/ffi/gobject";
2
- import { tick } from "./timing.js";
1
+ import { runInAct } from "./act.js";
3
2
  /**
4
- * Emits a GTK signal on a widget or event controller.
3
+ * Emits a GObject signal on a widget or object inside React's act environment,
4
+ * so any resulting state updates are flushed before the promise resolves.
5
5
  *
6
- * Low-level utility for triggering signals directly. Prefer {@link userEvent}
7
- * for common interactions like clicking and typing.
8
- *
9
- * @param element - The widget or event controller to emit the signal on
10
- * @param signalName - GTK signal name (e.g., "clicked", "activate", "drag-begin")
11
- * @param args - Additional signal arguments as GValues
12
- *
13
- * @example
14
- * ```tsx
15
- * import { fireEvent } from "@gtkx/testing";
16
- * import { Value } from "@gtkx/ffi/gobject";
17
- *
18
- * // Emit signal on widget
19
- * await fireEvent(widget, "clicked");
20
- *
21
- * // Emit signal on gesture controller
22
- * const gesture = widget.observeControllers().getObject(0) as Gtk.GestureDrag;
23
- * await fireEvent(gesture, "drag-begin", Value.newFromDouble(100), Value.newFromDouble(100));
24
- * ```
25
- *
26
- * @see {@link userEvent} for high-level user interactions
6
+ * @param element The GObject instance to emit the signal on.
7
+ * @param signalName Name of the signal to emit.
8
+ * @param args Arguments passed to the signal handlers.
27
9
  */
28
- export const fireEvent = async (element, signalName, ...args) => {
29
- const gtype = typeFromName(element.constructor.glibTypeName);
30
- const signalId = signalLookup(signalName, gtype);
31
- const instanceValue = Value.newFromObject(element);
32
- signalEmitv([instanceValue, ...args], signalId, 0);
33
- await tick();
10
+ const fireEvent = async (element, signalName, ...args) => {
11
+ await runInAct(() => {
12
+ element.emit(signalName, ...args);
13
+ });
34
14
  };
15
+ export { fireEvent };
35
16
  //# sourceMappingURL=fire-event.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fire-event.js","sourceRoot":"","sources":["../src/fire-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE3G,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC1B,OAAyC,EACzC,UAAkB,EAClB,GAAG,IAAa,EACH,EAAE;IACf,MAAM,KAAK,GAAG,YAAY,CAAE,OAAO,CAAC,WAA8B,CAAC,YAAY,CAAC,CAAC;IACjF,MAAM,QAAQ,GAAG,YAAY,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAEjD,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC,OAAkB,CAAC,CAAC;IAE9D,WAAW,CAAC,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IAEnD,MAAM,IAAI,EAAE,CAAC;AACjB,CAAC,CAAC"}
1
+ {"version":3,"file":"fire-event.js","sourceRoot":"","sources":["../src/fire-event.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC;;;;;;;GAOG;AACH,MAAM,SAAS,GAAG,KAAK,EAAE,OAAuB,EAAE,UAAkB,EAAE,GAAG,IAAe,EAAiB,EAAE;IACvG,MAAM,QAAQ,CAAC,GAAG,EAAE;QAChB,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC","sourcesContent":["import type * as GObject from \"@gtkx/gi/gobject\";\nimport { runInAct } from \"./act.js\";\n\n/**\n * Emits a GObject signal on a widget or object inside React's act environment,\n * so any resulting state updates are flushed before the promise resolves.\n *\n * @param element The GObject instance to emit the signal on.\n * @param signalName Name of the signal to emit.\n * @param args Arguments passed to the signal handlers.\n */\nconst fireEvent = async (element: GObject.Object, signalName: string, ...args: unknown[]): Promise<void> => {\n await runInAct(() => {\n element.emit(signalName, ...args);\n });\n};\n\nexport { fireEvent };\n"]}
@@ -0,0 +1,4 @@
1
+ import type * as Gtk from "@gtkx/gi/gtk";
2
+ declare const scheduleAfterLayout: (widget: Gtk.Widget | null, callback: () => void) => void;
3
+ export { scheduleAfterLayout };
4
+ //# sourceMappingURL=frame-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-sync.d.ts","sourceRoot":"","sources":["../src/frame-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,cAAc,CAAC;AAsCzC,QAAA,MAAM,mBAAmB,GAAI,QAAQ,GAAG,CAAC,MAAM,GAAG,IAAI,EAAE,UAAU,MAAM,IAAI,KAAG,IAU9E,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,37 @@
1
+ import * as GLib from "@gtkx/gi/glib";
2
+ const CLOCK_STALL_FALLBACK_MS = 500;
3
+ const once = (callback) => {
4
+ let isCalled = false;
5
+ return () => {
6
+ if (isCalled) {
7
+ return;
8
+ }
9
+ isCalled = true;
10
+ callback();
11
+ };
12
+ };
13
+ const runWhenSized = (widget, finish) => {
14
+ let tickId = 0;
15
+ const fallback = setTimeout(() => {
16
+ widget.removeTickCallback(tickId);
17
+ finish();
18
+ }, CLOCK_STALL_FALLBACK_MS);
19
+ tickId = widget.addTickCallback(() => {
20
+ if (widget.getWidth() === 0) {
21
+ return GLib.SOURCE_CONTINUE;
22
+ }
23
+ clearTimeout(fallback);
24
+ finish();
25
+ return GLib.SOURCE_REMOVE;
26
+ });
27
+ };
28
+ const scheduleAfterLayout = (widget, callback) => {
29
+ const finish = once(callback);
30
+ if (widget?.getFrameClock() == null || widget.getWidth() > 0) {
31
+ queueMicrotask(finish);
32
+ return;
33
+ }
34
+ runWhenSized(widget, finish);
35
+ };
36
+ export { scheduleAfterLayout };
37
+ //# sourceMappingURL=frame-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-sync.js","sourceRoot":"","sources":["../src/frame-sync.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC;AAEtC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAEpC,MAAM,IAAI,GAAG,CAAC,QAAoB,EAAgB,EAAE;IAChD,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,OAAO,GAAG,EAAE;QACR,IAAI,QAAQ,EAAE,CAAC;YACX,OAAO;QACX,CAAC;QAED,QAAQ,GAAG,IAAI,CAAC;QAChB,QAAQ,EAAE,CAAC;IACf,CAAC,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,MAAkB,EAAE,MAAkB,EAAQ,EAAE;IAClE,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,EAAE;QAC7B,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,EAAE,CAAC;IACb,CAAC,EAAE,uBAAuB,CAAC,CAAC;IAE5B,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE;QACjC,IAAI,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC,eAAe,CAAC;QAChC,CAAC;QAED,YAAY,CAAC,QAAQ,CAAC,CAAC;QACvB,MAAM,EAAE,CAAC;QAET,OAAO,IAAI,CAAC,aAAa,CAAC;IAC9B,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,MAAyB,EAAE,QAAoB,EAAQ,EAAE;IAClF,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAE9B,IAAI,MAAM,EAAE,aAAa,EAAE,IAAI,IAAI,IAAI,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC;QAC3D,cAAc,CAAC,MAAM,CAAC,CAAC;QAEvB,OAAO;IACX,CAAC;IAED,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACjC,CAAC,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,CAAC","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\nimport * as GLib from \"@gtkx/gi/glib\";\n\nconst CLOCK_STALL_FALLBACK_MS = 500;\n\nconst once = (callback: () => void): (() => void) => {\n let isCalled = false;\n\n return () => {\n if (isCalled) {\n return;\n }\n\n isCalled = true;\n callback();\n };\n};\n\nconst runWhenSized = (widget: Gtk.Widget, finish: () => void): void => {\n let tickId = 0;\n\n const fallback = setTimeout(() => {\n widget.removeTickCallback(tickId);\n finish();\n }, CLOCK_STALL_FALLBACK_MS);\n\n tickId = widget.addTickCallback(() => {\n if (widget.getWidth() === 0) {\n return GLib.SOURCE_CONTINUE;\n }\n\n clearTimeout(fallback);\n finish();\n\n return GLib.SOURCE_REMOVE;\n });\n};\n\nconst scheduleAfterLayout = (widget: Gtk.Widget | null, callback: () => void): void => {\n const finish = once(callback);\n\n if (widget?.getFrameClock() == null || widget.getWidth() > 0) {\n queueMicrotask(finish);\n\n return;\n }\n\n runWhenSized(widget, finish);\n};\n\nexport { scheduleAfterLayout };\n"]}
package/dist/index.d.ts CHANGED
@@ -1,21 +1,26 @@
1
- export type { Config } from "./config.js";
1
+ import "./register-test-hooks.js";
2
+ export { act } from "./act.js";
3
+ export type { BoundQueries, RenderResult, Screen } from "./bound-queries.js";
4
+ export type { Config, ConfigFn } from "./config.js";
2
5
  export { configure, getConfig } from "./config.js";
3
6
  export { fireEvent } from "./fire-event.js";
7
+ export type { TextExpectation } from "./matchers.js";
8
+ export { matchers, registerMatchers } from "./matchers.js";
4
9
  export type { PrettyWidgetOptions } from "./pretty-widget.js";
5
- export { prettyWidget } from "./pretty-widget.js";
6
- export { findAllByLabelText, findAllByName, findAllByRole, findAllByText, findByLabelText, findByName, findByRole, findByText, queryAllByLabelText, queryAllByName, queryAllByRole, queryAllByText, queryByLabelText, queryByName, queryByRole, queryByText, } from "./queries.js";
7
- export { cleanup, render } from "./render.js";
10
+ export { logWidget, prettyWidget } from "./pretty-widget.js";
11
+ export { findAllByDisplayValue, findAllByLabelText, findAllByName, findAllByPlaceholderText, findAllByRole, findAllByText, findByDisplayValue, findByLabelText, findByName, findByPlaceholderText, findByRole, findByText, getAllByDisplayValue, getAllByLabelText, getAllByName, getAllByPlaceholderText, getAllByRole, getAllByText, getByDisplayValue, getByLabelText, getByName, getByPlaceholderText, getByRole, getByText, getDefaultNormalizer, queryAllByDisplayValue, queryAllByLabelText, queryAllByName, queryAllByPlaceholderText, queryAllByRole, queryAllByText, queryByDisplayValue, queryByLabelText, queryByName, queryByPlaceholderText, queryByRole, queryByText, } from "./queries.js";
8
12
  export { renderHook } from "./render-hook.js";
9
- export type { RoleInfo } from "./role-helpers.js";
10
- export { getRoles, logRoles, prettyRoles } from "./role-helpers.js";
13
+ export { cleanup, render } from "./render.js";
14
+ export { formatRole, getRoles, logRoles, prettyRoles } from "./role-helpers.js";
11
15
  export { screen } from "./screen.js";
12
- export type { ScreenshotOptions } from "./screenshot.js";
13
- export { screenshot } from "./screenshot.js";
14
- export { tick } from "./timing.js";
16
+ export { captureAndSaveScreenshot, logScreenshotPath, screenshot } from "./screenshot.js";
17
+ export type { Method, Suggestion, Variant } from "./suggestions.js";
18
+ export { getSuggestedQuery } from "./suggestions.js";
15
19
  export type { Container } from "./traversal.js";
16
- export type { BoundQueries, ByRoleOptions, NormalizerOptions, RenderHookOptions, RenderHookResult, RenderOptions, RenderResult, ScreenshotResult, TextMatch, TextMatchFunction, TextMatchOptions, WaitForOptions, WrapperComponent, } from "./types.js";
17
- export type { PointerInput, TabOptions } from "./user-event.js";
18
- export { userEvent } from "./user-event.js";
20
+ export type { ByRoleOptions, ByRoleValue, Matcher, MatcherFunction, MatcherOptions, NormalizerFn, NormalizerOptions, RenderHookOptions, RenderHookResult, RenderOptions, ScreenshotOptions, ScreenshotResult, WaitForOptions, WindowSelector, WrapperComponent, } from "./types.js";
21
+ export type { DragOffset, DragOptions, DropContent, DropOptions, PointerInput, ScrollDelta, TabOptions, TypeOptions, UserEvent, } from "./user-event/index.js";
22
+ export { userEvent } from "./user-event/index.js";
19
23
  export { waitFor, waitForElementToBeRemoved } from "./wait-for.js";
24
+ export { getWidgetErrorMessage, getWidgetInvalidState, getWidgetNodeText, } from "./widget-accessible-properties.js";
20
25
  export { within } from "./within.js";
21
26
  //# sourceMappingURL=index.d.ts.map