@gtkx/testing 0.9.4 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/render.d.ts CHANGED
@@ -1,19 +1,48 @@
1
1
  import type { ReactNode } from "react";
2
2
  import type { RenderOptions, RenderResult } from "./types.js";
3
3
  /**
4
- * Renders a React element into a GTK application for testing.
4
+ * Renders a React element for testing.
5
+ *
6
+ * Creates a GTK application context and renders the element, returning
7
+ * query methods and utilities for interacting with the rendered widgets.
8
+ *
5
9
  * @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
10
+ * @param options - Render options including wrapper configuration
11
+ * @returns A promise resolving to query methods and utilities
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * import { render, screen } from "@gtkx/testing";
16
+ *
17
+ * test("button click", async () => {
18
+ * await render(<MyButton />);
19
+ * const button = await screen.findByRole(Gtk.AccessibleRole.BUTTON);
20
+ * await userEvent.click(button);
21
+ * });
22
+ * ```
23
+ *
24
+ * @see {@link cleanup} for cleaning up after tests
25
+ * @see {@link screen} for global query access
8
26
  */
9
27
  export declare const render: (element: ReactNode, options?: RenderOptions) => Promise<RenderResult>;
10
28
  /**
11
- * Cleans up the rendered component by unmounting it and destroying windows.
12
- * Should be called after each test to reset state.
29
+ * Cleans up the rendered component tree.
30
+ *
31
+ * Unmounts all rendered components and resets the testing environment.
32
+ * Call this in `afterEach` to ensure tests don't affect each other.
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * import { render, cleanup } from "@gtkx/testing";
37
+ *
38
+ * afterEach(async () => {
39
+ * await cleanup();
40
+ * });
41
+ *
42
+ * test("my test", async () => {
43
+ * await render(<MyComponent />);
44
+ * // ...
45
+ * });
46
+ * ```
13
47
  */
14
48
  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
- */
19
- export declare const teardown: () => Promise<void>;
package/dist/render.js CHANGED
@@ -1,13 +1,15 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { getApplication, getNativeObject, start, stop } from "@gtkx/ffi";
2
+ import { discardAllBatches, getNativeObject, start } from "@gtkx/ffi";
3
3
  import * as Gtk from "@gtkx/ffi/gtk";
4
- import { ApplicationWindow, ROOT_NODE_CONTAINER, reconciler } from "@gtkx/react";
4
+ import { ApplicationContext, GtkApplicationWindow, reconciler } from "@gtkx/react";
5
5
  import * as queries from "./queries.js";
6
6
  import { setScreenRoot } from "./screen.js";
7
7
  import { tick } from "./timing.js";
8
8
  import { hasLabel } from "./widget.js";
9
- const APP_ID = "com.gtkx.testing";
9
+ let application = null;
10
10
  let container = null;
11
+ let lastRenderError = null;
12
+ const APP_ID = `com.gtkx.test${process.pid}`;
11
13
  const getWidgetLabel = (widget) => {
12
14
  if (!hasLabel(widget))
13
15
  return null;
@@ -35,18 +37,28 @@ const printWidgetTree = (root, indent = 0) => {
35
37
  return result;
36
38
  };
37
39
  const update = async (instance, element, fiberRoot) => {
40
+ lastRenderError = null;
38
41
  instance.updateContainer(element, fiberRoot, null, () => { });
39
42
  await tick();
43
+ if (lastRenderError) {
44
+ const error = lastRenderError;
45
+ lastRenderError = null;
46
+ throw error;
47
+ }
48
+ };
49
+ const handleError = (error) => {
50
+ discardAllBatches();
51
+ lastRenderError = error;
40
52
  };
41
53
  const ensureInitialized = () => {
42
- const app = start(APP_ID);
54
+ application = start(APP_ID);
43
55
  if (!container) {
44
56
  const instance = reconciler.getInstance();
45
- container = instance.createContainer(ROOT_NODE_CONTAINER, 0, null, false, null, "", (error) => console.error("Test reconciler error:", error), () => { }, () => { }, () => { }, null);
57
+ container = instance.createContainer(application, 0, null, false, null, "", handleError, handleError, () => { }, () => { }, null);
46
58
  }
47
- return { app, container };
59
+ return { app: application, container };
48
60
  };
49
- const DefaultWrapper = ({ children }) => (_jsx(ApplicationWindow, { children: children }));
61
+ const DefaultWrapper = ({ children }) => (_jsx(GtkApplicationWindow, { children: children }));
50
62
  const wrapElement = (element, wrapper = true) => {
51
63
  if (wrapper === false)
52
64
  return element;
@@ -56,16 +68,35 @@ const wrapElement = (element, wrapper = true) => {
56
68
  return _jsx(Wrapper, { children: element });
57
69
  };
58
70
  /**
59
- * Renders a React element into a GTK application for testing.
71
+ * Renders a React element for testing.
72
+ *
73
+ * Creates a GTK application context and renders the element, returning
74
+ * query methods and utilities for interacting with the rendered widgets.
75
+ *
60
76
  * @param element - The React element to render
61
- * @param options - Render options including wrapper component
62
- * @returns Object containing query methods, container, and utility functions
77
+ * @param options - Render options including wrapper configuration
78
+ * @returns A promise resolving to query methods and utilities
79
+ *
80
+ * @example
81
+ * ```tsx
82
+ * import { render, screen } from "@gtkx/testing";
83
+ *
84
+ * test("button click", async () => {
85
+ * await render(<MyButton />);
86
+ * const button = await screen.findByRole(Gtk.AccessibleRole.BUTTON);
87
+ * await userEvent.click(button);
88
+ * });
89
+ * ```
90
+ *
91
+ * @see {@link cleanup} for cleaning up after tests
92
+ * @see {@link screen} for global query access
63
93
  */
64
94
  export const render = async (element, options) => {
65
95
  const { app: application, container: fiberRoot } = ensureInitialized();
66
96
  const instance = reconciler.getInstance();
67
97
  const wrappedElement = wrapElement(element, options?.wrapper);
68
- await update(instance, wrappedElement, fiberRoot);
98
+ const withContext = _jsx(ApplicationContext.Provider, { value: application, children: wrappedElement });
99
+ await update(instance, withContext, fiberRoot);
69
100
  setScreenRoot(application);
70
101
  return {
71
102
  container: application,
@@ -80,7 +111,8 @@ export const render = async (element, options) => {
80
111
  unmount: () => update(instance, null, fiberRoot),
81
112
  rerender: (newElement) => {
82
113
  const wrapped = wrapElement(newElement, options?.wrapper);
83
- return update(instance, wrapped, fiberRoot);
114
+ const withCtx = _jsx(ApplicationContext.Provider, { value: application, children: wrapped });
115
+ return update(instance, withCtx, fiberRoot);
84
116
  },
85
117
  debug: () => {
86
118
  const activeWindow = application.getActiveWindow();
@@ -91,26 +123,30 @@ export const render = async (element, options) => {
91
123
  };
92
124
  };
93
125
  /**
94
- * Cleans up the rendered component by unmounting it and destroying windows.
95
- * Should be called after each test to reset state.
126
+ * Cleans up the rendered component tree.
127
+ *
128
+ * Unmounts all rendered components and resets the testing environment.
129
+ * Call this in `afterEach` to ensure tests don't affect each other.
130
+ *
131
+ * @example
132
+ * ```tsx
133
+ * import { render, cleanup } from "@gtkx/testing";
134
+ *
135
+ * afterEach(async () => {
136
+ * await cleanup();
137
+ * });
138
+ *
139
+ * test("my test", async () => {
140
+ * await render(<MyComponent />);
141
+ * // ...
142
+ * });
143
+ * ```
96
144
  */
97
145
  export const cleanup = async () => {
98
- if (container) {
99
- const app = getApplication();
146
+ if (container && application) {
100
147
  const instance = reconciler.getInstance();
101
148
  await update(instance, null, container);
102
- for (const window of app.getWindows()) {
103
- window.destroy();
104
- }
105
149
  }
106
150
  container = null;
107
151
  setScreenRoot(null);
108
152
  };
109
- /**
110
- * Tears down the testing environment by cleaning up and stopping GTK.
111
- * Can be used as global teardown in your test runner configuration.
112
- */
113
- export const teardown = async () => {
114
- await cleanup();
115
- stop();
116
- };
package/dist/screen.d.ts CHANGED
@@ -1,19 +1,44 @@
1
1
  import type * as Gtk from "@gtkx/ffi/gtk";
2
2
  import type { ByRoleOptions, TextMatch, TextMatchOptions } from "./types.js";
3
+ /** @internal */
3
4
  export declare const setScreenRoot: (root: Gtk.Application | null) => void;
4
5
  /**
5
- * Global screen object providing query methods bound to the current render root.
6
- * Similar to Testing Library's screen, it provides all query variants without
7
- * needing to destructure from render().
6
+ * Global query object for accessing rendered components.
7
+ *
8
+ * Provides the same query methods as render result, but automatically
9
+ * uses the most recently rendered application as the container.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * import { render, screen } from "@gtkx/testing";
14
+ *
15
+ * test("finds button", async () => {
16
+ * await render(<MyComponent />);
17
+ * const button = await screen.findByRole(Gtk.AccessibleRole.BUTTON);
18
+ * expect(button).toBeDefined();
19
+ * });
20
+ * ```
21
+ *
22
+ * @see {@link render} for rendering components
23
+ * @see {@link within} for scoped queries
8
24
  */
9
25
  export declare const screen: {
26
+ /** Find single element by accessible role */
10
27
  findByRole: (role: Gtk.AccessibleRole, options?: ByRoleOptions) => Promise<Gtk.Widget>;
28
+ /** Find single element by label/text content */
11
29
  findByLabelText: (text: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget>;
30
+ /** Find single element by visible text */
12
31
  findByText: (text: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget>;
32
+ /** Find single element by test ID (widget name) */
13
33
  findByTestId: (testId: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget>;
34
+ /** Find all elements by accessible role */
14
35
  findAllByRole: (role: Gtk.AccessibleRole, options?: ByRoleOptions) => Promise<Gtk.Widget[]>;
36
+ /** Find all elements by label/text content */
15
37
  findAllByLabelText: (text: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget[]>;
38
+ /** Find all elements by visible text */
16
39
  findAllByText: (text: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget[]>;
40
+ /** Find all elements by test ID (widget name) */
17
41
  findAllByTestId: (testId: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget[]>;
42
+ /** Print debug info to console */
18
43
  debug: () => void;
19
44
  };
package/dist/screen.js CHANGED
@@ -1,28 +1,53 @@
1
1
  import * as queries from "./queries.js";
2
2
  let currentRoot = null;
3
+ /** @internal */
3
4
  export const setScreenRoot = (root) => {
4
5
  currentRoot = root;
5
6
  };
6
7
  const getRoot = () => {
7
8
  if (!currentRoot) {
8
- throw new Error("No render has been performed. Call render() before using screen queries.");
9
+ throw new Error("No render has been performed: call render() before using screen queries");
9
10
  }
10
11
  return currentRoot;
11
12
  };
12
13
  /**
13
- * Global screen object providing query methods bound to the current render root.
14
- * Similar to Testing Library's screen, it provides all query variants without
15
- * needing to destructure from render().
14
+ * Global query object for accessing rendered components.
15
+ *
16
+ * Provides the same query methods as render result, but automatically
17
+ * uses the most recently rendered application as the container.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * import { render, screen } from "@gtkx/testing";
22
+ *
23
+ * test("finds button", async () => {
24
+ * await render(<MyComponent />);
25
+ * const button = await screen.findByRole(Gtk.AccessibleRole.BUTTON);
26
+ * expect(button).toBeDefined();
27
+ * });
28
+ * ```
29
+ *
30
+ * @see {@link render} for rendering components
31
+ * @see {@link within} for scoped queries
16
32
  */
17
33
  export const screen = {
34
+ /** Find single element by accessible role */
18
35
  findByRole: (role, options) => queries.findByRole(getRoot(), role, options),
36
+ /** Find single element by label/text content */
19
37
  findByLabelText: (text, options) => queries.findByLabelText(getRoot(), text, options),
38
+ /** Find single element by visible text */
20
39
  findByText: (text, options) => queries.findByText(getRoot(), text, options),
40
+ /** Find single element by test ID (widget name) */
21
41
  findByTestId: (testId, options) => queries.findByTestId(getRoot(), testId, options),
42
+ /** Find all elements by accessible role */
22
43
  findAllByRole: (role, options) => queries.findAllByRole(getRoot(), role, options),
44
+ /** Find all elements by label/text content */
23
45
  findAllByLabelText: (text, options) => queries.findAllByLabelText(getRoot(), text, options),
46
+ /** Find all elements by visible text */
24
47
  findAllByText: (text, options) => queries.findAllByText(getRoot(), text, options),
48
+ /** Find all elements by test ID (widget name) */
25
49
  findAllByTestId: (testId, options) => queries.findAllByTestId(getRoot(), testId, options),
50
+ /** Print debug info to console */
26
51
  debug: () => {
27
52
  console.log("Screen debug - root:", getRoot());
28
53
  },
package/dist/timing.d.ts CHANGED
@@ -1 +1,17 @@
1
+ /**
2
+ * Yields to the event loop, allowing pending GTK events to process.
3
+ *
4
+ * Use this after actions that trigger async widget updates.
5
+ *
6
+ * @returns Promise that resolves on the next event loop tick
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * import { tick } from "@gtkx/testing";
11
+ *
12
+ * widget.setSensitive(false);
13
+ * await tick(); // Wait for GTK to process the change
14
+ * expect(widget.getSensitive()).toBe(false);
15
+ * ```
16
+ */
1
17
  export declare const tick: () => Promise<void>;
package/dist/timing.js CHANGED
@@ -1 +1,17 @@
1
+ /**
2
+ * Yields to the event loop, allowing pending GTK events to process.
3
+ *
4
+ * Use this after actions that trigger async widget updates.
5
+ *
6
+ * @returns Promise that resolves on the next event loop tick
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * import { tick } from "@gtkx/testing";
11
+ *
12
+ * widget.setSensitive(false);
13
+ * await tick(); // Wait for GTK to process the change
14
+ * expect(widget.getSensitive()).toBe(false);
15
+ * ```
16
+ */
1
17
  export const tick = () => new Promise((resolve) => setTimeout(resolve, 0));
package/dist/types.d.ts CHANGED
@@ -1,117 +1,124 @@
1
1
  import type * as Gtk from "@gtkx/ffi/gtk";
2
2
  import type { ComponentType, ReactNode } from "react";
3
3
  /**
4
- * A function that receives the text content and widget, returning true for a match.
5
- * Matches React Testing Library's function matcher signature.
4
+ * Custom function for matching text content.
5
+ *
6
+ * @param content - The normalized text content to match against
7
+ * @param widget - The widget being tested
8
+ * @returns `true` if the content matches
6
9
  */
7
10
  export type TextMatchFunction = (content: string, widget: Gtk.Widget) => boolean;
8
11
  /**
9
- * Flexible text matching: string for exact/partial, RegExp for patterns, or function for custom logic.
10
- * Matches React Testing Library's TextMatch type.
12
+ * Text matching pattern.
13
+ *
14
+ * Can be a string for exact/substring matching, a RegExp for pattern matching,
15
+ * or a custom function for advanced matching logic.
11
16
  */
12
17
  export type TextMatch = string | RegExp | TextMatchFunction;
13
18
  /**
14
- * Options for normalizing text before comparison.
19
+ * Options for text normalization before matching.
15
20
  */
16
21
  export type NormalizerOptions = {
17
- /** Whether to trim whitespace from text. Defaults to true. */
22
+ /** Remove leading/trailing whitespace (default: true) */
18
23
  trim?: boolean;
19
- /** Whether to collapse multiple whitespace into single spaces. Defaults to true. */
24
+ /** Replace multiple whitespace characters with single space (default: true) */
20
25
  collapseWhitespace?: boolean;
21
26
  };
22
27
  /**
23
- * Options for text matching in queries.
28
+ * Options for text-based queries.
24
29
  */
25
30
  export type TextMatchOptions = {
26
- /** Whether to match the entire string exactly. Defaults to true. */
31
+ /** Require exact match vs substring match (default: true) */
27
32
  exact?: boolean;
28
- /**
29
- * Custom function to normalize text before comparison.
30
- * Cannot be used with trim/collapseWhitespace options.
31
- */
33
+ /** Custom text normalizer function */
32
34
  normalizer?: (text: string) => string;
33
- /** Whether to trim whitespace from text. Defaults to true. */
35
+ /** Remove leading/trailing whitespace (default: true) */
34
36
  trim?: boolean;
35
- /** Whether to collapse multiple whitespace into single spaces. Defaults to true. */
37
+ /** Replace multiple whitespace with single space (default: true) */
36
38
  collapseWhitespace?: boolean;
37
- /** Maximum time in milliseconds to wait for a match. */
39
+ /** Timeout in milliseconds for async queries (default: 1000) */
38
40
  timeout?: number;
39
41
  };
40
42
  /**
41
- * Options for querying elements by their accessible role.
43
+ * Options for role-based queries.
44
+ *
45
+ * Extends text matching options with accessible state filters.
42
46
  */
43
47
  export type ByRoleOptions = TextMatchOptions & {
44
- /** Filter by the element's accessible name. Supports string, RegExp, or function matcher. */
48
+ /** Filter by accessible name/label */
45
49
  name?: TextMatch;
46
- /** Filter checkboxes/switches by checked state. */
50
+ /** Filter by checked state (checkboxes, radios, toggles) */
47
51
  checked?: boolean;
48
- /** Filter toggle buttons by pressed state. */
52
+ /** Filter by pressed state */
49
53
  pressed?: boolean;
50
- /** Filter selectable items by selected state. */
54
+ /** Filter by selected state */
51
55
  selected?: boolean;
52
- /** Filter expandable elements by expanded state. */
56
+ /** Filter by expanded state (expanders) */
53
57
  expanded?: boolean;
54
- /** Filter headings by their level (1-6). */
58
+ /** Filter by heading level */
55
59
  level?: number;
56
60
  };
57
61
  /**
58
- * Options for waitFor and related async utilities.
62
+ * Options for {@link waitFor} and {@link waitForElementToBeRemoved}.
59
63
  */
60
64
  export type WaitForOptions = {
61
- /** Maximum time in milliseconds to wait. Defaults to 1000ms. */
65
+ /** Maximum time to wait in milliseconds (default: 1000) */
62
66
  timeout?: number;
63
- /** Interval in milliseconds between condition checks. Defaults to 50ms. */
67
+ /** Polling interval in milliseconds (default: 50) */
64
68
  interval?: number;
65
- /** Custom error handler called when timeout is reached. */
69
+ /** Custom error handler called on timeout */
66
70
  onTimeout?: (error: Error) => Error;
67
71
  };
68
72
  /**
69
- * Options for the render function.
73
+ * Options for {@link render}.
70
74
  */
71
75
  export type RenderOptions = {
72
76
  /**
73
- * Controls how the rendered element is wrapped.
74
- * - `true` (default): Wrap in ApplicationWindow
75
- * - `false`: No wrapping, render element as-is
76
- * - Component: Use a custom wrapper component
77
+ * Wrapper component or boolean.
78
+ * - `true` (default): Wrap in GtkApplicationWindow
79
+ * - `false`: No wrapper
80
+ * - Component: Custom wrapper component
77
81
  */
78
82
  wrapper?: boolean | ComponentType<{
79
83
  children: ReactNode;
80
84
  }>;
81
85
  };
82
86
  /**
83
- * Query methods bound to a specific container. All queries return promises
84
- * that resolve when a matching element is found or reject on timeout.
87
+ * Query methods bound to a container.
88
+ *
89
+ * @see {@link screen} for global queries
90
+ * @see {@link within} for scoped queries
85
91
  */
86
92
  export type BoundQueries = {
87
- /** Find a single element by its accessible role. */
93
+ /** Find single element by accessible role */
88
94
  findByRole: (role: Gtk.AccessibleRole, options?: ByRoleOptions) => Promise<Gtk.Widget>;
89
- /** Find a single element by its associated label text. */
95
+ /** Find single element by label/text content */
90
96
  findByLabelText: (text: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget>;
91
- /** Find a single element by its text content. */
97
+ /** Find single element by visible text */
92
98
  findByText: (text: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget>;
93
- /** Find a single element by its test ID. */
99
+ /** Find single element by test ID (widget name) */
94
100
  findByTestId: (testId: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget>;
95
- /** Find all elements matching an accessible role. */
101
+ /** Find all elements by accessible role */
96
102
  findAllByRole: (role: Gtk.AccessibleRole, options?: ByRoleOptions) => Promise<Gtk.Widget[]>;
97
- /** Find all elements with matching label text. */
103
+ /** Find all elements by label/text content */
98
104
  findAllByLabelText: (text: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget[]>;
99
- /** Find all elements with matching text content. */
105
+ /** Find all elements by visible text */
100
106
  findAllByText: (text: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget[]>;
101
- /** Find all elements with matching test ID. */
107
+ /** Find all elements by test ID (widget name) */
102
108
  findAllByTestId: (testId: TextMatch, options?: TextMatchOptions) => Promise<Gtk.Widget[]>;
103
109
  };
104
110
  /**
105
- * The result returned by the render function. Includes query methods
106
- * and utilities for interacting with the rendered component.
111
+ * Result returned by {@link render}.
112
+ *
113
+ * Provides query methods and utilities for testing rendered components.
107
114
  */
108
115
  export type RenderResult = BoundQueries & {
109
- /** The GTK Application instance containing the rendered component. */
116
+ /** The GTK Application container */
110
117
  container: Gtk.Application;
111
- /** Unmount the rendered component and clean up resources. */
118
+ /** Unmount the rendered component */
112
119
  unmount: () => Promise<void>;
113
- /** Re-render with a new element, preserving state where possible. */
120
+ /** Re-render with a new element */
114
121
  rerender: (element: ReactNode) => Promise<void>;
115
- /** Print the current widget tree to the console for debugging. */
122
+ /** Print the widget tree to console for debugging */
116
123
  debug: () => void;
117
124
  };
@@ -1,23 +1,97 @@
1
1
  import * as Gtk from "@gtkx/ffi/gtk";
2
2
  /**
3
- * Options for the tab user event.
3
+ * Options for tab navigation.
4
4
  */
5
5
  export type TabOptions = {
6
- /** If true, navigates backwards (Shift+Tab behavior). */
6
+ /** Navigate backwards (Shift+Tab) instead of forwards */
7
7
  shift?: boolean;
8
8
  };
9
9
  /**
10
- * Simulates user interactions with GTK widgets. Provides methods that mimic
11
- * real user behavior like clicking, typing, and clearing input fields.
10
+ * User interaction utilities for testing.
11
+ *
12
+ * Simulates user actions like clicking, typing, and selecting.
13
+ * All methods are async and wait for GTK event processing.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * import { render, screen, userEvent } from "@gtkx/testing";
18
+ *
19
+ * test("form submission", async () => {
20
+ * await render(<LoginForm />);
21
+ *
22
+ * const input = await screen.findByRole(Gtk.AccessibleRole.TEXT_BOX);
23
+ * await userEvent.type(input, "username");
24
+ *
25
+ * const button = await screen.findByRole(Gtk.AccessibleRole.BUTTON);
26
+ * await userEvent.click(button);
27
+ * });
28
+ * ```
12
29
  */
13
30
  export declare const userEvent: {
31
+ /**
32
+ * Clicks or toggles a widget.
33
+ *
34
+ * For toggleable widgets (checkboxes, switches, toggle buttons),
35
+ * toggles the active state. For buttons, emits clicked signal.
36
+ */
14
37
  click: (element: Gtk.Widget) => Promise<void>;
38
+ /**
39
+ * Double-clicks a widget.
40
+ *
41
+ * Emits two consecutive clicked signals.
42
+ */
15
43
  dblClick: (element: Gtk.Widget) => Promise<void>;
44
+ /**
45
+ * Triple-clicks a widget.
46
+ *
47
+ * Emits three consecutive clicked signals. Useful for text selection.
48
+ */
16
49
  tripleClick: (element: Gtk.Widget) => Promise<void>;
50
+ /**
51
+ * Activates a widget.
52
+ *
53
+ * Calls the widget's activate method.
54
+ */
17
55
  activate: (element: Gtk.Widget) => Promise<void>;
56
+ /**
57
+ * Simulates Tab key navigation.
58
+ *
59
+ * @param element - Starting element
60
+ * @param options - Use `shift: true` for backwards navigation
61
+ */
18
62
  tab: (element: Gtk.Widget, options?: TabOptions) => Promise<void>;
63
+ /**
64
+ * Types text into an editable widget.
65
+ *
66
+ * Appends text to the current content. Works with Entry, SearchEntry,
67
+ * and SpinButton widgets.
68
+ *
69
+ * @param element - The editable widget
70
+ * @param text - Text to type
71
+ */
19
72
  type: (element: Gtk.Widget, text: string) => Promise<void>;
73
+ /**
74
+ * Clears an editable widget's content.
75
+ *
76
+ * Sets the text to empty string.
77
+ */
20
78
  clear: (element: Gtk.Widget) => Promise<void>;
21
- selectOptions: (element: Gtk.Widget, values: string | string[] | number | number[]) => Promise<void>;
79
+ /**
80
+ * Selects options in a dropdown or list.
81
+ *
82
+ * Works with DropDown, ComboBox, ListBox, ListView, GridView, and ColumnView.
83
+ *
84
+ * @param element - The selectable widget
85
+ * @param values - Index or array of indices to select
86
+ */
87
+ selectOptions: (element: Gtk.Widget, values: number | number[]) => Promise<void>;
88
+ /**
89
+ * Deselects options in a list.
90
+ *
91
+ * Works with ListBox and multi-selection list views.
92
+ *
93
+ * @param element - The selectable widget
94
+ * @param values - Index or array of indices to deselect
95
+ */
22
96
  deselectOptions: (element: Gtk.Widget, values: number | number[]) => Promise<void>;
23
97
  };