@gtkx/testing 0.20.0 → 1.0.0-rc.1

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 +122 -55
  2. package/dist/act.d.ts +19 -0
  3. package/dist/act.d.ts.map +1 -0
  4. package/dist/act.js +48 -0
  5. package/dist/act.js.map +1 -0
  6. package/dist/bound-queries.d.ts +32 -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 +103 -0
  13. package/dist/build-queries.js.map +1 -0
  14. package/dist/cleanup-registry.d.ts +4 -0
  15. package/dist/cleanup-registry.d.ts.map +1 -0
  16. package/dist/cleanup-registry.js +11 -0
  17. package/dist/cleanup-registry.js.map +1 -0
  18. package/dist/config.d.ts +18 -51
  19. package/dist/config.d.ts.map +1 -1
  20. package/dist/config.js +9 -40
  21. package/dist/config.js.map +1 -1
  22. package/dist/editable.d.ts +7 -0
  23. package/dist/editable.d.ts.map +1 -0
  24. package/dist/editable.js +24 -0
  25. package/dist/editable.js.map +1 -0
  26. package/dist/errors.d.ts +29 -0
  27. package/dist/errors.d.ts.map +1 -0
  28. package/dist/errors.js +119 -0
  29. package/dist/errors.js.map +1 -0
  30. package/dist/fire-event.d.ts +7 -25
  31. package/dist/fire-event.d.ts.map +1 -1
  32. package/dist/fire-event.js +9 -29
  33. package/dist/fire-event.js.map +1 -1
  34. package/dist/frame-sync.d.ts +3 -0
  35. package/dist/frame-sync.d.ts.map +1 -0
  36. package/dist/frame-sync.js +30 -0
  37. package/dist/frame-sync.js.map +1 -0
  38. package/dist/index.d.ts +16 -11
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +10 -6
  41. package/dist/index.js.map +1 -1
  42. package/dist/matchers.d.ts +55 -0
  43. package/dist/matchers.d.ts.map +1 -0
  44. package/dist/matchers.js +103 -0
  45. package/dist/matchers.js.map +1 -0
  46. package/dist/pretty-widget.d.ts +21 -25
  47. package/dist/pretty-widget.d.ts.map +1 -1
  48. package/dist/pretty-widget.js +69 -115
  49. package/dist/pretty-widget.js.map +1 -1
  50. package/dist/queries.d.ts +130 -177
  51. package/dist/queries.d.ts.map +1 -1
  52. package/dist/queries.js +212 -325
  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 +15 -0
  57. package/dist/register-test-hooks.js.map +1 -0
  58. package/dist/render-hook.d.ts +14 -35
  59. package/dist/render-hook.d.ts.map +1 -1
  60. package/dist/render-hook.js +8 -45
  61. package/dist/render-hook.js.map +1 -1
  62. package/dist/render.d.ts +11 -41
  63. package/dist/render.d.ts.map +1 -1
  64. package/dist/render.js +129 -118
  65. package/dist/render.js.map +1 -1
  66. package/dist/role-helpers.d.ts +16 -51
  67. package/dist/role-helpers.d.ts.map +1 -1
  68. package/dist/role-helpers.js +39 -58
  69. package/dist/role-helpers.js.map +1 -1
  70. package/dist/screen.d.ts +6 -63
  71. package/dist/screen.d.ts.map +1 -1
  72. package/dist/screen.js +21 -109
  73. package/dist/screen.js.map +1 -1
  74. package/dist/screenshot.d.ts +20 -23
  75. package/dist/screenshot.d.ts.map +1 -1
  76. package/dist/screenshot.js +89 -48
  77. package/dist/screenshot.js.map +1 -1
  78. package/dist/suggestions.d.ts +22 -0
  79. package/dist/suggestions.d.ts.map +1 -0
  80. package/dist/suggestions.js +56 -0
  81. package/dist/suggestions.js.map +1 -0
  82. package/dist/traversal.d.ts +10 -8
  83. package/dist/traversal.d.ts.map +1 -1
  84. package/dist/traversal.js +28 -13
  85. package/dist/traversal.js.map +1 -1
  86. package/dist/types.d.ts +103 -172
  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 +8 -0
  90. package/dist/user-event/adjustment.d.ts.map +1 -0
  91. package/dist/user-event/adjustment.js +33 -0
  92. package/dist/user-event/adjustment.js.map +1 -0
  93. package/dist/user-event/click.d.ts +7 -0
  94. package/dist/user-event/click.d.ts.map +1 -0
  95. package/dist/user-event/click.js +65 -0
  96. package/dist/user-event/click.js.map +1 -0
  97. package/dist/user-event/controller.d.ts +7 -0
  98. package/dist/user-event/controller.d.ts.map +1 -0
  99. package/dist/user-event/controller.js +28 -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 +10 -0
  104. package/dist/user-event/dispatch.js.map +1 -0
  105. package/dist/user-event/event-wrapper.d.ts +3 -0
  106. package/dist/user-event/event-wrapper.d.ts.map +1 -0
  107. package/dist/user-event/event-wrapper.js +48 -0
  108. package/dist/user-event/event-wrapper.js.map +1 -0
  109. package/dist/user-event/gesture.d.ts +31 -0
  110. package/dist/user-event/gesture.d.ts.map +1 -0
  111. package/dist/user-event/gesture.js +105 -0
  112. package/dist/user-event/gesture.js.map +1 -0
  113. package/dist/user-event/index.d.ts +44 -0
  114. package/dist/user-event/index.d.ts.map +1 -0
  115. package/dist/user-event/index.js +38 -0
  116. package/dist/user-event/index.js.map +1 -0
  117. package/dist/user-event/keyboard.d.ts +9 -0
  118. package/dist/user-event/keyboard.d.ts.map +1 -0
  119. package/dist/user-event/keyboard.js +173 -0
  120. package/dist/user-event/keyboard.js.map +1 -0
  121. package/dist/user-event/pointer.d.ts +6 -0
  122. package/dist/user-event/pointer.d.ts.map +1 -0
  123. package/dist/user-event/pointer.js +27 -0
  124. package/dist/user-event/pointer.js.map +1 -0
  125. package/dist/user-event/selection.d.ts +4 -0
  126. package/dist/user-event/selection.d.ts.map +1 -0
  127. package/dist/user-event/selection.js +106 -0
  128. package/dist/user-event/selection.js.map +1 -0
  129. package/dist/user-event/state.d.ts +6 -0
  130. package/dist/user-event/state.d.ts.map +1 -0
  131. package/dist/user-event/state.js +2 -0
  132. package/dist/user-event/state.js.map +1 -0
  133. package/dist/user-event/text.d.ts +17 -0
  134. package/dist/user-event/text.d.ts.map +1 -0
  135. package/dist/user-event/text.js +107 -0
  136. package/dist/user-event/text.js.map +1 -0
  137. package/dist/wait-for.d.ts +13 -32
  138. package/dist/wait-for.d.ts.map +1 -1
  139. package/dist/wait-for.js +62 -73
  140. package/dist/wait-for.js.map +1 -1
  141. package/dist/widget-accessible-properties.d.ts +33 -0
  142. package/dist/widget-accessible-properties.d.ts.map +1 -0
  143. package/dist/widget-accessible-properties.js +215 -0
  144. package/dist/widget-accessible-properties.js.map +1 -0
  145. package/dist/within.d.ts +9 -26
  146. package/dist/within.d.ts.map +1 -1
  147. package/dist/within.js +15 -25
  148. package/dist/within.js.map +1 -1
  149. package/package.json +21 -12
  150. package/src/act.ts +68 -0
  151. package/src/bound-queries.ts +36 -0
  152. package/src/build-queries.ts +185 -0
  153. package/src/cleanup-registry.ts +14 -0
  154. package/src/config.ts +28 -59
  155. package/src/editable.ts +30 -0
  156. package/src/errors.ts +130 -0
  157. package/src/fire-event.ts +11 -38
  158. package/src/frame-sync.ts +34 -0
  159. package/src/index.ts +60 -18
  160. package/src/matchers.ts +200 -0
  161. package/src/pretty-widget.ts +99 -138
  162. package/src/queries.ts +321 -425
  163. package/src/register-test-hooks.ts +16 -0
  164. package/src/render-hook.tsx +31 -44
  165. package/src/render.tsx +161 -149
  166. package/src/role-helpers.ts +47 -67
  167. package/src/screen.ts +21 -114
  168. package/src/screenshot.ts +104 -55
  169. package/src/suggestions.ts +87 -0
  170. package/src/traversal.ts +32 -18
  171. package/src/types.ts +115 -176
  172. package/src/user-event/adjustment.ts +49 -0
  173. package/src/user-event/click.ts +70 -0
  174. package/src/user-event/controller.ts +44 -0
  175. package/src/user-event/dispatch.ts +23 -0
  176. package/src/user-event/event-wrapper.ts +54 -0
  177. package/src/user-event/gesture.ts +154 -0
  178. package/src/user-event/index.ts +74 -0
  179. package/src/user-event/keyboard.ts +204 -0
  180. package/src/user-event/pointer.ts +34 -0
  181. package/src/user-event/selection.ts +122 -0
  182. package/src/user-event/state.ts +6 -0
  183. package/src/user-event/text.ts +137 -0
  184. package/src/wait-for.ts +79 -80
  185. package/src/widget-accessible-properties.ts +244 -0
  186. package/src/within.ts +26 -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/types.d.ts CHANGED
@@ -1,200 +1,131 @@
1
- import type * as Gtk from "@gtkx/ffi/gtk";
2
- import type { ComponentType, ReactNode, Ref } from "react";
1
+ import type * as Gtk from "@gtkx/gi/gtk";
2
+ import type { RootElement } from "@gtkx/react";
3
+ import type { ComponentType, ErrorInfo, ReactNode } from "react";
4
+ import type { PrettyWidgetOptions } from "./pretty-widget.js";
3
5
  import type { Container } from "./traversal.js";
4
- /**
5
- * Custom function for matching text content.
6
- *
7
- * @param content - The normalized text content to match against
8
- * @param widget - The widget being tested
9
- * @returns `true` if the content matches
10
- */
11
- export type TextMatchFunction = (content: string, widget: Gtk.Widget) => boolean;
12
- /**
13
- * Text matching pattern.
14
- *
15
- * Can be a string for exact/substring matching, a RegExp for pattern matching,
16
- * or a custom function for advanced matching logic.
17
- */
18
- export type TextMatch = string | RegExp | TextMatchFunction;
19
- /**
20
- * Options for text normalization before matching.
21
- */
6
+ /** A custom matcher predicate: given a candidate widget's normalized text content and the widget itself, returns whether it matches. */
7
+ export type MatcherFunction = (content: string, widget: Gtk.Widget) => boolean;
8
+ /** A value used to match widget text: a string or number, a regular expression, or a custom {@link MatcherFunction}. */
9
+ export type Matcher = string | number | RegExp | MatcherFunction;
10
+ /** Normalizes a widget's text before it is compared against a matcher. */
11
+ export type NormalizerFn = (text: string) => string;
12
+ /** Options controlling the default text normalizer. */
22
13
  export type NormalizerOptions = {
23
- /** Remove leading/trailing whitespace (default: true) */
24
- trim?: boolean;
25
- /** Replace multiple whitespace characters with single space (default: true) */
26
- collapseWhitespace?: boolean;
14
+ /** Trim leading and trailing whitespace. */
15
+ trim?: boolean | undefined;
16
+ /** Collapse runs of whitespace into a single space. */
17
+ collapseWhitespace?: boolean | undefined;
27
18
  };
28
- /**
29
- * Options for text-based queries.
30
- */
31
- export type TextMatchOptions = {
32
- /** Require exact match vs substring match (default: true) */
33
- exact?: boolean;
34
- /** Custom text normalizer function */
35
- normalizer?: (text: string) => string;
36
- /** Remove leading/trailing whitespace (default: true) */
37
- trim?: boolean;
38
- /** Replace multiple whitespace with single space (default: true) */
39
- collapseWhitespace?: boolean;
40
- /** Timeout in milliseconds for async queries (default: 1000) */
41
- timeout?: number;
19
+ /** Options controlling how asynchronous queries and waits poll for a condition. */
20
+ export type WaitForOptions = {
21
+ /** Maximum time in milliseconds to keep retrying before failing. */
22
+ timeout?: number | undefined;
23
+ /** Delay in milliseconds between retries. */
24
+ interval?: number | undefined;
25
+ /** Transforms the error thrown when the timeout elapses. */
26
+ onTimeout?: ((error: Error) => Error) | undefined;
27
+ /** Error whose stack trace attributes the timeout failure to the calling code. */
28
+ stackTraceError?: Error | undefined;
42
29
  };
43
- /**
44
- * Options for role-based queries.
45
- *
46
- * Extends text matching options with accessible state filters.
47
- */
48
- export type ByRoleOptions = TextMatchOptions & {
49
- /** Filter by accessible name/label */
50
- name?: TextMatch;
51
- /** Filter by checked state (checkboxes, radios, toggles) */
52
- checked?: boolean;
53
- /** Filter by pressed state */
54
- pressed?: boolean;
55
- /** Filter by selected state */
56
- selected?: boolean;
57
- /** Filter by expanded state (expanders) */
58
- expanded?: boolean;
59
- /** Filter by heading level */
60
- level?: number;
30
+ /** Options controlling text matching and, for asynchronous queries, polling behavior. */
31
+ export type MatcherOptions = {
32
+ /** When true (the default), require an exact match; when false, match case-insensitively as a substring. */
33
+ exact?: boolean | undefined;
34
+ /** Custom normalizer replacing the default; cannot be combined with `trim` or `collapseWhitespace`. */
35
+ normalizer?: NormalizerFn | undefined;
36
+ /** Forwarded to the default normalizer when no custom `normalizer` is given. */
37
+ trim?: boolean | undefined;
38
+ /** Forwarded to the default normalizer when no custom `normalizer` is given. */
39
+ collapseWhitespace?: boolean | undefined;
40
+ /** Whether to include a suggested better query in error messages. */
41
+ suggest?: boolean | undefined;
42
+ } & WaitForOptions;
43
+ /** Constraints on a widget's numeric range value used by role queries. */
44
+ export type ByRoleValue = {
45
+ /** The current value. */
46
+ now?: number | undefined;
47
+ min?: number | undefined;
48
+ max?: number | undefined;
49
+ /** Matcher for the value's textual representation. */
50
+ text?: Matcher | undefined;
61
51
  };
62
- /**
63
- * Options for {@link waitFor} and {@link waitForElementToBeRemoved}.
64
- */
65
- export type WaitForOptions = {
66
- /** Maximum time to wait in milliseconds (default: 1000) */
67
- timeout?: number;
68
- /** Polling interval in milliseconds (default: 50) */
69
- interval?: number;
70
- /** Custom error handler called on timeout */
71
- onTimeout?: (error: Error) => Error;
52
+ /** Options for role queries: an accessible name matcher plus accessible state and value constraints. */
53
+ export type ByRoleOptions = MatcherOptions & {
54
+ name?: Matcher | undefined;
55
+ checked?: boolean | undefined;
56
+ pressed?: boolean | undefined;
57
+ selected?: boolean | undefined;
58
+ expanded?: boolean | undefined;
59
+ /** Heading or hierarchy level. */
60
+ level?: number | undefined;
61
+ busy?: boolean | undefined;
62
+ description?: Matcher | undefined;
63
+ value?: ByRoleValue | undefined;
64
+ /** When true, include widgets excluded from the accessibility tree. */
65
+ hidden?: boolean | undefined;
72
66
  };
73
- /**
74
- * A wrapper component that exposes its root GTK widget via `ref`.
75
- * Accept `ref` as a prop and pass it through to the root intrinsic element.
76
- */
67
+ /** A React component that wraps rendered content, receiving it as its children. */
77
68
  export type WrapperComponent = ComponentType<{
78
69
  children: ReactNode;
79
- ref?: Ref<Gtk.Widget>;
80
70
  }>;
81
- /**
82
- * Options for {@link render}.
83
- */
84
- export type RenderOptions = {
85
- /**
86
- * Wrapper component or boolean.
87
- * - `true` (default): Wrap in GtkApplicationWindow
88
- * - `false`: No wrapper
89
- * - Component: Custom wrapper that passes `ref` to its root element
90
- */
91
- wrapper?: boolean | WrapperComponent;
92
- /**
93
- * The element queries are bound to.
94
- * Defaults to the GTK Application (searches all toplevel windows).
95
- * Provide a specific widget or application to scope queries.
96
- */
97
- baseElement?: Container;
71
+ type Query = (container: Container, ...args: never[]) => unknown;
72
+ export type QueryMap = Record<string, Query>;
73
+ type BoundQuery<Q extends Query> = Q extends (container: Container, ...args: infer A) => infer R ? (...args: A) => R : never;
74
+ export type BoundCustomQueries<Q extends QueryMap> = {
75
+ [K in keyof Q]: BoundQuery<Q[K]>;
98
76
  };
99
- /**
100
- * Query methods bound to a container.
101
- *
102
- * @see {@link screen} for global queries
103
- * @see {@link within} for scoped queries
104
- */
105
- export type BoundQueries = {
106
- /** Query single element by accessible role (returns null if not found) */
107
- queryByRole: (role: Gtk.AccessibleRole, options?: ByRoleOptions) => Gtk.Widget | null;
108
- /** Query single element by label/text content (returns null if not found) */
109
- queryByLabelText: (text: TextMatch, options?: TextMatchOptions) => Gtk.Widget | null;
110
- /** Query single element by visible text (returns null if not found) */
111
- queryByText: (text: TextMatch, options?: TextMatchOptions) => Gtk.Widget | null;
112
- /** Query single element by test ID (returns null if not found) */
113
- queryByTestId: (testId: TextMatch, options?: TextMatchOptions) => Gtk.Widget | null;
114
- /** Query all elements by accessible role (returns empty array if none found) */
115
- queryAllByRole: (role: Gtk.AccessibleRole, options?: ByRoleOptions) => Gtk.Widget[];
116
- /** Query all elements by label/text content (returns empty array if none found) */
117
- queryAllByLabelText: (text: TextMatch, options?: TextMatchOptions) => Gtk.Widget[];
118
- /** Query all elements by visible text (returns empty array if none found) */
119
- queryAllByText: (text: TextMatch, options?: TextMatchOptions) => Gtk.Widget[];
120
- /** Query all elements by test ID (returns empty array if none found) */
121
- queryAllByTestId: (testId: TextMatch, options?: TextMatchOptions) => Gtk.Widget[];
122
- /** Find single element by accessible role (waits and throws if not found) */
123
- findByRole: (role: Gtk.AccessibleRole, options?: ByRoleOptions) => Promise<Gtk.Widget>;
124
- /** Find single element by label/text content (waits and throws if not found) */
125
- findByLabelText: (text: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget>;
126
- /** Find single element by visible text (waits and throws if not found) */
127
- findByText: (text: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget>;
128
- /** Find single element by test ID (waits and throws if not found) */
129
- findByTestId: (testId: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget>;
130
- /** Find all elements by accessible role (waits and throws if none found) */
131
- findAllByRole: (role: Gtk.AccessibleRole, options?: ByRoleOptions) => Promise<Gtk.Widget[]>;
132
- /** Find all elements by label/text content (waits and throws if none found) */
133
- findAllByLabelText: (text: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget[]>;
134
- /** Find all elements by visible text (waits and throws if none found) */
135
- findAllByText: (text: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget[]>;
136
- /** Find all elements by test ID (waits and throws if none found) */
137
- findAllByTestId: (testId: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget[]>;
77
+ /** Options for {@link render}: the container and base element to mount into, an optional wrapper, React behavior toggles, error callbacks, and custom queries to bind. */
78
+ export type RenderOptions<Q extends QueryMap = Record<never, never>> = {
79
+ container?: Gtk.Widget | RootElement | undefined;
80
+ /** Root of the subtree that bound queries search. */
81
+ baseElement?: Container | undefined;
82
+ wrapper?: WrapperComponent | undefined;
83
+ /** Render inside React StrictMode. */
84
+ reactStrictMode?: boolean | undefined;
85
+ /** Enable widget animations during the test. */
86
+ animations?: boolean | undefined;
87
+ /** Called for errors caught by React error boundaries. */
88
+ onCaughtError?: ((error: unknown, errorInfo: ErrorInfo) => void) | undefined;
89
+ /** Called for errors React recovered from automatically. */
90
+ onRecoverableError?: ((error: unknown, errorInfo: ErrorInfo) => void) | undefined;
91
+ /** Custom queries to bind to the rendered result. */
92
+ queries?: Q | undefined;
138
93
  };
139
- /**
140
- * Result returned by {@link render}.
141
- *
142
- * Provides query methods and utilities for testing rendered components.
143
- */
144
- export type RenderResult = BoundQueries & {
145
- /** The direct container widget wrapping the rendered content */
146
- container: Gtk.Widget;
147
- /** The element queries are bound to (defaults to the GTK Application) */
148
- baseElement: Container;
149
- /** Unmount the rendered component */
150
- unmount: () => Promise<void>;
151
- /** Re-render with a new element */
152
- rerender: (element: ReactNode) => Promise<void>;
153
- /** Print the widget tree to console for debugging */
154
- debug: () => void;
94
+ export type DebugUtilities = {
95
+ debug: (element?: Container | Container[], options?: PrettyWidgetOptions) => void;
96
+ logRoles: () => void;
97
+ screenshot: (selector?: WindowSelector, options?: ScreenshotOptions) => Promise<ScreenshotResult>;
155
98
  };
156
- /**
157
- * Result returned by {@link screenshot} and screen.screenshot.
158
- */
99
+ /** A captured screenshot: base64-encoded image data, its MIME type, and pixel dimensions. */
159
100
  export type ScreenshotResult = {
160
- /** Base64-encoded PNG image data */
161
101
  data: string;
162
- /** MIME type of the image (always "image/png") */
163
102
  mimeType: string;
164
- /** Width of the captured image in pixels */
165
103
  width: number;
166
- /** Height of the captured image in pixels */
167
104
  height: number;
168
105
  };
169
- /**
170
- * Options for {@link renderHook}.
171
- */
106
+ /** Options for capturing a screenshot: the poll timeout and interval, plus a rendering scale factor. */
107
+ export type ScreenshotOptions = Pick<WaitForOptions, "timeout" | "interval"> & {
108
+ /** Device scale factor applied when rendering. */
109
+ scale?: number;
110
+ };
111
+ /** Selects the window to screenshot by index, or by title (exact string or regular expression); undefined targets the default window. */
112
+ export type WindowSelector = number | string | RegExp | undefined;
113
+ /** Options for {@link renderHook}: an optional wrapper and the initial props (required unless the props type permits undefined). */
172
114
  export type RenderHookOptions<Props> = {
173
- /**
174
- * Initial props passed to the hook callback.
175
- */
115
+ wrapper?: WrapperComponent;
116
+ } & (undefined extends Props ? {
176
117
  initialProps?: Props;
177
- /**
178
- * Wrapper component or boolean.
179
- * - `true` (default): Wrap in GtkApplicationWindow
180
- * - `false`: No wrapper
181
- * - Component: Custom wrapper that passes `ref` to its root element
182
- */
183
- wrapper?: boolean | WrapperComponent;
184
- };
185
- /**
186
- * Result returned by {@link renderHook}.
187
- *
188
- * Provides access to the hook result and utilities for re-rendering and cleanup.
189
- */
118
+ } : {
119
+ initialProps: Props;
120
+ });
121
+ /** The result of {@link renderHook}: the latest hook return value plus functions to rerender with new props and to unmount. */
190
122
  export type RenderHookResult<Result, Props> = {
191
- /** Object containing the current hook return value */
123
+ /** Holds the most recent value returned by the hook under `current`. */
192
124
  result: {
193
125
  current: Result;
194
126
  };
195
- /** Re-render the hook with optional new props */
196
127
  rerender: (newProps?: Props) => Promise<void>;
197
- /** Unmount the component containing the hook */
198
128
  unmount: () => Promise<void>;
199
129
  };
130
+ export {};
200
131
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\nimport type { RootElement } from \"@gtkx/react\";\nimport type { ComponentType, ErrorInfo, ReactNode } from \"react\";\nimport type { PrettyWidgetOptions } from \"./pretty-widget.js\";\nimport type { Container } from \"./traversal.js\";\n\n/** A custom matcher predicate: given a candidate widget's normalized text content and the widget itself, returns whether it matches. */\nexport type MatcherFunction = (content: string, widget: Gtk.Widget) => boolean;\n\n/** A value used to match widget text: a string or number, a regular expression, or a custom {@link MatcherFunction}. */\nexport type Matcher = string | number | RegExp | MatcherFunction;\n\n/** Normalizes a widget's text before it is compared against a matcher. */\nexport type NormalizerFn = (text: string) => string;\n\n/** Options controlling the default text normalizer. */\nexport type NormalizerOptions = {\n /** Trim leading and trailing whitespace. */\n trim?: boolean | undefined;\n /** Collapse runs of whitespace into a single space. */\n collapseWhitespace?: boolean | undefined;\n};\n\n/** Options controlling how asynchronous queries and waits poll for a condition. */\nexport type WaitForOptions = {\n /** Maximum time in milliseconds to keep retrying before failing. */\n timeout?: number | undefined;\n /** Delay in milliseconds between retries. */\n interval?: number | undefined;\n /** Transforms the error thrown when the timeout elapses. */\n onTimeout?: ((error: Error) => Error) | undefined;\n /** Error whose stack trace attributes the timeout failure to the calling code. */\n stackTraceError?: Error | undefined;\n};\n\n/** Options controlling text matching and, for asynchronous queries, polling behavior. */\nexport type MatcherOptions = {\n /** When true (the default), require an exact match; when false, match case-insensitively as a substring. */\n exact?: boolean | undefined;\n /** Custom normalizer replacing the default; cannot be combined with `trim` or `collapseWhitespace`. */\n normalizer?: NormalizerFn | undefined;\n /** Forwarded to the default normalizer when no custom `normalizer` is given. */\n trim?: boolean | undefined;\n /** Forwarded to the default normalizer when no custom `normalizer` is given. */\n collapseWhitespace?: boolean | undefined;\n /** Whether to include a suggested better query in error messages. */\n suggest?: boolean | undefined;\n} & WaitForOptions;\n\n/** Constraints on a widget's numeric range value used by role queries. */\nexport type ByRoleValue = {\n /** The current value. */\n now?: number | undefined;\n min?: number | undefined;\n max?: number | undefined;\n /** Matcher for the value's textual representation. */\n text?: Matcher | undefined;\n};\n\n/** Options for role queries: an accessible name matcher plus accessible state and value constraints. */\nexport type ByRoleOptions = MatcherOptions & {\n name?: Matcher | undefined;\n checked?: boolean | undefined;\n pressed?: boolean | undefined;\n selected?: boolean | undefined;\n expanded?: boolean | undefined;\n /** Heading or hierarchy level. */\n level?: number | undefined;\n busy?: boolean | undefined;\n description?: Matcher | undefined;\n value?: ByRoleValue | undefined;\n /** When true, include widgets excluded from the accessibility tree. */\n hidden?: boolean | undefined;\n};\n\n/** A React component that wraps rendered content, receiving it as its children. */\nexport type WrapperComponent = ComponentType<{\n children: ReactNode;\n}>;\n\ntype Query = (container: Container, ...args: never[]) => unknown;\n\nexport type QueryMap = Record<string, Query>;\n\ntype BoundQuery<Q extends Query> = Q extends (container: Container, ...args: infer A) => infer R\n ? (...args: A) => R\n : never;\n\nexport type BoundCustomQueries<Q extends QueryMap> = { [K in keyof Q]: BoundQuery<Q[K]> };\n\n/** Options for {@link render}: the container and base element to mount into, an optional wrapper, React behavior toggles, error callbacks, and custom queries to bind. */\nexport type RenderOptions<Q extends QueryMap = Record<never, never>> = {\n container?: Gtk.Widget | RootElement | undefined;\n /** Root of the subtree that bound queries search. */\n baseElement?: Container | undefined;\n wrapper?: WrapperComponent | undefined;\n /** Render inside React StrictMode. */\n reactStrictMode?: boolean | undefined;\n /** Enable widget animations during the test. */\n animations?: boolean | undefined;\n /** Called for errors caught by React error boundaries. */\n onCaughtError?: ((error: unknown, errorInfo: ErrorInfo) => void) | undefined;\n /** Called for errors React recovered from automatically. */\n onRecoverableError?: ((error: unknown, errorInfo: ErrorInfo) => void) | undefined;\n /** Custom queries to bind to the rendered result. */\n queries?: Q | undefined;\n};\n\nexport type DebugUtilities = {\n debug: (element?: Container | Container[], options?: PrettyWidgetOptions) => void;\n logRoles: () => void;\n screenshot: (selector?: WindowSelector, options?: ScreenshotOptions) => Promise<ScreenshotResult>;\n};\n\n/** A captured screenshot: base64-encoded image data, its MIME type, and pixel dimensions. */\nexport type ScreenshotResult = {\n data: string;\n mimeType: string;\n width: number;\n height: number;\n};\n\n/** Options for capturing a screenshot: the poll timeout and interval, plus a rendering scale factor. */\nexport type ScreenshotOptions = Pick<WaitForOptions, \"timeout\" | \"interval\"> & {\n /** Device scale factor applied when rendering. */\n scale?: number;\n};\n\n/** Selects the window to screenshot by index, or by title (exact string or regular expression); undefined targets the default window. */\nexport type WindowSelector = number | string | RegExp | undefined;\n\n/** Options for {@link renderHook}: an optional wrapper and the initial props (required unless the props type permits undefined). */\nexport type RenderHookOptions<Props> = {\n wrapper?: WrapperComponent;\n} & (undefined extends Props\n ? {\n initialProps?: Props;\n }\n : {\n initialProps: Props;\n });\n\n/** The result of {@link renderHook}: the latest hook return value plus functions to rerender with new props and to unmount. */\nexport type RenderHookResult<Result, Props> = {\n /** Holds the most recent value returned by the hook under `current`. */\n result: { current: Result };\n rerender: (newProps?: Props) => Promise<void>;\n unmount: () => Promise<void>;\n};\n"]}
@@ -0,0 +1,8 @@
1
+ import * as Gtk from "@gtkx/gi/gtk";
2
+ export type ScrollDelta = {
3
+ x?: number;
4
+ y?: number;
5
+ };
6
+ export declare const slide: (widget: Gtk.Widget, value: number) => Promise<void>;
7
+ export declare const scroll: (widget: Gtk.Widget, delta: ScrollDelta) => Promise<void>;
8
+ //# sourceMappingURL=adjustment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adjustment.d.ts","sourceRoot":"","sources":["../../src/user-event/adjustment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AAGpC,MAAM,MAAM,WAAW,GAAG;IACtB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,eAAO,MAAM,KAAK,WAAY,GAAG,CAAC,MAAM,SAAS,MAAM,KAAG,OAAO,CAAC,IAAI,CAMhE,CAAC;AAwBP,eAAO,MAAM,MAAM,WAAY,GAAG,CAAC,MAAM,SAAS,WAAW,KAAG,OAAO,CAAC,IAAI,CAUtE,CAAC"}
@@ -0,0 +1,33 @@
1
+ import * as Gtk from "@gtkx/gi/gtk";
2
+ import { wrapEvent } from "./event-wrapper.js";
3
+ export const slide = (widget, value) => wrapEvent(widget, () => {
4
+ if (!(widget instanceof Gtk.Range)) {
5
+ throw new Error(`userEvent.slide requires a Gtk.Range (e.g. Gtk.Scale), got ${widget.constructor.name}`);
6
+ }
7
+ widget.emit("change-value", Gtk.ScrollType.JUMP, value);
8
+ });
9
+ const resolveScrollAdjustments = (widget) => {
10
+ for (let current = widget; current; current = current.getParent()) {
11
+ if (current instanceof Gtk.ScrolledWindow) {
12
+ return { horizontal: current.getHadjustment(), vertical: current.getVadjustment() };
13
+ }
14
+ if (current instanceof Gtk.Scrollable) {
15
+ return { horizontal: current.getHadjustment(), vertical: current.getVadjustment() };
16
+ }
17
+ }
18
+ return null;
19
+ };
20
+ const applyScrollDelta = (adjustment, delta) => {
21
+ if (!adjustment || delta === 0)
22
+ return;
23
+ adjustment.setValue(adjustment.getValue() + delta);
24
+ };
25
+ export const scroll = (widget, delta) => wrapEvent(widget, () => {
26
+ const adjustments = resolveScrollAdjustments(widget);
27
+ if (!adjustments) {
28
+ throw new Error("userEvent.scroll: no Gtk.ScrolledWindow or Gtk.Scrollable found on the widget or its ancestors");
29
+ }
30
+ applyScrollDelta(adjustments.horizontal, delta.x ?? 0);
31
+ applyScrollDelta(adjustments.vertical, delta.y ?? 0);
32
+ });
33
+ //# sourceMappingURL=adjustment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adjustment.js","sourceRoot":"","sources":["../../src/user-event/adjustment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAO/C,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,MAAkB,EAAE,KAAa,EAAiB,EAAE,CACtE,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE;IACnB,IAAI,CAAC,CAAC,MAAM,YAAY,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,8DAA8D,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7G,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC5D,CAAC,CAAC,CAAC;AAOP,MAAM,wBAAwB,GAAG,CAAC,MAAkB,EAA4B,EAAE;IAC9E,KAAK,IAAI,OAAO,GAAsB,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;QACnF,IAAI,OAAO,YAAY,GAAG,CAAC,cAAc,EAAE,CAAC;YACxC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;QACxF,CAAC;QACD,IAAI,OAAO,YAAY,GAAG,CAAC,UAAU,EAAE,CAAC;YACpC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;QACxF,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,UAAiC,EAAE,KAAa,EAAQ,EAAE;IAChF,IAAI,CAAC,UAAU,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO;IACvC,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,CAAC;AACvD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAAkB,EAAE,KAAkB,EAAiB,EAAE,CAC5E,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE;IACnB,MAAM,WAAW,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACrD,IAAI,CAAC,WAAW,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACX,gGAAgG,CACnG,CAAC;IACN,CAAC;IACD,gBAAgB,CAAC,WAAW,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,gBAAgB,CAAC,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACzD,CAAC,CAAC,CAAC","sourcesContent":["import * as Gtk from \"@gtkx/gi/gtk\";\nimport { wrapEvent } from \"./event-wrapper.js\";\n\nexport type ScrollDelta = {\n x?: number;\n y?: number;\n};\n\nexport const slide = (widget: Gtk.Widget, value: number): Promise<void> =>\n wrapEvent(widget, () => {\n if (!(widget instanceof Gtk.Range)) {\n throw new Error(`userEvent.slide requires a Gtk.Range (e.g. Gtk.Scale), got ${widget.constructor.name}`);\n }\n widget.emit(\"change-value\", Gtk.ScrollType.JUMP, value);\n });\n\ntype ScrollAdjustments = {\n horizontal: Gtk.Adjustment | null;\n vertical: Gtk.Adjustment | null;\n};\n\nconst resolveScrollAdjustments = (widget: Gtk.Widget): ScrollAdjustments | null => {\n for (let current: Gtk.Widget | null = widget; current; current = current.getParent()) {\n if (current instanceof Gtk.ScrolledWindow) {\n return { horizontal: current.getHadjustment(), vertical: current.getVadjustment() };\n }\n if (current instanceof Gtk.Scrollable) {\n return { horizontal: current.getHadjustment(), vertical: current.getVadjustment() };\n }\n }\n return null;\n};\n\nconst applyScrollDelta = (adjustment: Gtk.Adjustment | null, delta: number): void => {\n if (!adjustment || delta === 0) return;\n adjustment.setValue(adjustment.getValue() + delta);\n};\n\nexport const scroll = (widget: Gtk.Widget, delta: ScrollDelta): Promise<void> =>\n wrapEvent(widget, () => {\n const adjustments = resolveScrollAdjustments(widget);\n if (!adjustments) {\n throw new Error(\n \"userEvent.scroll: no Gtk.ScrolledWindow or Gtk.Scrollable found on the widget or its ancestors\",\n );\n }\n applyScrollDelta(adjustments.horizontal, delta.x ?? 0);\n applyScrollDelta(adjustments.vertical, delta.y ?? 0);\n });\n"]}
@@ -0,0 +1,7 @@
1
+ import * as Gtk from "@gtkx/gi/gtk";
2
+ export declare const emitPress: (widget: Gtk.Widget, controllers: Gtk.GestureClick[], nPress: number) => void;
3
+ export declare const emitRelease: (widget: Gtk.Widget, controllers: Gtk.GestureClick[], nPress: number) => void;
4
+ export declare const click: (widget: Gtk.Widget) => Promise<void>;
5
+ export declare const dblClick: (widget: Gtk.Widget) => Promise<void>;
6
+ export declare const tripleClick: (widget: Gtk.Widget) => Promise<void>;
7
+ //# sourceMappingURL=click.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../src/user-event/click.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AAWpC,eAAO,MAAM,SAAS,WAAY,GAAG,CAAC,MAAM,eAAe,GAAG,CAAC,YAAY,EAAE,UAAU,MAAM,KAAG,IAK/F,CAAC;AAEF,eAAO,MAAM,WAAW,WAAY,GAAG,CAAC,MAAM,eAAe,GAAG,CAAC,YAAY,EAAE,UAAU,MAAM,KAAG,IAKjG,CAAC;AAuBF,eAAO,MAAM,KAAK,WAAkB,GAAG,CAAC,MAAM,KAAG,OAAO,CAAC,IAAI,CAoB5D,CAAC;AAEF,eAAO,MAAM,QAAQ,WAAY,GAAG,CAAC,MAAM,KAAG,OAAO,CAAC,IAAI,CAAyC,CAAC;AACpG,eAAO,MAAM,WAAW,WAAY,GAAG,CAAC,MAAM,KAAG,OAAO,CAAC,IAAI,CAAyC,CAAC"}
@@ -0,0 +1,65 @@
1
+ import * as Gtk from "@gtkx/gi/gtk";
2
+ import { getOrCreateControllers, queryController } from "./controller.js";
3
+ import { wrapEvent } from "./event-wrapper.js";
4
+ const pressPointOf = (widget) => {
5
+ const width = widget.getWidth();
6
+ const height = widget.getHeight();
7
+ if (width > 0 && height > 0)
8
+ return { x: width / 2, y: height / 2 };
9
+ return { x: 0, y: 0 };
10
+ };
11
+ export const emitPress = (widget, controllers, nPress) => {
12
+ const { x, y } = pressPointOf(widget);
13
+ for (const controller of controllers) {
14
+ controller.emit("pressed", nPress, x, y);
15
+ }
16
+ };
17
+ export const emitRelease = (widget, controllers, nPress) => {
18
+ const { x, y } = pressPointOf(widget);
19
+ for (const controller of controllers) {
20
+ controller.emit("released", nPress, x, y);
21
+ }
22
+ };
23
+ const emitClickSequence = (widget, target, nPress) => wrapEvent(widget, () => {
24
+ const controllers = getOrCreateControllers(target, Gtk.GestureClick);
25
+ for (let i = 1; i <= nPress; i++) {
26
+ emitPress(target, controllers, i);
27
+ emitRelease(target, controllers, i);
28
+ }
29
+ });
30
+ const findClickableAncestor = (widget) => {
31
+ let current = widget.getParent();
32
+ while (current) {
33
+ if (current instanceof Gtk.Button || queryController(current, Gtk.GestureClick) !== null) {
34
+ return current;
35
+ }
36
+ current = current.getParent();
37
+ }
38
+ return null;
39
+ };
40
+ export const click = async (widget) => {
41
+ if (widget instanceof Gtk.Button) {
42
+ await emitClickSequence(widget, widget, 1);
43
+ return;
44
+ }
45
+ if (widget instanceof Gtk.Switch) {
46
+ await wrapEvent(widget, () => {
47
+ widget.setActive(!widget.getActive());
48
+ });
49
+ return;
50
+ }
51
+ if (widget.getAccessibleRole() !== Gtk.AccessibleRole.LABEL) {
52
+ let activated = false;
53
+ await wrapEvent(widget, () => {
54
+ activated = widget.activate();
55
+ });
56
+ if (activated)
57
+ return;
58
+ }
59
+ const target = findClickableAncestor(widget);
60
+ if (target)
61
+ await emitClickSequence(widget, target, 1);
62
+ };
63
+ export const dblClick = (widget) => emitClickSequence(widget, widget, 2);
64
+ export const tripleClick = (widget) => emitClickSequence(widget, widget, 3);
65
+ //# sourceMappingURL=click.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"click.js","sourceRoot":"","sources":["../../src/user-event/click.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Gtk from \"@gtkx/gi/gtk\";\nimport { getOrCreateControllers, queryController } from \"./controller.js\";\nimport { wrapEvent } from \"./event-wrapper.js\";\n\nconst pressPointOf = (widget: Gtk.Widget): { x: number; y: number } => {\n const width = widget.getWidth();\n const height = widget.getHeight();\n if (width > 0 && height > 0) return { x: width / 2, y: height / 2 };\n return { x: 0, y: 0 };\n};\n\nexport const emitPress = (widget: Gtk.Widget, controllers: Gtk.GestureClick[], nPress: number): void => {\n const { x, y } = pressPointOf(widget);\n for (const controller of controllers) {\n controller.emit(\"pressed\", nPress, x, y);\n }\n};\n\nexport const emitRelease = (widget: Gtk.Widget, controllers: Gtk.GestureClick[], nPress: number): void => {\n const { x, y } = pressPointOf(widget);\n for (const controller of controllers) {\n controller.emit(\"released\", nPress, x, y);\n }\n};\n\nconst emitClickSequence = (widget: Gtk.Widget, target: Gtk.Widget, nPress: number): Promise<void> =>\n wrapEvent(widget, () => {\n const controllers = getOrCreateControllers(target, Gtk.GestureClick);\n\n for (let i = 1; i <= nPress; i++) {\n emitPress(target, controllers, i);\n emitRelease(target, controllers, i);\n }\n });\n\nconst findClickableAncestor = (widget: Gtk.Widget): Gtk.Widget | null => {\n let current = widget.getParent();\n while (current) {\n if (current instanceof Gtk.Button || queryController(current, Gtk.GestureClick) !== null) {\n return current;\n }\n current = current.getParent();\n }\n return null;\n};\n\nexport const click = async (widget: Gtk.Widget): Promise<void> => {\n if (widget instanceof Gtk.Button) {\n await emitClickSequence(widget, widget, 1);\n return;\n }\n if (widget instanceof Gtk.Switch) {\n await wrapEvent(widget, () => {\n widget.setActive(!widget.getActive());\n });\n return;\n }\n if (widget.getAccessibleRole() !== Gtk.AccessibleRole.LABEL) {\n let activated = false;\n await wrapEvent(widget, () => {\n activated = widget.activate();\n });\n if (activated) return;\n }\n const target = findClickableAncestor(widget);\n if (target) await emitClickSequence(widget, target, 1);\n};\n\nexport const dblClick = (widget: Gtk.Widget): Promise<void> => emitClickSequence(widget, widget, 2);\nexport const tripleClick = (widget: Gtk.Widget): Promise<void> => emitClickSequence(widget, widget, 3);\n"]}
@@ -0,0 +1,7 @@
1
+ import type * as Gtk from "@gtkx/gi/gtk";
2
+ export type ControllerConstructor<T extends Gtk.EventController> = new () => T;
3
+ export declare const queryAllControllers: <T extends Gtk.EventController>(widget: Gtk.Widget, controllerType: ControllerConstructor<T>) => T[];
4
+ export declare const queryController: <T extends Gtk.EventController>(widget: Gtk.Widget, controllerType: ControllerConstructor<T>) => T | null;
5
+ export declare const getAllControllers: <T extends Gtk.EventController>(widget: Gtk.Widget, controllerType: ControllerConstructor<T>) => T[];
6
+ export declare const getOrCreateControllers: <T extends Gtk.EventController>(widget: Gtk.Widget, controllerType: ControllerConstructor<T>) => T[];
7
+ //# sourceMappingURL=controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/user-event/controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,cAAc,CAAC;AAEzC,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,GAAG,CAAC,eAAe,IAAI,UAAU,CAAC,CAAC;AAE/E,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,GAAG,CAAC,eAAe,UACrD,GAAG,CAAC,MAAM,kBACF,qBAAqB,CAAC,CAAC,CAAC,KACzC,CAAC,EASH,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,GAAG,CAAC,eAAe,UACjD,GAAG,CAAC,MAAM,kBACF,qBAAqB,CAAC,CAAC,CAAC,KACzC,CAAC,GAAG,IAA8D,CAAC;AAEtE,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,GAAG,CAAC,eAAe,UACnD,GAAG,CAAC,MAAM,kBACF,qBAAqB,CAAC,CAAC,CAAC,KACzC,CAAC,EAMH,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,CAAC,SAAS,GAAG,CAAC,eAAe,UACxD,GAAG,CAAC,MAAM,kBACF,qBAAqB,CAAC,CAAC,CAAC,KACzC,CAAC,EAMH,CAAC"}
@@ -0,0 +1,28 @@
1
+ export const queryAllControllers = (widget, controllerType) => {
2
+ const controllers = widget.observeControllers();
3
+ const nItems = controllers.getNItems();
4
+ const matches = [];
5
+ for (let i = 0; i < nItems; i++) {
6
+ const controller = controllers.getItem(i);
7
+ if (controller instanceof controllerType)
8
+ matches.push(controller);
9
+ }
10
+ return matches;
11
+ };
12
+ export const queryController = (widget, controllerType) => queryAllControllers(widget, controllerType)[0] ?? null;
13
+ export const getAllControllers = (widget, controllerType) => {
14
+ const controllers = queryAllControllers(widget, controllerType);
15
+ if (controllers.length === 0) {
16
+ throw new Error(`No ${controllerType.name} controller is attached to the widget`);
17
+ }
18
+ return controllers;
19
+ };
20
+ export const getOrCreateControllers = (widget, controllerType) => {
21
+ const existing = queryAllControllers(widget, controllerType);
22
+ if (existing.length > 0)
23
+ return existing;
24
+ const controller = new controllerType();
25
+ widget.addController(controller);
26
+ return [controller];
27
+ };
28
+ //# sourceMappingURL=controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller.js","sourceRoot":"","sources":["../../src/user-event/controller.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAC/B,MAAkB,EAClB,cAAwC,EACrC,EAAE;IACL,MAAM,WAAW,GAAG,MAAM,CAAC,kBAAkB,EAAE,CAAC;IAChD,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,EAAE,CAAC;IACvC,MAAM,OAAO,GAAQ,EAAE,CAAC;IACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1C,IAAI,UAAU,YAAY,cAAc;YAAE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAC3B,MAAkB,EAClB,cAAwC,EAChC,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAEtE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC7B,MAAkB,EAClB,cAAwC,EACrC,EAAE;IACL,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAChE,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,MAAM,cAAc,CAAC,IAAI,uCAAuC,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,WAAW,CAAC;AACvB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAClC,MAAkB,EAClB,cAAwC,EACrC,EAAE;IACL,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC7D,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IACzC,MAAM,UAAU,GAAG,IAAI,cAAc,EAAE,CAAC;IACxC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACjC,OAAO,CAAC,UAAU,CAAC,CAAC;AACxB,CAAC,CAAC","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\n\nexport type ControllerConstructor<T extends Gtk.EventController> = new () => T;\n\nexport const queryAllControllers = <T extends Gtk.EventController>(\n widget: Gtk.Widget,\n controllerType: ControllerConstructor<T>,\n): T[] => {\n const controllers = widget.observeControllers();\n const nItems = controllers.getNItems();\n const matches: T[] = [];\n for (let i = 0; i < nItems; i++) {\n const controller = controllers.getItem(i);\n if (controller instanceof controllerType) matches.push(controller);\n }\n return matches;\n};\n\nexport const queryController = <T extends Gtk.EventController>(\n widget: Gtk.Widget,\n controllerType: ControllerConstructor<T>,\n): T | null => queryAllControllers(widget, controllerType)[0] ?? null;\n\nexport const getAllControllers = <T extends Gtk.EventController>(\n widget: Gtk.Widget,\n controllerType: ControllerConstructor<T>,\n): T[] => {\n const controllers = queryAllControllers(widget, controllerType);\n if (controllers.length === 0) {\n throw new Error(`No ${controllerType.name} controller is attached to the widget`);\n }\n return controllers;\n};\n\nexport const getOrCreateControllers = <T extends Gtk.EventController>(\n widget: Gtk.Widget,\n controllerType: ControllerConstructor<T>,\n): T[] => {\n const existing = queryAllControllers(widget, controllerType);\n if (existing.length > 0) return existing;\n const controller = new controllerType();\n widget.addController(controller);\n return [controller];\n};\n"]}
@@ -0,0 +1,7 @@
1
+ import type * as Gtk from "@gtkx/gi/gtk";
2
+ import { type ControllerConstructor } from "./controller.js";
3
+ type ControllerEmit<T extends Gtk.EventController> = (controller: T) => void | PromiseLike<void>;
4
+ export declare const dispatchOnOrCreateControllers: <T extends Gtk.EventController>(widget: Gtk.Widget, controllerType: ControllerConstructor<T>, emit: ControllerEmit<T>) => Promise<void>;
5
+ export declare const dispatchOnControllers: <T extends Gtk.EventController>(widget: Gtk.Widget, controllerType: ControllerConstructor<T>, emit: ControllerEmit<T>) => Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=dispatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/user-event/dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,KAAK,qBAAqB,EAA6C,MAAM,iBAAiB,CAAC;AAGxG,KAAK,cAAc,CAAC,CAAC,SAAS,GAAG,CAAC,eAAe,IAAI,CAAC,UAAU,EAAE,CAAC,KAAK,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;AAQjG,eAAO,MAAM,6BAA6B,GAAI,CAAC,SAAS,GAAG,CAAC,eAAe,UAC/D,GAAG,CAAC,MAAM,kBACF,qBAAqB,CAAC,CAAC,CAAC,QAClC,cAAc,CAAC,CAAC,CAAC,KACxB,OAAO,CAAC,IAAI,CAA6F,CAAC;AAE7G,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,GAAG,CAAC,eAAe,UACvD,GAAG,CAAC,MAAM,kBACF,qBAAqB,CAAC,CAAC,CAAC,QAClC,cAAc,CAAC,CAAC,CAAC,KACxB,OAAO,CAAC,IAAI,CAAwF,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { getAllControllers, getOrCreateControllers } from "./controller.js";
2
+ import { wrapEvent } from "./event-wrapper.js";
3
+ const emitOnAll = async (controllers, emit) => {
4
+ for (const controller of controllers) {
5
+ await emit(controller);
6
+ }
7
+ };
8
+ export const dispatchOnOrCreateControllers = (widget, controllerType, emit) => wrapEvent(widget, () => emitOnAll(getOrCreateControllers(widget, controllerType), emit));
9
+ export const dispatchOnControllers = (widget, controllerType, emit) => wrapEvent(widget, () => emitOnAll(getAllControllers(widget, controllerType), emit));
10
+ //# sourceMappingURL=dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../src/user-event/dispatch.ts"],"names":[],"mappings":"AACA,OAAO,EAA8B,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACxG,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAI/C,MAAM,SAAS,GAAG,KAAK,EAAiC,WAAgB,EAAE,IAAuB,EAAiB,EAAE;IAChH,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACnC,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3B,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,6BAA6B,GAAG,CACzC,MAAkB,EAClB,cAAwC,EACxC,IAAuB,EACV,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,sBAAsB,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAE7G,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACjC,MAAkB,EAClB,cAAwC,EACxC,IAAuB,EACV,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,iBAAiB,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\nimport { type ControllerConstructor, getAllControllers, getOrCreateControllers } from \"./controller.js\";\nimport { wrapEvent } from \"./event-wrapper.js\";\n\ntype ControllerEmit<T extends Gtk.EventController> = (controller: T) => void | PromiseLike<void>;\n\nconst emitOnAll = async <T extends Gtk.EventController>(controllers: T[], emit: ControllerEmit<T>): Promise<void> => {\n for (const controller of controllers) {\n await emit(controller);\n }\n};\n\nexport const dispatchOnOrCreateControllers = <T extends Gtk.EventController>(\n widget: Gtk.Widget,\n controllerType: ControllerConstructor<T>,\n emit: ControllerEmit<T>,\n): Promise<void> => wrapEvent(widget, () => emitOnAll(getOrCreateControllers(widget, controllerType), emit));\n\nexport const dispatchOnControllers = <T extends Gtk.EventController>(\n widget: Gtk.Widget,\n controllerType: ControllerConstructor<T>,\n emit: ControllerEmit<T>,\n): Promise<void> => wrapEvent(widget, () => emitOnAll(getAllControllers(widget, controllerType), emit));\n"]}
@@ -0,0 +1,3 @@
1
+ import * as Gtk from "@gtkx/gi/gtk";
2
+ export declare const wrapEvent: (widget: Gtk.Widget, body: () => void | PromiseLike<void>) => Promise<void>;
3
+ //# sourceMappingURL=event-wrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-wrapper.d.ts","sourceRoot":"","sources":["../../src/user-event/event-wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AA8CpC,eAAO,MAAM,SAAS,WAAY,GAAG,CAAC,MAAM,QAAQ,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,KAAG,OAAO,CAAC,IAAI,CAOxF,CAAC"}