@gtkx/testing 1.0.0-rc.4 → 1.1.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/README.md +5 -5
- package/dist/accessible-native.d.ts +16 -0
- package/dist/accessible-native.d.ts.map +1 -0
- package/dist/accessible-native.js +206 -0
- package/dist/accessible-native.js.map +1 -0
- package/dist/act.d.ts +1 -3
- package/dist/act.d.ts.map +1 -1
- package/dist/act.js +1 -1
- package/dist/act.js.map +1 -1
- package/dist/build-queries.d.ts +27 -10
- package/dist/build-queries.d.ts.map +1 -1
- package/dist/build-queries.js +22 -24
- package/dist/build-queries.js.map +1 -1
- package/dist/cleanup-registry.d.ts +1 -1
- package/dist/cleanup-registry.d.ts.map +1 -1
- package/dist/cleanup-registry.js.map +1 -1
- package/dist/config.d.ts +8 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +10 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +10 -1
- package/dist/errors.js.map +1 -1
- package/dist/fire-event.d.ts +35 -6
- package/dist/fire-event.d.ts.map +1 -1
- package/dist/fire-event.js +23 -7
- package/dist/fire-event.js.map +1 -1
- package/dist/frame-sync.d.ts +3 -2
- package/dist/frame-sync.d.ts.map +1 -1
- package/dist/frame-sync.js +19 -9
- package/dist/frame-sync.js.map +1 -1
- package/dist/harness-window.d.ts +5 -0
- package/dist/harness-window.d.ts.map +1 -0
- package/dist/harness-window.js +17 -0
- package/dist/harness-window.js.map +1 -0
- package/dist/index.d.ts +14 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -5
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +5 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +5 -0
- package/dist/internal.js.map +1 -0
- package/dist/matchers.d.ts +88 -46
- package/dist/matchers.d.ts.map +1 -1
- package/dist/matchers.js +178 -20
- package/dist/matchers.js.map +1 -1
- package/dist/pretty-format.d.ts +2 -0
- package/dist/pretty-format.d.ts.map +1 -0
- package/dist/pretty-format.js +2 -0
- package/dist/pretty-format.js.map +1 -0
- package/dist/pretty-widget.d.ts +5 -2
- package/dist/pretty-widget.d.ts.map +1 -1
- package/dist/pretty-widget.js +75 -57
- package/dist/pretty-widget.js.map +1 -1
- package/dist/production.d.ts +8 -0
- package/dist/production.d.ts.map +1 -0
- package/dist/production.js +34 -0
- package/dist/production.js.map +1 -0
- package/dist/queries.d.ts +98 -56
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +123 -83
- package/dist/queries.js.map +1 -1
- package/dist/query-helpers.d.ts +44 -0
- package/dist/query-helpers.d.ts.map +1 -0
- package/dist/query-helpers.js +57 -0
- package/dist/query-helpers.js.map +1 -0
- package/dist/render-children.d.ts +9 -0
- package/dist/render-children.d.ts.map +1 -0
- package/dist/render-children.js +11 -0
- package/dist/render-children.js.map +1 -0
- package/dist/render.d.ts +12 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +52 -16
- package/dist/render.js.map +1 -1
- package/dist/role-helpers.d.ts +12 -3
- package/dist/role-helpers.d.ts.map +1 -1
- package/dist/role-helpers.js +15 -5
- package/dist/role-helpers.js.map +1 -1
- package/dist/role-naming.d.ts +5 -0
- package/dist/role-naming.d.ts.map +1 -0
- package/dist/role-naming.js +96 -0
- package/dist/role-naming.js.map +1 -0
- package/dist/screenshot.d.ts +12 -20
- package/dist/screenshot.d.ts.map +1 -1
- package/dist/screenshot.js +179 -93
- package/dist/screenshot.js.map +1 -1
- package/dist/timers.d.ts +9 -0
- package/dist/timers.d.ts.map +1 -0
- package/dist/timers.js +21 -0
- package/dist/timers.js.map +1 -0
- package/dist/traversal.d.ts +7 -1
- package/dist/traversal.d.ts.map +1 -1
- package/dist/traversal.js +40 -6
- package/dist/traversal.js.map +1 -1
- package/dist/types.d.ts +32 -15
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/user-event/adjustment.d.ts +3 -0
- package/dist/user-event/adjustment.d.ts.map +1 -1
- package/dist/user-event/adjustment.js +25 -3
- package/dist/user-event/adjustment.js.map +1 -1
- package/dist/user-event/click.d.ts +44 -8
- package/dist/user-event/click.d.ts.map +1 -1
- package/dist/user-event/click.js +176 -44
- package/dist/user-event/click.js.map +1 -1
- package/dist/user-event/column-header-click.d.ts +4 -0
- package/dist/user-event/column-header-click.d.ts.map +1 -0
- package/dist/user-event/column-header-click.js +55 -0
- package/dist/user-event/column-header-click.js.map +1 -0
- package/dist/user-event/event-wrapper.d.ts.map +1 -1
- package/dist/user-event/event-wrapper.js +34 -20
- package/dist/user-event/event-wrapper.js.map +1 -1
- package/dist/user-event/index.d.ts +80 -13
- package/dist/user-event/index.d.ts.map +1 -1
- package/dist/user-event/index.js +44 -26
- package/dist/user-event/index.js.map +1 -1
- package/dist/user-event/indexed-children.d.ts +10 -0
- package/dist/user-event/indexed-children.d.ts.map +1 -0
- package/dist/user-event/indexed-children.js +50 -0
- package/dist/user-event/indexed-children.js.map +1 -0
- package/dist/user-event/keyboard.d.ts.map +1 -1
- package/dist/user-event/keyboard.js +115 -31
- package/dist/user-event/keyboard.js.map +1 -1
- package/dist/user-event/list-row-click.d.ts +4 -0
- package/dist/user-event/list-row-click.d.ts.map +1 -0
- package/dist/user-event/list-row-click.js +38 -0
- package/dist/user-event/list-row-click.js.map +1 -0
- package/dist/user-event/native-click.d.ts +6 -0
- package/dist/user-event/native-click.d.ts.map +1 -0
- package/dist/user-event/native-click.js +36 -0
- package/dist/user-event/native-click.js.map +1 -0
- package/dist/user-event/notebook-tab-click.d.ts +5 -0
- package/dist/user-event/notebook-tab-click.d.ts.map +1 -0
- package/dist/user-event/notebook-tab-click.js +39 -0
- package/dist/user-event/notebook-tab-click.js.map +1 -0
- package/dist/user-event/pointer.d.ts +1 -1
- package/dist/user-event/pointer.d.ts.map +1 -1
- package/dist/user-event/pointer.js +33 -9
- package/dist/user-event/pointer.js.map +1 -1
- package/dist/user-event/selection.d.ts +11 -8
- package/dist/user-event/selection.d.ts.map +1 -1
- package/dist/user-event/selection.js +49 -38
- package/dist/user-event/selection.js.map +1 -1
- package/dist/user-event/text.d.ts +12 -5
- package/dist/user-event/text.d.ts.map +1 -1
- package/dist/user-event/text.js +151 -46
- package/dist/user-event/text.js.map +1 -1
- package/dist/wait-for.d.ts.map +1 -1
- package/dist/wait-for.js +4 -3
- package/dist/wait-for.js.map +1 -1
- package/dist/widget-accessible-properties.d.ts +14 -26
- package/dist/widget-accessible-properties.d.ts.map +1 -1
- package/dist/widget-accessible-properties.js +135 -190
- package/dist/widget-accessible-properties.js.map +1 -1
- package/dist/widget-getters.d.ts +11 -0
- package/dist/widget-getters.d.ts.map +1 -0
- package/dist/widget-getters.js +46 -0
- package/dist/widget-getters.js.map +1 -0
- package/dist/window-state.d.ts +10 -0
- package/dist/window-state.d.ts.map +1 -0
- package/dist/window-state.js +41 -0
- package/dist/window-state.js.map +1 -0
- package/dist/within.d.ts +3 -2
- package/dist/within.d.ts.map +1 -1
- package/dist/within.js +3 -2
- package/dist/within.js.map +1 -1
- package/package.json +21 -8
- package/src/accessible-native.ts +333 -0
- package/src/act.ts +1 -1
- package/src/build-queries.ts +47 -41
- package/src/cleanup-registry.ts +1 -1
- package/src/config.ts +10 -1
- package/src/errors.ts +12 -1
- package/src/fire-event.ts +61 -8
- package/src/frame-sync.ts +30 -9
- package/src/harness-window.ts +23 -0
- package/src/index.ts +18 -11
- package/src/internal.ts +12 -0
- package/src/matchers.ts +457 -72
- package/src/pretty-format.ts +1 -0
- package/src/pretty-widget.ts +98 -70
- package/src/production.ts +51 -0
- package/src/queries.ts +127 -89
- package/src/query-helpers.ts +97 -0
- package/src/render-children.ts +25 -0
- package/src/render.tsx +77 -17
- package/src/role-helpers.ts +16 -5
- package/src/role-naming.ts +99 -0
- package/src/screenshot.ts +266 -104
- package/src/timers.ts +31 -0
- package/src/traversal.ts +66 -6
- package/src/types.ts +34 -17
- package/src/user-event/adjustment.ts +31 -3
- package/src/user-event/click.ts +248 -52
- package/src/user-event/column-header-click.ts +76 -0
- package/src/user-event/event-wrapper.ts +41 -23
- package/src/user-event/index.ts +130 -40
- package/src/user-event/indexed-children.ts +75 -0
- package/src/user-event/keyboard.ts +161 -43
- package/src/user-event/list-row-click.ts +54 -0
- package/src/user-event/native-click.ts +51 -0
- package/src/user-event/notebook-tab-click.ts +57 -0
- package/src/user-event/pointer.ts +48 -9
- package/src/user-event/selection.ts +67 -41
- package/src/user-event/text.ts +192 -46
- package/src/wait-for.ts +4 -4
- package/src/widget-accessible-properties.ts +183 -230
- package/src/widget-getters.ts +85 -0
- package/src/window-state.ts +70 -0
- package/src/within.ts +3 -2
package/dist/matchers.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import type { SyncExpectationResult } from "@vitest/expect";
|
|
1
2
|
import * as Gtk from "@gtkx/gi/gtk";
|
|
3
|
+
import type { ByRoleOptions, Matcher, MatcherOptions } from "./types.js";
|
|
4
|
+
import { type AccessibleAttributeValue } from "./accessible-native.js";
|
|
2
5
|
/** The expected value for a text matcher: an exact string or a regular expression. */
|
|
3
6
|
type TextExpectation = string | RegExp;
|
|
4
7
|
/** Options controlling how `toHaveTextContent` normalizes the text it reads. */
|
|
@@ -12,18 +15,27 @@ type TextContentOptions = {
|
|
|
12
15
|
/** The expected value for a style class: an exact class name or a regular expression. */
|
|
13
16
|
type ClassExpectation = string | RegExp;
|
|
14
17
|
/** The outcome of a matcher: whether it passed, and the failure text built on demand. */
|
|
15
|
-
type MatcherResult =
|
|
16
|
-
pass: boolean;
|
|
17
|
-
message: () => string;
|
|
18
|
-
};
|
|
18
|
+
type MatcherResult = Pick<SyncExpectationResult, "message" | "pass">;
|
|
19
19
|
/** The matcher state bound as `this`, supplying the test runner's deep equality check. */
|
|
20
20
|
type MatcherContext = {
|
|
21
|
+
/** Compares a received value against an expected one, resolving asymmetric matchers. */
|
|
21
22
|
equals: (actual: unknown, expected: unknown) => boolean;
|
|
22
23
|
};
|
|
23
24
|
/** Compares text read from the received widget; with no expected value, asserts the text is non-empty. */
|
|
24
25
|
type TextMatcher = (received: unknown, expected?: TextExpectation) => MatcherResult;
|
|
25
26
|
/** Asserts a single state of the received widget, taking no expected value. */
|
|
26
27
|
type StateMatcher = (received: unknown) => MatcherResult;
|
|
28
|
+
/** Trailing arguments of the `ByRole` query family, as a containment matcher takes them. */
|
|
29
|
+
type RoleQueryArgs = [role: Gtk.AccessibleRole, options?: ByRoleOptions];
|
|
30
|
+
/** Trailing arguments of the text-based query families, as a containment matcher takes them. */
|
|
31
|
+
type TextQueryArgs = [text: Matcher, options?: MatcherOptions];
|
|
32
|
+
/** Counts the descendants a query family finds under the received widget. */
|
|
33
|
+
type ContainmentMatcher<Args extends unknown[]> = (received: unknown, ...args: Args) => MatcherResult;
|
|
34
|
+
type BooleanAccessibleState = Gtk.AccessibleState.BUSY | Gtk.AccessibleState.DISABLED | Gtk.AccessibleState.EXPANDED | Gtk.AccessibleState.HIDDEN | Gtk.AccessibleState.SELECTED | Gtk.AccessibleState.VISITED;
|
|
35
|
+
type TristateAccessibleState = Gtk.AccessibleState.CHECKED | Gtk.AccessibleState.PRESSED;
|
|
36
|
+
type StringAccessibleProperty = Gtk.AccessibleProperty.DESCRIPTION | Gtk.AccessibleProperty.HELP_TEXT | Gtk.AccessibleProperty.KEY_SHORTCUTS | Gtk.AccessibleProperty.LABEL | Gtk.AccessibleProperty.PLACEHOLDER | Gtk.AccessibleProperty.ROLE_DESCRIPTION | Gtk.AccessibleProperty.VALUE_TEXT;
|
|
37
|
+
type BooleanAccessibleProperty = Gtk.AccessibleProperty.HAS_POPUP | Gtk.AccessibleProperty.MODAL | Gtk.AccessibleProperty.MULTI_LINE | Gtk.AccessibleProperty.MULTI_SELECTABLE | Gtk.AccessibleProperty.READ_ONLY | Gtk.AccessibleProperty.REQUIRED;
|
|
38
|
+
type NumberAccessibleProperty = Gtk.AccessibleProperty.LEVEL | Gtk.AccessibleProperty.VALUE_MAX | Gtk.AccessibleProperty.VALUE_MIN | Gtk.AccessibleProperty.VALUE_NOW;
|
|
27
39
|
/** A text matcher that also takes normalization options for the text it reads. */
|
|
28
40
|
type TextContentMatcher = (received: unknown, expected?: TextExpectation, options?: TextContentOptions) => MatcherResult;
|
|
29
41
|
/** Signatures of the widget assertion matchers, keyed by the name each is registered under. */
|
|
@@ -41,23 +53,27 @@ type MatcherImplementations = {
|
|
|
41
53
|
toHaveAccessibleDescription: TextMatcher;
|
|
42
54
|
/** Asserts the joined accessible names of the widget's `error-message` targets, read only while it is invalid. */
|
|
43
55
|
toHaveAccessibleErrorMessage: TextMatcher;
|
|
44
|
-
/** Asserts the widget's placeholder text; with no argument, that it has some. */
|
|
45
|
-
toHavePlaceholderText: TextMatcher;
|
|
46
56
|
/** Asserts the text currently selected in an editable widget. */
|
|
47
57
|
toHaveSelection: TextMatcher;
|
|
58
|
+
/**
|
|
59
|
+
* Asserts an accessible state GTK holds for the widget, taking the value type that state carries.
|
|
60
|
+
* With no expected value, asserts only that the state is set to something determinate.
|
|
61
|
+
*/
|
|
62
|
+
toHaveAccessibleState: (received: unknown, state: Gtk.AccessibleState, expected?: boolean | number) => MatcherResult;
|
|
63
|
+
/**
|
|
64
|
+
* Asserts an accessible property GTK holds for the widget, taking the value type that property
|
|
65
|
+
* carries. With no expected value, asserts only that the property is set. Numeric properties
|
|
66
|
+
* compare the way `toHaveValue` and the `value` option of the `ByRole` queries do, within 0.001.
|
|
67
|
+
*/
|
|
68
|
+
toHaveAccessibleProperty: (received: unknown, property: Gtk.AccessibleProperty, expected?: AccessibleAttributeValue) => MatcherResult;
|
|
48
69
|
/** Asserts the widget's checked state is checked rather than unchecked or mixed. */
|
|
49
70
|
toBeChecked: StateMatcher;
|
|
50
71
|
/** Asserts the widget's checked state is mixed. */
|
|
51
72
|
toBePartiallyChecked: StateMatcher;
|
|
52
73
|
/** Asserts a `Gtk.ToggleButton` is active, and throws for any other widget. */
|
|
53
74
|
toBePressed: StateMatcher;
|
|
54
|
-
/** Asserts
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Asserts a `Gtk.ListBoxRow` or `Gtk.FlowBoxChild` is selected, or that a widget in a selectable role
|
|
58
|
-
* carries the selected state flag, and throws for anything else.
|
|
59
|
-
*/
|
|
60
|
-
toBeSelected: StateMatcher;
|
|
75
|
+
/** Asserts the widget's accessible pressed state is mixed, and throws when it exposes none. */
|
|
76
|
+
toBePartiallyPressed: StateMatcher;
|
|
61
77
|
/** Asserts the widget is insensitive, or sits inside an insensitive ancestor. */
|
|
62
78
|
toBeDisabled: StateMatcher;
|
|
63
79
|
/** Asserts the widget and all of its ancestors are sensitive. */
|
|
@@ -67,7 +83,7 @@ type MatcherImplementations = {
|
|
|
67
83
|
/** Asserts the widget's root is a window that is still in the toplevel list. */
|
|
68
84
|
toBeRooted: StateMatcher;
|
|
69
85
|
/** Asserts the widget has neither a child nor label text. */
|
|
70
|
-
|
|
86
|
+
toBeEmptyWidget: StateMatcher;
|
|
71
87
|
/** Asserts the widget's accessible invalid state is set to anything other than false. */
|
|
72
88
|
toBeInvalid: StateMatcher;
|
|
73
89
|
/** Asserts the widget's accessible invalid state is unset or false. */
|
|
@@ -76,12 +92,45 @@ type MatcherImplementations = {
|
|
|
76
92
|
toBeRequired: StateMatcher;
|
|
77
93
|
/** Asserts the widget holds the platform focus state. */
|
|
78
94
|
toHaveFocus: StateMatcher;
|
|
79
|
-
/**
|
|
95
|
+
/**
|
|
96
|
+
* Asserts a widget's numeric value, or its display value when a string is given.
|
|
97
|
+
*
|
|
98
|
+
* Numbers come from the accessibility tree, which GTK keeps to a resolution of 0.001: it drops an
|
|
99
|
+
* update whose value is nearer than that to the one already published, so a widget that moves by
|
|
100
|
+
* less keeps its previous value. Numbers therefore match within 0.001, the same tolerance the
|
|
101
|
+
* `value` option of the `ByRole` queries and `toHaveAccessibleProperty` apply. That option reads
|
|
102
|
+
* the same tree, where the maximum of a paged widget such as a scrollbar is the last value it can
|
|
103
|
+
* reach, its adjustment's upper bound less one page.
|
|
104
|
+
*/
|
|
80
105
|
toHaveValue: (received: unknown, expected?: number | string) => MatcherResult;
|
|
81
106
|
/** Asserts the widget's accessible role. */
|
|
82
107
|
toHaveRole: (received: unknown, expected: Gtk.AccessibleRole) => MatcherResult;
|
|
83
108
|
/** Asserts the widget is, or is an ancestor of, the given widget. */
|
|
84
109
|
toContainElement: (received: unknown, descendant: Gtk.Widget | null) => MatcherResult;
|
|
110
|
+
/** Asserts the widget comes before the given widget in the widget tree, neither containing the other. */
|
|
111
|
+
toAppearBefore: (received: unknown, other: Gtk.Widget) => MatcherResult;
|
|
112
|
+
/** Asserts the widget comes after the given widget in the widget tree, neither containing the other. */
|
|
113
|
+
toAppearAfter: (received: unknown, other: Gtk.Widget) => MatcherResult;
|
|
114
|
+
/** Asserts at least one widget under the received one matches the `ByRole` query. */
|
|
115
|
+
toContainAnyByRole: ContainmentMatcher<RoleQueryArgs>;
|
|
116
|
+
/** Asserts exactly one widget under the received one matches the `ByRole` query. */
|
|
117
|
+
toContainOneByRole: ContainmentMatcher<RoleQueryArgs>;
|
|
118
|
+
/** Asserts at least one widget under the received one matches the `ByText` query. */
|
|
119
|
+
toContainAnyByText: ContainmentMatcher<TextQueryArgs>;
|
|
120
|
+
/** Asserts exactly one widget under the received one matches the `ByText` query. */
|
|
121
|
+
toContainOneByText: ContainmentMatcher<TextQueryArgs>;
|
|
122
|
+
/** Asserts at least one widget under the received one matches the `ByLabelText` query. */
|
|
123
|
+
toContainAnyByLabelText: ContainmentMatcher<TextQueryArgs>;
|
|
124
|
+
/** Asserts exactly one widget under the received one matches the `ByLabelText` query. */
|
|
125
|
+
toContainOneByLabelText: ContainmentMatcher<TextQueryArgs>;
|
|
126
|
+
/** Asserts at least one widget under the received one matches the `ByPlaceholderText` query. */
|
|
127
|
+
toContainAnyByPlaceholderText: ContainmentMatcher<TextQueryArgs>;
|
|
128
|
+
/** Asserts exactly one widget under the received one matches the `ByPlaceholderText` query. */
|
|
129
|
+
toContainOneByPlaceholderText: ContainmentMatcher<TextQueryArgs>;
|
|
130
|
+
/** Asserts at least one widget under the received one matches the `ByDisplayValue` query. */
|
|
131
|
+
toContainAnyByDisplayValue: ContainmentMatcher<TextQueryArgs>;
|
|
132
|
+
/** Asserts exactly one widget under the received one matches the `ByDisplayValue` query. */
|
|
133
|
+
toContainOneByDisplayValue: ContainmentMatcher<TextQueryArgs>;
|
|
85
134
|
/**
|
|
86
135
|
* Asserts the widget carries every given style class, each a name, a space-separated list, or a pattern.
|
|
87
136
|
* Pass `{ exact: true }` last to require exactly that set, which rules out patterns.
|
|
@@ -93,34 +142,8 @@ type MatcherImplementations = {
|
|
|
93
142
|
*/
|
|
94
143
|
toHaveObjectProperty: (this: MatcherContext, received: unknown, ...args: unknown[]) => MatcherResult;
|
|
95
144
|
};
|
|
96
|
-
declare const toHaveAccessibleName: TextMatcher;
|
|
97
|
-
declare const toHaveAccessibleDescription: TextMatcher;
|
|
98
|
-
declare const toHaveAccessibleErrorMessage: TextMatcher;
|
|
99
|
-
declare const toHavePlaceholderText: TextMatcher;
|
|
100
|
-
declare const toHaveSelection: TextMatcher;
|
|
101
|
-
declare const toBePressed: StateMatcher;
|
|
102
|
-
declare const toBeExpanded: StateMatcher;
|
|
103
|
-
declare const toBeSelected: StateMatcher;
|
|
104
|
-
declare const toBeRequired: StateMatcher;
|
|
105
145
|
/** The widget assertion matchers keyed by name, suitable for passing to `expect.extend`. */
|
|
106
146
|
declare const matchers: MatcherImplementations;
|
|
107
|
-
declare function toHaveTextContent(received: unknown, expected?: TextExpectation, options?: TextContentOptions): MatcherResult;
|
|
108
|
-
declare function toBeChecked(received: unknown): MatcherResult;
|
|
109
|
-
declare function toBePartiallyChecked(received: unknown): MatcherResult;
|
|
110
|
-
declare function toHaveDisplayValue(received: unknown, expected?: TextExpectation): MatcherResult;
|
|
111
|
-
declare function toHaveValue(received: unknown, expected?: number | string): MatcherResult;
|
|
112
|
-
declare function toBeDisabled(received: unknown): MatcherResult;
|
|
113
|
-
declare function toBeEnabled(received: unknown): MatcherResult;
|
|
114
|
-
declare function toBeVisible(received: unknown): MatcherResult;
|
|
115
|
-
declare function toBeRooted(received: unknown): MatcherResult;
|
|
116
|
-
declare function toBeEmpty(received: unknown): MatcherResult;
|
|
117
|
-
declare function toBeInvalid(received: unknown): MatcherResult;
|
|
118
|
-
declare function toBeValid(received: unknown): MatcherResult;
|
|
119
|
-
declare function toHaveFocus(received: unknown): MatcherResult;
|
|
120
|
-
declare function toHaveRole(received: unknown, expected: Gtk.AccessibleRole): MatcherResult;
|
|
121
|
-
declare function toContainElement(received: unknown, descendant: Gtk.Widget | null): MatcherResult;
|
|
122
|
-
declare function toHaveClass(received: unknown, ...args: unknown[]): MatcherResult;
|
|
123
|
-
declare function toHaveObjectProperty(this: MatcherContext, received: unknown, ...args: unknown[]): MatcherResult;
|
|
124
147
|
/** Registers the widget matchers on the global `expect`, when one is available. Safe to call more than once. */
|
|
125
148
|
declare const registerMatchers: () => void;
|
|
126
149
|
declare module "@vitest/expect" {
|
|
@@ -130,18 +153,25 @@ declare module "@vitest/expect" {
|
|
|
130
153
|
toHaveAccessibleName(expected?: TextExpectation): void;
|
|
131
154
|
toHaveAccessibleDescription(expected?: TextExpectation): void;
|
|
132
155
|
toHaveAccessibleErrorMessage(expected?: TextExpectation): void;
|
|
133
|
-
toHavePlaceholderText(expected?: TextExpectation): void;
|
|
134
156
|
toHaveSelection(expected?: TextExpectation): void;
|
|
157
|
+
toHaveAccessibleState(state: BooleanAccessibleState, expected?: boolean): void;
|
|
158
|
+
toHaveAccessibleState(state: TristateAccessibleState, expected?: Gtk.AccessibleTristate): void;
|
|
159
|
+
toHaveAccessibleState(state: Gtk.AccessibleState.INVALID, expected?: Gtk.AccessibleInvalidState): void;
|
|
160
|
+
toHaveAccessibleProperty(property: StringAccessibleProperty, expected?: string): void;
|
|
161
|
+
toHaveAccessibleProperty(property: BooleanAccessibleProperty, expected?: boolean): void;
|
|
162
|
+
toHaveAccessibleProperty(property: NumberAccessibleProperty, expected?: number): void;
|
|
163
|
+
toHaveAccessibleProperty(property: Gtk.AccessibleProperty.AUTOCOMPLETE, expected?: Gtk.AccessibleAutocomplete): void;
|
|
164
|
+
toHaveAccessibleProperty(property: Gtk.AccessibleProperty.ORIENTATION, expected?: Gtk.Orientation): void;
|
|
165
|
+
toHaveAccessibleProperty(property: Gtk.AccessibleProperty.SORT, expected?: Gtk.AccessibleSort): void;
|
|
135
166
|
toBeChecked(): void;
|
|
136
167
|
toBePartiallyChecked(): void;
|
|
137
168
|
toBePressed(): void;
|
|
138
|
-
|
|
139
|
-
toBeSelected(): void;
|
|
169
|
+
toBePartiallyPressed(): void;
|
|
140
170
|
toBeDisabled(): void;
|
|
141
171
|
toBeEnabled(): void;
|
|
142
172
|
toBeVisible(): void;
|
|
143
173
|
toBeRooted(): void;
|
|
144
|
-
|
|
174
|
+
toBeEmptyWidget(): void;
|
|
145
175
|
toBeInvalid(): void;
|
|
146
176
|
toBeValid(): void;
|
|
147
177
|
toBeRequired(): void;
|
|
@@ -149,6 +179,18 @@ declare module "@vitest/expect" {
|
|
|
149
179
|
toHaveValue(expected?: number | string): void;
|
|
150
180
|
toHaveRole(expected: Gtk.AccessibleRole): void;
|
|
151
181
|
toContainElement(descendant: Gtk.Widget | null): void;
|
|
182
|
+
toAppearBefore(other: Gtk.Widget): void;
|
|
183
|
+
toAppearAfter(other: Gtk.Widget): void;
|
|
184
|
+
toContainAnyByRole(...args: RoleQueryArgs): void;
|
|
185
|
+
toContainOneByRole(...args: RoleQueryArgs): void;
|
|
186
|
+
toContainAnyByText(...args: TextQueryArgs): void;
|
|
187
|
+
toContainOneByText(...args: TextQueryArgs): void;
|
|
188
|
+
toContainAnyByLabelText(...args: TextQueryArgs): void;
|
|
189
|
+
toContainOneByLabelText(...args: TextQueryArgs): void;
|
|
190
|
+
toContainAnyByPlaceholderText(...args: TextQueryArgs): void;
|
|
191
|
+
toContainOneByPlaceholderText(...args: TextQueryArgs): void;
|
|
192
|
+
toContainAnyByDisplayValue(...args: TextQueryArgs): void;
|
|
193
|
+
toContainOneByDisplayValue(...args: TextQueryArgs): void;
|
|
152
194
|
toHaveClass(...args: (ClassExpectation | {
|
|
153
195
|
exact: boolean;
|
|
154
196
|
})[]): void;
|
|
@@ -159,5 +201,5 @@ declare module "@vitest/expect" {
|
|
|
159
201
|
interface AsymmetricMatchersContaining extends WidgetMatchers {
|
|
160
202
|
}
|
|
161
203
|
}
|
|
162
|
-
export {
|
|
204
|
+
export { matchers, registerMatchers, type ClassExpectation, type TextContentOptions, type TextExpectation };
|
|
163
205
|
//# sourceMappingURL=matchers.d.ts.map
|
package/dist/matchers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matchers.d.ts","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"matchers.d.ts","sourceRoot":"","sources":["../src/matchers.ts"],"names":[],"mappings":"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"}
|
package/dist/matchers.js
CHANGED
|
@@ -1,20 +1,33 @@
|
|
|
1
|
-
/// <reference types="@vitest/expect" />
|
|
2
1
|
import * as GObject from "@gtkx/gi/gobject";
|
|
3
2
|
import * as Gtk from "@gtkx/gi/gtk";
|
|
3
|
+
import { ACCESSIBLE_NUMBER_TOLERANCE, isAccessibleNumberMatch, isAccessibleNumberProperty, readAccessibleProperty, readAccessibleState, } from "./accessible-native.js";
|
|
4
4
|
import { getDefaultNormalizer } from "./normalize.js";
|
|
5
|
+
import { queryAllByDisplayValue, queryAllByLabelText, queryAllByPlaceholderText, queryAllByRole, queryAllByText, } from "./queries.js";
|
|
5
6
|
import { formatRole } from "./role-helpers.js";
|
|
6
|
-
import {
|
|
7
|
+
import { descendants } from "./traversal.js";
|
|
8
|
+
import { getWidgetAccessibleName, getWidgetCheckedState, getWidgetDescribedByText, getWidgetDisplayValue, getWidgetErrorMessage, getWidgetInvalidState, getWidgetLabelText, getWidgetPressedState, getWidgetRequiredState, getWidgetSelection, getWidgetTextContent, getWidgetValueNow, hasDisplayValue, isWidgetDisabled, isWidgetValueMatch, isWidgetVisible, } from "./widget-accessible-properties.js";
|
|
9
|
+
import { getTypeTag } from "./widget-getters.js";
|
|
10
|
+
import { isWindowActivated } from "./window-state.js";
|
|
7
11
|
const registration = { isRegistered: false };
|
|
12
|
+
const MIXED_TRISTATE = Gtk.AccessibleTristate.MIXED;
|
|
13
|
+
const ROUNDED_READING = ", which the accessibility tree rounds to six significant digits";
|
|
8
14
|
const displayValueMatcher = textMatcher("toHaveDisplayValue", getWidgetDisplayValue, "exact");
|
|
9
15
|
const toHaveAccessibleName = textMatcher("toHaveAccessibleName", getWidgetAccessibleName, "exact");
|
|
10
16
|
const toHaveAccessibleDescription = textMatcher("toHaveAccessibleDescription", getWidgetDescribedByText, "exact");
|
|
11
17
|
const toHaveAccessibleErrorMessage = textMatcher("toHaveAccessibleErrorMessage", readErrorMessageText, "exact");
|
|
12
|
-
const toHavePlaceholderText = textMatcher("toHavePlaceholderText", getWidgetPlaceholderText, "exact");
|
|
13
18
|
const toHaveSelection = textMatcher("toHaveSelection", getWidgetSelection, "exact");
|
|
14
19
|
const toBePressed = booleanStateMatcher("toBePressed", "pressed", getWidgetPressedState);
|
|
15
|
-
const toBeExpanded = booleanStateMatcher("toBeExpanded", "expanded", getWidgetExpandedState);
|
|
16
|
-
const toBeSelected = booleanStateMatcher("toBeSelected", "selected", getWidgetSelectedState);
|
|
17
20
|
const toBeRequired = booleanStateMatcher("toBeRequired", "required", getWidgetRequiredState);
|
|
21
|
+
const toContainAnyByRole = containmentMatcher("toContainAnyByRole", false, queryAllByRole);
|
|
22
|
+
const toContainOneByRole = containmentMatcher("toContainOneByRole", true, queryAllByRole);
|
|
23
|
+
const toContainAnyByText = containmentMatcher("toContainAnyByText", false, queryAllByText);
|
|
24
|
+
const toContainOneByText = containmentMatcher("toContainOneByText", true, queryAllByText);
|
|
25
|
+
const toContainAnyByLabelText = containmentMatcher("toContainAnyByLabelText", false, queryAllByLabelText);
|
|
26
|
+
const toContainOneByLabelText = containmentMatcher("toContainOneByLabelText", true, queryAllByLabelText);
|
|
27
|
+
const toContainAnyByPlaceholderText = containmentMatcher("toContainAnyByPlaceholderText", false, queryAllByPlaceholderText);
|
|
28
|
+
const toContainOneByPlaceholderText = containmentMatcher("toContainOneByPlaceholderText", true, queryAllByPlaceholderText);
|
|
29
|
+
const toContainAnyByDisplayValue = containmentMatcher("toContainAnyByDisplayValue", false, queryAllByDisplayValue);
|
|
30
|
+
const toContainOneByDisplayValue = containmentMatcher("toContainOneByDisplayValue", true, queryAllByDisplayValue);
|
|
18
31
|
/** The widget assertion matchers keyed by name, suitable for passing to `expect.extend`. */
|
|
19
32
|
const matchers = {
|
|
20
33
|
toHaveDisplayValue,
|
|
@@ -22,18 +35,18 @@ const matchers = {
|
|
|
22
35
|
toHaveAccessibleName,
|
|
23
36
|
toHaveAccessibleDescription,
|
|
24
37
|
toHaveAccessibleErrorMessage,
|
|
25
|
-
toHavePlaceholderText,
|
|
26
38
|
toHaveSelection,
|
|
39
|
+
toHaveAccessibleState,
|
|
40
|
+
toHaveAccessibleProperty,
|
|
27
41
|
toBeChecked,
|
|
28
42
|
toBePartiallyChecked,
|
|
29
43
|
toBePressed,
|
|
30
|
-
|
|
31
|
-
toBeSelected,
|
|
44
|
+
toBePartiallyPressed,
|
|
32
45
|
toBeDisabled,
|
|
33
46
|
toBeEnabled,
|
|
34
47
|
toBeVisible,
|
|
35
48
|
toBeRooted,
|
|
36
|
-
|
|
49
|
+
toBeEmptyWidget,
|
|
37
50
|
toBeInvalid,
|
|
38
51
|
toBeValid,
|
|
39
52
|
toBeRequired,
|
|
@@ -41,6 +54,18 @@ const matchers = {
|
|
|
41
54
|
toHaveValue,
|
|
42
55
|
toHaveRole,
|
|
43
56
|
toContainElement,
|
|
57
|
+
toAppearBefore,
|
|
58
|
+
toAppearAfter,
|
|
59
|
+
toContainAnyByRole,
|
|
60
|
+
toContainOneByRole,
|
|
61
|
+
toContainAnyByText,
|
|
62
|
+
toContainOneByText,
|
|
63
|
+
toContainAnyByLabelText,
|
|
64
|
+
toContainOneByLabelText,
|
|
65
|
+
toContainAnyByPlaceholderText,
|
|
66
|
+
toContainOneByPlaceholderText,
|
|
67
|
+
toContainAnyByDisplayValue,
|
|
68
|
+
toContainOneByDisplayValue,
|
|
44
69
|
toHaveClass,
|
|
45
70
|
toHaveObjectProperty,
|
|
46
71
|
};
|
|
@@ -61,7 +86,7 @@ const describeWidget = (widget) => {
|
|
|
61
86
|
const name = getWidgetAccessibleName(widget);
|
|
62
87
|
return name === null ? `<${role}>` : `<${role} name=${JSON.stringify(name)}>`;
|
|
63
88
|
};
|
|
64
|
-
const describeObject = (object) => object instanceof Gtk.Widget ? describeWidget(object) : `<${object
|
|
89
|
+
const describeObject = (object) => object instanceof Gtk.Widget ? describeWidget(object) : `<${getTypeTag(object)}>`;
|
|
65
90
|
const isTextMatch = (actual, expected, mode) => {
|
|
66
91
|
if (expected instanceof RegExp) {
|
|
67
92
|
expected.lastIndex = 0;
|
|
@@ -88,6 +113,69 @@ const stateResult = (widget, stateName, isPass) => ({
|
|
|
88
113
|
pass: isPass,
|
|
89
114
|
message: () => `expected widget ${negationPrefix(isPass)}to be ${stateName}\n${describeWidget(widget)}`,
|
|
90
115
|
});
|
|
116
|
+
const isHoldingFocus = (widget, root) => {
|
|
117
|
+
const focus = root.getFocus();
|
|
118
|
+
return focus !== null && (focus === widget || focus.isAncestor(widget));
|
|
119
|
+
};
|
|
120
|
+
const isFocusHeldByInactiveWindow = (widget) => {
|
|
121
|
+
const root = widget.getRoot();
|
|
122
|
+
return root instanceof Gtk.Window && !isWindowActivated(root) && isHoldingFocus(widget, root);
|
|
123
|
+
};
|
|
124
|
+
const focusResult = (widget, isPass) => {
|
|
125
|
+
if (isPass || !isFocusHeldByInactiveWindow(widget)) {
|
|
126
|
+
return stateResult(widget, "focused", isPass);
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
pass: false,
|
|
130
|
+
message: () => "expected widget to be focused: its window has given it the focus, " +
|
|
131
|
+
`but that window is not active\n${describeWidget(widget)}`,
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
const describeAttributeValue = (value) => value === null ? "unset" : JSON.stringify(value);
|
|
135
|
+
const attributeSetResult = (widget, label, actual) => {
|
|
136
|
+
const isSet = actual !== null;
|
|
137
|
+
return {
|
|
138
|
+
pass: isSet,
|
|
139
|
+
message: () => `expected widget ${negationPrefix(isSet)}to have ${label} set\n${describeWidget(widget)}`,
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
const describeReading = (expectation) => `${describeAttributeValue(expectation.actual)}${expectation.isReadingRounded ? ROUNDED_READING : ""}`;
|
|
143
|
+
const attributeValueResult = (widget, expectation) => ({
|
|
144
|
+
pass: expectation.isPass,
|
|
145
|
+
message: () => `expected widget ${negationPrefix(expectation.isPass)}to have ${expectation.label} ` +
|
|
146
|
+
`${expectation.comparison} ${describeAttributeValue(expectation.expected)}, but received ` +
|
|
147
|
+
`${describeReading(expectation)}\n${describeWidget(widget)}`,
|
|
148
|
+
});
|
|
149
|
+
const orderResult = (widget, other, position, isPass) => ({
|
|
150
|
+
pass: isPass,
|
|
151
|
+
message: () => `expected widget ${negationPrefix(isPass)}to appear ${position} ${describeWidget(other)} ` +
|
|
152
|
+
`in the widget tree\n${describeWidget(widget)}`,
|
|
153
|
+
});
|
|
154
|
+
const getTreeRoot = (widget) => {
|
|
155
|
+
let root = widget;
|
|
156
|
+
let parent = root.getParent();
|
|
157
|
+
while (parent) {
|
|
158
|
+
root = parent;
|
|
159
|
+
parent = root.getParent();
|
|
160
|
+
}
|
|
161
|
+
return root;
|
|
162
|
+
};
|
|
163
|
+
const isSeparateWidget = (first, second) => first !== second && !first.isAncestor(second) && !second.isAncestor(first);
|
|
164
|
+
const isPrecedingWidget = (root, first, second) => {
|
|
165
|
+
for (const widget of descendants(root)) {
|
|
166
|
+
if (widget === first) {
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
if (widget === second) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return false;
|
|
174
|
+
};
|
|
175
|
+
const isAppearingBefore = (first, second) => {
|
|
176
|
+
const root = getTreeRoot(first);
|
|
177
|
+
return isSeparateWidget(first, second) && root === getTreeRoot(second) && isPrecedingWidget(root, first, second);
|
|
178
|
+
};
|
|
91
179
|
const camelCase = (name) => name.replaceAll(/-([a-z])/g, (_match, letter) => letter.toUpperCase());
|
|
92
180
|
const isAsymmetricMatcher = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "asymmetricMatch") === "function";
|
|
93
181
|
const isEqualValue = (context, actual, expected) => {
|
|
@@ -206,6 +294,77 @@ function booleanStateMatcher(matcherName, stateName, read) {
|
|
|
206
294
|
return stateResult(widget, stateName, state);
|
|
207
295
|
};
|
|
208
296
|
}
|
|
297
|
+
function containmentMatcher(matcherName, isSingle, queryAll) {
|
|
298
|
+
const quantity = isSingle ? "exactly one widget" : "any widget";
|
|
299
|
+
return (received, ...args) => {
|
|
300
|
+
const widget = asWidget(received, matcherName);
|
|
301
|
+
const matches = queryAll(widget, ...args);
|
|
302
|
+
const isPass = isSingle ? matches.length === 1 : matches.length > 0;
|
|
303
|
+
return {
|
|
304
|
+
pass: isPass,
|
|
305
|
+
message: () => `expected widget ${negationPrefix(isPass)}to contain ${quantity} matching ${matcherName}, ` +
|
|
306
|
+
`but found ${String(matches.length)}\n${describeWidget(widget)}`,
|
|
307
|
+
};
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
function toHaveAccessibleState(received, state, expected) {
|
|
311
|
+
const widget = asWidget(received, "toHaveAccessibleState");
|
|
312
|
+
const actual = readAccessibleState(widget, state);
|
|
313
|
+
const label = `accessible state ${Gtk.AccessibleState[state]}`;
|
|
314
|
+
if (expected === undefined) {
|
|
315
|
+
return attributeSetResult(widget, label, actual);
|
|
316
|
+
}
|
|
317
|
+
const wanted = typeof expected === "boolean" ? Number(expected) : expected;
|
|
318
|
+
return attributeValueResult(widget, {
|
|
319
|
+
label,
|
|
320
|
+
comparison: "equal to",
|
|
321
|
+
expected: wanted,
|
|
322
|
+
actual,
|
|
323
|
+
isPass: actual === wanted,
|
|
324
|
+
isReadingRounded: false,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
const propertyLabel = (property) => `accessible property ${Gtk.AccessibleProperty[property]}`;
|
|
328
|
+
const propertyExpectation = (widget, property, expected, actual) => {
|
|
329
|
+
const label = propertyLabel(property);
|
|
330
|
+
if (typeof expected === "number" && isAccessibleNumberProperty(property)) {
|
|
331
|
+
return {
|
|
332
|
+
label,
|
|
333
|
+
comparison: `within ${String(ACCESSIBLE_NUMBER_TOLERANCE)} of`,
|
|
334
|
+
expected,
|
|
335
|
+
actual,
|
|
336
|
+
isPass: isAccessibleNumberMatch(widget, property, expected),
|
|
337
|
+
isReadingRounded: actual !== null,
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
return { label, comparison: "equal to", expected, actual, isPass: actual === expected, isReadingRounded: false };
|
|
341
|
+
};
|
|
342
|
+
function toHaveAccessibleProperty(received, property, expected) {
|
|
343
|
+
const widget = asWidget(received, "toHaveAccessibleProperty");
|
|
344
|
+
const actual = readAccessibleProperty(widget, property);
|
|
345
|
+
if (expected === undefined) {
|
|
346
|
+
return attributeSetResult(widget, propertyLabel(property), actual);
|
|
347
|
+
}
|
|
348
|
+
return attributeValueResult(widget, propertyExpectation(widget, property, expected, actual));
|
|
349
|
+
}
|
|
350
|
+
function toBePartiallyPressed(received) {
|
|
351
|
+
const widget = asWidget(received, "toBePartiallyPressed");
|
|
352
|
+
const state = readAccessibleState(widget, Gtk.AccessibleState.PRESSED);
|
|
353
|
+
if (state === null) {
|
|
354
|
+
throw notApplicable("toBePartiallyPressed", "pressed state", widget);
|
|
355
|
+
}
|
|
356
|
+
return stateResult(widget, "partially pressed", state === MIXED_TRISTATE);
|
|
357
|
+
}
|
|
358
|
+
function toAppearBefore(received, other) {
|
|
359
|
+
const widget = asWidget(received, "toAppearBefore");
|
|
360
|
+
const target = asWidget(other, "toAppearBefore");
|
|
361
|
+
return orderResult(widget, target, "before", isAppearingBefore(widget, target));
|
|
362
|
+
}
|
|
363
|
+
function toAppearAfter(received, other) {
|
|
364
|
+
const widget = asWidget(received, "toAppearAfter");
|
|
365
|
+
const target = asWidget(other, "toAppearAfter");
|
|
366
|
+
return orderResult(widget, target, "after", isAppearingBefore(target, widget));
|
|
367
|
+
}
|
|
209
368
|
function readCheckedState(widget, matcherName) {
|
|
210
369
|
const state = getWidgetCheckedState(widget);
|
|
211
370
|
if (state === null) {
|
|
@@ -228,20 +387,21 @@ function toHaveDisplayValue(received, expected) {
|
|
|
228
387
|
}
|
|
229
388
|
return displayValueMatcher(received, expected);
|
|
230
389
|
}
|
|
390
|
+
const describeValueExpectation = (expected) => expected === undefined ? "set" : `within ${String(ACCESSIBLE_NUMBER_TOLERANCE)} of ${String(expected)}`;
|
|
231
391
|
function toHaveValue(received, expected) {
|
|
232
392
|
const widget = asWidget(received, "toHaveValue");
|
|
233
393
|
if (typeof expected === "string") {
|
|
234
394
|
return displayValueMatcher(received, expected);
|
|
235
395
|
}
|
|
236
|
-
const actual =
|
|
396
|
+
const actual = getWidgetValueNow(widget);
|
|
237
397
|
if (actual === null) {
|
|
238
398
|
throw notApplicable("toHaveValue", "numeric value", widget);
|
|
239
399
|
}
|
|
240
|
-
const isPass = expected === undefined ||
|
|
400
|
+
const isPass = expected === undefined || isWidgetValueMatch(widget, "now", expected);
|
|
241
401
|
return {
|
|
242
402
|
pass: isPass,
|
|
243
|
-
message: () => `expected widget ${negationPrefix(isPass)}to have value ${
|
|
244
|
-
`but received ${String(actual)}\n${describeWidget(widget)}`,
|
|
403
|
+
message: () => `expected widget ${negationPrefix(isPass)}to have value ${describeValueExpectation(expected)}, ` +
|
|
404
|
+
`but received ${String(actual)}${ROUNDED_READING}\n${describeWidget(widget)}`,
|
|
245
405
|
};
|
|
246
406
|
}
|
|
247
407
|
function toBeDisabled(received) {
|
|
@@ -263,8 +423,8 @@ function toBeRooted(received) {
|
|
|
263
423
|
const widget = asWidget(received, "toBeRooted");
|
|
264
424
|
return stateResult(widget, "rooted in a window", isWidgetRooted(widget));
|
|
265
425
|
}
|
|
266
|
-
function
|
|
267
|
-
const widget = asWidget(received, "
|
|
426
|
+
function toBeEmptyWidget(received) {
|
|
427
|
+
const widget = asWidget(received, "toBeEmptyWidget");
|
|
268
428
|
return stateResult(widget, "empty", widget.getFirstChild() === null && getWidgetLabelText(widget) === null);
|
|
269
429
|
}
|
|
270
430
|
function toBeInvalid(received) {
|
|
@@ -279,7 +439,7 @@ function toBeValid(received) {
|
|
|
279
439
|
}
|
|
280
440
|
function toHaveFocus(received) {
|
|
281
441
|
const widget = asWidget(received, "toHaveFocus");
|
|
282
|
-
return
|
|
442
|
+
return focusResult(widget, widget.getPlatformState(Gtk.AccessiblePlatformState.FOCUSED));
|
|
283
443
|
}
|
|
284
444
|
function toHaveRole(received, expected) {
|
|
285
445
|
const widget = asWidget(received, "toHaveRole");
|
|
@@ -329,8 +489,6 @@ function toHaveObjectProperty(received, ...args) {
|
|
|
329
489
|
`"${String(name)}", but received ${JSON.stringify(actual)}`,
|
|
330
490
|
};
|
|
331
491
|
}
|
|
332
|
-
/* eslint-disable-next-line unicorn/no-this-outside-of-class --
|
|
333
|
-
expect.extend invokes matchers with the matcher state as `this` */
|
|
334
492
|
const isPass = isEqualValue(this, actual, expected);
|
|
335
493
|
return {
|
|
336
494
|
pass: isPass,
|
|
@@ -350,5 +508,5 @@ const registerMatchers = () => {
|
|
|
350
508
|
expect.extend(matchers);
|
|
351
509
|
registration.isRegistered = true;
|
|
352
510
|
};
|
|
353
|
-
export {
|
|
511
|
+
export { matchers, registerMatchers };
|
|
354
512
|
//# sourceMappingURL=matchers.js.map
|