@gtkx/testing 0.1.45 → 0.1.46

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.
@@ -1,3 +1,17 @@
1
1
  import type * as Gtk from "@gtkx/ffi/gtk";
2
2
  import type { Arg } from "@gtkx/native";
3
+ /**
4
+ * Low-level utility to emit GTK signals on widgets. For common interactions
5
+ * like clicking or typing, use `userEvent` instead.
6
+ *
7
+ * @param element - The GTK widget to emit the signal on
8
+ * @param signalName - The name of the signal to emit
9
+ * @param args - Additional arguments to pass to the signal handlers
10
+ *
11
+ * @example
12
+ * fireEvent(button, "clicked")
13
+ *
14
+ * @example
15
+ * fireEvent(widget, "custom-signal", { type: { type: "int", size: 32 }, value: 42 })
16
+ */
3
17
  export declare const fireEvent: (element: Gtk.Widget, signalName: string, ...args: Arg[]) => void;
@@ -1,4 +1,18 @@
1
1
  import { call } from "@gtkx/native";
2
+ /**
3
+ * Low-level utility to emit GTK signals on widgets. For common interactions
4
+ * like clicking or typing, use `userEvent` instead.
5
+ *
6
+ * @param element - The GTK widget to emit the signal on
7
+ * @param signalName - The name of the signal to emit
8
+ * @param args - Additional arguments to pass to the signal handlers
9
+ *
10
+ * @example
11
+ * fireEvent(button, "clicked")
12
+ *
13
+ * @example
14
+ * fireEvent(widget, "custom-signal", { type: { type: "int", size: 32 }, value: 42 })
15
+ */
2
16
  export const fireEvent = (element, signalName, ...args) => {
3
17
  call("libgobject-2.0.so.0", "g_signal_emit_by_name", [{ type: { type: "gobject" }, value: element.ptr }, { type: { type: "string" }, value: signalName }, ...args], { type: "undefined" });
4
18
  };
package/dist/queries.d.ts CHANGED
@@ -2,12 +2,68 @@ import type * as Gtk from "@gtkx/ffi/gtk";
2
2
  import { AccessibleRole } from "@gtkx/ffi/gtk";
3
3
  import type { ByRoleOptions, TextMatchOptions } from "./types.js";
4
4
  type Container = Gtk.Application | Gtk.Widget;
5
+ /**
6
+ * Waits for and finds a single widget matching the specified accessible role.
7
+ * @param container - The container to search within
8
+ * @param role - The accessible role to match
9
+ * @param options - Additional filtering options (name, checked, expanded)
10
+ * @returns Promise resolving to the matching widget
11
+ */
5
12
  export declare const findByRole: (container: Container, role: AccessibleRole, options?: ByRoleOptions) => Promise<Gtk.Widget>;
13
+ /**
14
+ * Waits for and finds all widgets matching the specified accessible role.
15
+ * @param container - The container to search within
16
+ * @param role - The accessible role to match
17
+ * @param options - Additional filtering options (name, checked, expanded)
18
+ * @returns Promise resolving to array of matching widgets
19
+ */
6
20
  export declare const findAllByRole: (container: Container, role: AccessibleRole, options?: ByRoleOptions) => Promise<Gtk.Widget[]>;
21
+ /**
22
+ * Waits for and finds a single widget matching the specified label text.
23
+ * @param container - The container to search within
24
+ * @param text - The text or pattern to match
25
+ * @param options - Text matching options (exact, normalizer)
26
+ * @returns Promise resolving to the matching widget
27
+ */
7
28
  export declare const findByLabelText: (container: Container, text: string | RegExp, options?: TextMatchOptions) => Promise<Gtk.Widget>;
29
+ /**
30
+ * Waits for and finds all widgets matching the specified label text.
31
+ * @param container - The container to search within
32
+ * @param text - The text or pattern to match
33
+ * @param options - Text matching options (exact, normalizer)
34
+ * @returns Promise resolving to array of matching widgets
35
+ */
8
36
  export declare const findAllByLabelText: (container: Container, text: string | RegExp, options?: TextMatchOptions) => Promise<Gtk.Widget[]>;
37
+ /**
38
+ * Waits for and finds a single widget matching the specified text content.
39
+ * @param container - The container to search within
40
+ * @param text - The text or pattern to match
41
+ * @param options - Text matching options (exact, normalizer)
42
+ * @returns Promise resolving to the matching widget
43
+ */
9
44
  export declare const findByText: (container: Container, text: string | RegExp, options?: TextMatchOptions) => Promise<Gtk.Widget>;
45
+ /**
46
+ * Waits for and finds all widgets matching the specified text content.
47
+ * @param container - The container to search within
48
+ * @param text - The text or pattern to match
49
+ * @param options - Text matching options (exact, normalizer)
50
+ * @returns Promise resolving to array of matching widgets
51
+ */
10
52
  export declare const findAllByText: (container: Container, text: string | RegExp, options?: TextMatchOptions) => Promise<Gtk.Widget[]>;
53
+ /**
54
+ * Waits for and finds a single widget matching the specified test ID.
55
+ * @param container - The container to search within
56
+ * @param testId - The test ID or pattern to match
57
+ * @param options - Text matching options (exact, normalizer)
58
+ * @returns Promise resolving to the matching widget
59
+ */
11
60
  export declare const findByTestId: (container: Container, testId: string | RegExp, options?: TextMatchOptions) => Promise<Gtk.Widget>;
61
+ /**
62
+ * Waits for and finds all widgets matching the specified test ID.
63
+ * @param container - The container to search within
64
+ * @param testId - The test ID or pattern to match
65
+ * @param options - Text matching options (exact, normalizer)
66
+ * @returns Promise resolving to array of matching widgets
67
+ */
12
68
  export declare const findAllByTestId: (container: Container, testId: string | RegExp, options?: TextMatchOptions) => Promise<Gtk.Widget[]>;
13
69
  export {};
package/dist/queries.js CHANGED
@@ -196,11 +196,67 @@ const getByTestId = (container, testId, options) => {
196
196
  }
197
197
  return matches[0];
198
198
  };
199
+ /**
200
+ * Waits for and finds a single widget matching the specified accessible role.
201
+ * @param container - The container to search within
202
+ * @param role - The accessible role to match
203
+ * @param options - Additional filtering options (name, checked, expanded)
204
+ * @returns Promise resolving to the matching widget
205
+ */
199
206
  export const findByRole = async (container, role, options) => waitFor(() => getByRole(container, role, options));
207
+ /**
208
+ * Waits for and finds all widgets matching the specified accessible role.
209
+ * @param container - The container to search within
210
+ * @param role - The accessible role to match
211
+ * @param options - Additional filtering options (name, checked, expanded)
212
+ * @returns Promise resolving to array of matching widgets
213
+ */
200
214
  export const findAllByRole = async (container, role, options) => waitFor(() => getAllByRole(container, role, options));
215
+ /**
216
+ * Waits for and finds a single widget matching the specified label text.
217
+ * @param container - The container to search within
218
+ * @param text - The text or pattern to match
219
+ * @param options - Text matching options (exact, normalizer)
220
+ * @returns Promise resolving to the matching widget
221
+ */
201
222
  export const findByLabelText = async (container, text, options) => waitFor(() => getByLabelText(container, text, options));
223
+ /**
224
+ * Waits for and finds all widgets matching the specified label text.
225
+ * @param container - The container to search within
226
+ * @param text - The text or pattern to match
227
+ * @param options - Text matching options (exact, normalizer)
228
+ * @returns Promise resolving to array of matching widgets
229
+ */
202
230
  export const findAllByLabelText = async (container, text, options) => waitFor(() => getAllByLabelText(container, text, options));
231
+ /**
232
+ * Waits for and finds a single widget matching the specified text content.
233
+ * @param container - The container to search within
234
+ * @param text - The text or pattern to match
235
+ * @param options - Text matching options (exact, normalizer)
236
+ * @returns Promise resolving to the matching widget
237
+ */
203
238
  export const findByText = async (container, text, options) => waitFor(() => getByText(container, text, options));
239
+ /**
240
+ * Waits for and finds all widgets matching the specified text content.
241
+ * @param container - The container to search within
242
+ * @param text - The text or pattern to match
243
+ * @param options - Text matching options (exact, normalizer)
244
+ * @returns Promise resolving to array of matching widgets
245
+ */
204
246
  export const findAllByText = async (container, text, options) => waitFor(() => getAllByText(container, text, options));
247
+ /**
248
+ * Waits for and finds a single widget matching the specified test ID.
249
+ * @param container - The container to search within
250
+ * @param testId - The test ID or pattern to match
251
+ * @param options - Text matching options (exact, normalizer)
252
+ * @returns Promise resolving to the matching widget
253
+ */
205
254
  export const findByTestId = async (container, testId, options) => waitFor(() => getByTestId(container, testId, options));
255
+ /**
256
+ * Waits for and finds all widgets matching the specified test ID.
257
+ * @param container - The container to search within
258
+ * @param testId - The test ID or pattern to match
259
+ * @param options - Text matching options (exact, normalizer)
260
+ * @returns Promise resolving to array of matching widgets
261
+ */
206
262
  export const findAllByTestId = async (container, testId, options) => waitFor(() => getAllByTestId(container, testId, options));
package/dist/render.d.ts CHANGED
@@ -1,5 +1,19 @@
1
1
  import type { ReactNode } from "react";
2
2
  import type { RenderOptions, RenderResult } from "./types.js";
3
+ /**
4
+ * Renders a React element into a GTK application for testing.
5
+ * @param element - The React element to render
6
+ * @param options - Render options including wrapper component
7
+ * @returns Object containing query methods, container, and utility functions
8
+ */
3
9
  export declare const render: (element: ReactNode, options?: RenderOptions) => Promise<RenderResult>;
10
+ /**
11
+ * Cleans up the rendered component by unmounting it and destroying windows.
12
+ * Should be called after each test to reset state.
13
+ */
4
14
  export declare const cleanup: () => Promise<void>;
15
+ /**
16
+ * Tears down the testing environment by cleaning up and stopping GTK.
17
+ * Can be used as global teardown in your test runner configuration.
18
+ */
5
19
  export declare const teardown: () => Promise<void>;
package/dist/render.js CHANGED
@@ -30,12 +30,20 @@ const ensureInitialized = () => {
30
30
  const app = start(APP_ID);
31
31
  if (!container) {
32
32
  const instance = reconciler.getInstance();
33
- container = instance.createContainer(ROOT_NODE_CONTAINER, 0, null, false, null, "", (error) => console.error("Test reconciler error:", error), () => { }, () => { }, () => { }, null);
33
+ container = instance.createContainer(
34
+ // biome-ignore lint/suspicious/noExplicitAny: testing only
35
+ ROOT_NODE_CONTAINER, 0, null, false, null, "", (error) => console.error("Test reconciler error:", error), () => { }, () => { }, () => { }, null);
34
36
  }
35
37
  return { app, container };
36
38
  };
37
39
  const DefaultWrapper = ({ children }) => (_jsx(ApplicationWindow, { children: children }));
38
40
  const wrapElement = (element, Wrapper = DefaultWrapper) => (_jsx(Wrapper, { children: element }));
41
+ /**
42
+ * Renders a React element into a GTK application for testing.
43
+ * @param element - The React element to render
44
+ * @param options - Render options including wrapper component
45
+ * @returns Object containing query methods, container, and utility functions
46
+ */
39
47
  export const render = async (element, options) => {
40
48
  const { app: application, container: fiberRoot } = ensureInitialized();
41
49
  const instance = reconciler.getInstance();
@@ -65,6 +73,10 @@ export const render = async (element, options) => {
65
73
  },
66
74
  };
67
75
  };
76
+ /**
77
+ * Cleans up the rendered component by unmounting it and destroying windows.
78
+ * Should be called after each test to reset state.
79
+ */
68
80
  export const cleanup = async () => {
69
81
  if (container) {
70
82
  const app = getCurrentApp();
@@ -77,6 +89,10 @@ export const cleanup = async () => {
77
89
  container = null;
78
90
  setScreenRoot(null);
79
91
  };
92
+ /**
93
+ * Tears down the testing environment by cleaning up and stopping GTK.
94
+ * Can be used as global teardown in your test runner configuration.
95
+ */
80
96
  export const teardown = async () => {
81
97
  await cleanup();
82
98
  stop();
package/dist/screen.d.ts CHANGED
@@ -1,7 +1,16 @@
1
1
  import type * as Gtk from "@gtkx/ffi/gtk";
2
2
  import type { AccessibleRole } from "@gtkx/ffi/gtk";
3
3
  import type { ByRoleOptions, TextMatchOptions } from "./types.js";
4
+ /**
5
+ * Sets the root application for screen queries. Called internally by render().
6
+ * @param root - The GTK application to use as query root, or null to clear
7
+ */
4
8
  export declare const setScreenRoot: (root: Gtk.Application | null) => void;
9
+ /**
10
+ * Global screen object providing query methods bound to the current render root.
11
+ * Similar to Testing Library's screen, it provides all query variants without
12
+ * needing to destructure from render().
13
+ */
5
14
  export declare const screen: {
6
15
  findByRole: (role: AccessibleRole, options?: ByRoleOptions) => Promise<Gtk.Widget>;
7
16
  findByLabelText: (text: string | RegExp, options?: TextMatchOptions) => Promise<Gtk.Widget>;
package/dist/screen.js CHANGED
@@ -1,5 +1,9 @@
1
1
  import * as queries from "./queries.js";
2
2
  let currentRoot = null;
3
+ /**
4
+ * Sets the root application for screen queries. Called internally by render().
5
+ * @param root - The GTK application to use as query root, or null to clear
6
+ */
3
7
  export const setScreenRoot = (root) => {
4
8
  currentRoot = root;
5
9
  };
@@ -9,6 +13,11 @@ const getRoot = () => {
9
13
  }
10
14
  return currentRoot;
11
15
  };
16
+ /**
17
+ * Global screen object providing query methods bound to the current render root.
18
+ * Similar to Testing Library's screen, it provides all query variants without
19
+ * needing to destructure from render().
20
+ */
12
21
  export const screen = {
13
22
  findByRole: (role, options) => queries.findByRole(getRoot(), role, options),
14
23
  findByLabelText: (text, options) => queries.findByLabelText(getRoot(), text, options),
@@ -1,4 +1,10 @@
1
1
  import type * as Gtk from "@gtkx/ffi/gtk";
2
2
  type Container = Gtk.Application | Gtk.Widget;
3
+ /**
4
+ * Traverses the widget tree and returns all widgets matching the predicate.
5
+ * @param container - The application or widget to search within
6
+ * @param predicate - Function that returns true for matching widgets
7
+ * @returns Array of widgets that match the predicate
8
+ */
3
9
  export declare const findAll: (container: Container, predicate: (node: Gtk.Widget) => boolean) => Gtk.Widget[];
4
10
  export {};
package/dist/traversal.js CHANGED
@@ -21,6 +21,12 @@ const traverse = function* (container) {
21
21
  yield* traverseWidgetTree(container);
22
22
  }
23
23
  };
24
+ /**
25
+ * Traverses the widget tree and returns all widgets matching the predicate.
26
+ * @param container - The application or widget to search within
27
+ * @param predicate - Function that returns true for matching widgets
28
+ * @returns Array of widgets that match the predicate
29
+ */
24
30
  export const findAll = (container, predicate) => {
25
31
  const results = [];
26
32
  for (const node of traverse(container)) {
@@ -1,14 +1,31 @@
1
1
  import type * as Gtk from "@gtkx/ffi/gtk";
2
+ /**
3
+ * Options for configuring user event behavior.
4
+ */
2
5
  export interface UserEventOptions {
6
+ /** Delay between events in milliseconds */
3
7
  delay?: number;
4
8
  }
9
+ /**
10
+ * Instance returned by userEvent.setup() with bound options.
11
+ */
5
12
  export interface UserEventInstance {
13
+ /** Simulates a click on the element */
6
14
  click: (element: Gtk.Widget) => Promise<void>;
15
+ /** Simulates a double-click on the element */
7
16
  dblClick: (element: Gtk.Widget) => Promise<void>;
17
+ /** Activates the element (e.g., pressing Enter in an Entry) */
8
18
  activate: (element: Gtk.Widget) => Promise<void>;
19
+ /** Types text into an input element */
9
20
  type: (element: Gtk.Widget, text: string) => Promise<void>;
21
+ /** Clears the text content of an input element */
10
22
  clear: (element: Gtk.Widget) => Promise<void>;
11
23
  }
24
+ /**
25
+ * Simulates user interactions with GTK widgets. Provides methods that mimic
26
+ * real user behavior like clicking, typing, and clearing input fields.
27
+ * Use userEvent.setup() to create an instance with custom options.
28
+ */
12
29
  export declare const userEvent: {
13
30
  setup: (options?: UserEventOptions) => UserEventInstance;
14
31
  click: (element: Gtk.Widget) => Promise<void>;
@@ -34,6 +34,11 @@ const createUserEventInstance = (_options) => {
34
34
  },
35
35
  };
36
36
  };
37
+ /**
38
+ * Simulates user interactions with GTK widgets. Provides methods that mimic
39
+ * real user behavior like clicking, typing, and clearing input fields.
40
+ * Use userEvent.setup() to create an instance with custom options.
41
+ */
37
42
  export const userEvent = {
38
43
  setup: (options) => createUserEventInstance(options),
39
44
  click: async (element) => {
@@ -1,6 +1,20 @@
1
1
  import type * as Gtk from "@gtkx/ffi/gtk";
2
2
  import type { WaitForOptions } from "./types.js";
3
+ /**
4
+ * Waits for a callback to succeed without throwing an error.
5
+ * @param callback - Function to execute repeatedly until it succeeds
6
+ * @param options - Wait options (timeout, interval, onTimeout)
7
+ * @returns Promise resolving to the callback's return value
8
+ * @throws If the callback keeps failing after the timeout period
9
+ */
3
10
  export declare const waitFor: <T>(callback: () => T, options?: WaitForOptions) => Promise<T>;
4
11
  type ElementOrCallback = Gtk.Widget | (() => Gtk.Widget | null);
12
+ /**
13
+ * Waits for an element to be removed from the widget tree.
14
+ * @param elementOrCallback - The element to watch or a callback returning the element
15
+ * @param options - Wait options (timeout, interval, onTimeout)
16
+ * @returns Promise resolving when the element is removed
17
+ * @throws If the element is already removed when called, or if timeout is reached
18
+ */
5
19
  export declare const waitForElementToBeRemoved: (elementOrCallback: ElementOrCallback, options?: WaitForOptions) => Promise<void>;
6
20
  export {};
package/dist/wait-for.js CHANGED
@@ -1,5 +1,12 @@
1
1
  const DEFAULT_TIMEOUT = 1000;
2
2
  const DEFAULT_INTERVAL = 50;
3
+ /**
4
+ * Waits for a callback to succeed without throwing an error.
5
+ * @param callback - Function to execute repeatedly until it succeeds
6
+ * @param options - Wait options (timeout, interval, onTimeout)
7
+ * @returns Promise resolving to the callback's return value
8
+ * @throws If the callback keeps failing after the timeout period
9
+ */
3
10
  export const waitFor = async (callback, options) => {
4
11
  const { timeout = DEFAULT_TIMEOUT, interval = DEFAULT_INTERVAL, onTimeout } = options ?? {};
5
12
  const startTime = Date.now();
@@ -36,6 +43,13 @@ const isElementRemoved = (element) => {
36
43
  return true;
37
44
  }
38
45
  };
46
+ /**
47
+ * Waits for an element to be removed from the widget tree.
48
+ * @param elementOrCallback - The element to watch or a callback returning the element
49
+ * @param options - Wait options (timeout, interval, onTimeout)
50
+ * @returns Promise resolving when the element is removed
51
+ * @throws If the element is already removed when called, or if timeout is reached
52
+ */
39
53
  export const waitForElementToBeRemoved = async (elementOrCallback, options) => {
40
54
  const { timeout = DEFAULT_TIMEOUT, interval = DEFAULT_INTERVAL, onTimeout } = options ?? {};
41
55
  const initialElement = getElement(elementOrCallback);
package/dist/within.d.ts CHANGED
@@ -1,3 +1,18 @@
1
1
  import type * as Gtk from "@gtkx/ffi/gtk";
2
2
  import type { BoundQueries } from "./types.js";
3
+ /**
4
+ * Scopes queries to a specific container element.
5
+ * Returns an object with all query methods bound to the given container,
6
+ * allowing you to search only within a subtree of the widget hierarchy.
7
+ *
8
+ * @param container - The widget to scope queries to
9
+ * @returns An object containing all query methods bound to the container
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * const dialog = await screen.findByRole(AccessibleRole.DIALOG);
14
+ * const { findByText } = within(dialog);
15
+ * const button = await findByText("Confirm");
16
+ * ```
17
+ */
3
18
  export declare const within: (container: Gtk.Widget) => BoundQueries;
package/dist/within.js CHANGED
@@ -1,4 +1,19 @@
1
1
  import * as queries from "./queries.js";
2
+ /**
3
+ * Scopes queries to a specific container element.
4
+ * Returns an object with all query methods bound to the given container,
5
+ * allowing you to search only within a subtree of the widget hierarchy.
6
+ *
7
+ * @param container - The widget to scope queries to
8
+ * @returns An object containing all query methods bound to the container
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * const dialog = await screen.findByRole(AccessibleRole.DIALOG);
13
+ * const { findByText } = within(dialog);
14
+ * const button = await findByText("Confirm");
15
+ * ```
16
+ */
2
17
  export const within = (container) => ({
3
18
  findByRole: (role, options) => queries.findByRole(container, role, options),
4
19
  findByLabelText: (text, options) => queries.findByLabelText(container, text, options),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtkx/testing",
3
- "version": "0.1.45",
3
+ "version": "0.1.46",
4
4
  "description": "Testing utilities for GTKX applications",
5
5
  "keywords": [
6
6
  "gtk",
@@ -32,9 +32,9 @@
32
32
  "dist"
33
33
  ],
34
34
  "dependencies": {
35
- "@gtkx/native": "0.1.45",
36
- "@gtkx/ffi": "0.1.45",
37
- "@gtkx/react": "0.1.45"
35
+ "@gtkx/ffi": "0.1.46",
36
+ "@gtkx/native": "0.1.46",
37
+ "@gtkx/react": "0.1.46"
38
38
  },
39
39
  "scripts": {
40
40
  "build": "tsc -b && cp ../../README.md .",