@gtkx/testing 0.21.0 → 1.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +137 -34
- package/dist/act.d.ts +19 -0
- package/dist/act.d.ts.map +1 -0
- package/dist/act.js +56 -0
- package/dist/act.js.map +1 -0
- package/dist/bound-queries.d.ts +33 -0
- package/dist/bound-queries.d.ts.map +1 -0
- package/dist/bound-queries.js +2 -0
- package/dist/bound-queries.js.map +1 -0
- package/dist/build-queries.d.ts +16 -0
- package/dist/build-queries.d.ts.map +1 -0
- package/dist/build-queries.js +115 -0
- package/dist/build-queries.js.map +1 -0
- package/dist/cleanup-registry.d.ts +5 -0
- package/dist/cleanup-registry.d.ts.map +1 -0
- package/dist/cleanup-registry.js +21 -0
- package/dist/cleanup-registry.js.map +1 -0
- package/dist/config.d.ts +20 -52
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +17 -46
- package/dist/config.js.map +1 -1
- package/dist/editable.d.ts +8 -0
- package/dist/editable.d.ts.map +1 -0
- package/dist/editable.js +26 -0
- package/dist/editable.js.map +1 -0
- package/dist/errors.d.ts +30 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +135 -0
- package/dist/errors.js.map +1 -0
- package/dist/fire-event.d.ts +8 -25
- package/dist/fire-event.d.ts.map +1 -1
- package/dist/fire-event.js +11 -30
- package/dist/fire-event.js.map +1 -1
- package/dist/frame-sync.d.ts +4 -0
- package/dist/frame-sync.d.ts.map +1 -0
- package/dist/frame-sync.js +37 -0
- package/dist/frame-sync.js.map +1 -0
- package/dist/index.d.ts +17 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -7
- package/dist/index.js.map +1 -1
- package/dist/matchers.d.ts +59 -0
- package/dist/matchers.d.ts.map +1 -0
- package/dist/matchers.js +117 -0
- package/dist/matchers.js.map +1 -0
- package/dist/pretty-widget.d.ts +24 -26
- package/dist/pretty-widget.d.ts.map +1 -1
- package/dist/pretty-widget.js +111 -117
- package/dist/pretty-widget.js.map +1 -1
- package/dist/queries.d.ts +190 -180
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +291 -320
- package/dist/queries.js.map +1 -1
- package/dist/register-test-hooks.d.ts +2 -0
- package/dist/register-test-hooks.d.ts.map +1 -0
- package/dist/register-test-hooks.js +16 -0
- package/dist/register-test-hooks.js.map +1 -0
- package/dist/render-hook.d.ts +15 -35
- package/dist/render-hook.d.ts.map +1 -1
- package/dist/render-hook.js +9 -45
- package/dist/render-hook.js.map +1 -1
- package/dist/render.d.ts +13 -42
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +138 -121
- package/dist/render.js.map +1 -1
- package/dist/role-helpers.d.ts +19 -53
- package/dist/role-helpers.d.ts.map +1 -1
- package/dist/role-helpers.js +48 -63
- package/dist/role-helpers.js.map +1 -1
- package/dist/screen.d.ts +7 -63
- package/dist/screen.d.ts.map +1 -1
- package/dist/screen.js +24 -110
- package/dist/screen.js.map +1 -1
- package/dist/screenshot.d.ts +21 -23
- package/dist/screenshot.d.ts.map +1 -1
- package/dist/screenshot.js +98 -50
- package/dist/screenshot.js.map +1 -1
- package/dist/suggestions.d.ts +27 -0
- package/dist/suggestions.d.ts.map +1 -0
- package/dist/suggestions.js +61 -0
- package/dist/suggestions.js.map +1 -0
- package/dist/traversal.d.ts +12 -10
- package/dist/traversal.d.ts.map +1 -1
- package/dist/traversal.js +36 -15
- package/dist/traversal.js.map +1 -1
- package/dist/types.d.ts +115 -169
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/user-event/adjustment.d.ts +10 -0
- package/dist/user-event/adjustment.d.ts.map +1 -0
- package/dist/user-event/adjustment.js +35 -0
- package/dist/user-event/adjustment.js.map +1 -0
- package/dist/user-event/click.d.ts +8 -0
- package/dist/user-event/click.d.ts.map +1 -0
- package/dist/user-event/click.js +73 -0
- package/dist/user-event/click.js.map +1 -0
- package/dist/user-event/controller.d.ts +8 -0
- package/dist/user-event/controller.d.ts.map +1 -0
- package/dist/user-event/controller.js +31 -0
- package/dist/user-event/controller.js.map +1 -0
- package/dist/user-event/dispatch.d.ts +7 -0
- package/dist/user-event/dispatch.d.ts.map +1 -0
- package/dist/user-event/dispatch.js +11 -0
- package/dist/user-event/dispatch.js.map +1 -0
- package/dist/user-event/event-wrapper.d.ts +4 -0
- package/dist/user-event/event-wrapper.d.ts.map +1 -0
- package/dist/user-event/event-wrapper.js +59 -0
- package/dist/user-event/event-wrapper.js.map +1 -0
- package/dist/user-event/gesture.d.ts +35 -0
- package/dist/user-event/gesture.d.ts.map +1 -0
- package/dist/user-event/gesture.js +138 -0
- package/dist/user-event/gesture.js.map +1 -0
- package/dist/user-event/index.d.ts +51 -0
- package/dist/user-event/index.d.ts.map +1 -0
- package/dist/user-event/index.js +42 -0
- package/dist/user-event/index.js.map +1 -0
- package/dist/user-event/keyboard.d.ts +10 -0
- package/dist/user-event/keyboard.d.ts.map +1 -0
- package/dist/user-event/keyboard.js +204 -0
- package/dist/user-event/keyboard.js.map +1 -0
- package/dist/user-event/pointer.d.ts +10 -0
- package/dist/user-event/pointer.d.ts.map +1 -0
- package/dist/user-event/pointer.js +30 -0
- package/dist/user-event/pointer.js.map +1 -0
- package/dist/user-event/selection.d.ts +5 -0
- package/dist/user-event/selection.d.ts.map +1 -0
- package/dist/user-event/selection.js +105 -0
- package/dist/user-event/selection.js.map +1 -0
- package/dist/user-event/state.d.ts +7 -0
- package/dist/user-event/state.d.ts.map +1 -0
- package/dist/user-event/state.js +3 -0
- package/dist/user-event/state.js.map +1 -0
- package/dist/user-event/text.d.ts +18 -0
- package/dist/user-event/text.d.ts.map +1 -0
- package/dist/user-event/text.js +113 -0
- package/dist/user-event/text.js.map +1 -0
- package/dist/wait-for.d.ts +16 -36
- package/dist/wait-for.d.ts.map +1 -1
- package/dist/wait-for.js +74 -70
- package/dist/wait-for.js.map +1 -1
- package/dist/widget-accessible-properties.d.ts +34 -0
- package/dist/widget-accessible-properties.d.ts.map +1 -0
- package/dist/widget-accessible-properties.js +260 -0
- package/dist/widget-accessible-properties.js.map +1 -0
- package/dist/within.d.ts +10 -26
- package/dist/within.d.ts.map +1 -1
- package/dist/within.js +16 -25
- package/dist/within.js.map +1 -1
- package/package.json +23 -12
- package/src/act.ts +77 -0
- package/src/bound-queries.ts +37 -0
- package/src/build-queries.ts +226 -0
- package/src/cleanup-registry.ts +27 -0
- package/src/config.ts +35 -62
- package/src/editable.ts +37 -0
- package/src/errors.ts +191 -0
- package/src/fire-event.ts +13 -38
- package/src/frame-sync.ts +51 -0
- package/src/index.ts +58 -15
- package/src/matchers.ts +251 -0
- package/src/pretty-widget.ts +163 -130
- package/src/queries.ts +485 -396
- package/src/register-test-hooks.ts +19 -0
- package/src/render-hook.tsx +38 -45
- package/src/render.tsx +192 -155
- package/src/role-helpers.ts +65 -72
- package/src/screen.ts +26 -114
- package/src/screenshot.ts +128 -56
- package/src/suggestions.ts +106 -0
- package/src/traversal.ts +56 -22
- package/src/types.ts +144 -172
- package/src/user-event/adjustment.ts +62 -0
- package/src/user-event/click.ts +99 -0
- package/src/user-event/controller.ts +58 -0
- package/src/user-event/dispatch.ts +25 -0
- package/src/user-event/event-wrapper.ts +80 -0
- package/src/user-event/gesture.ts +239 -0
- package/src/user-event/index.ts +81 -0
- package/src/user-event/keyboard.ts +290 -0
- package/src/user-event/pointer.ts +46 -0
- package/src/user-event/selection.ts +159 -0
- package/src/user-event/state.ts +8 -0
- package/src/user-event/text.ts +172 -0
- package/src/wait-for.ts +117 -78
- package/src/widget-accessible-properties.ts +388 -0
- package/src/within.ts +29 -27
- package/dist/bind-queries.d.ts +0 -14
- package/dist/bind-queries.d.ts.map +0 -1
- package/dist/bind-queries.js +0 -29
- package/dist/bind-queries.js.map +0 -1
- package/dist/error-builder.d.ts +0 -28
- package/dist/error-builder.d.ts.map +0 -1
- package/dist/error-builder.js +0 -81
- package/dist/error-builder.js.map +0 -1
- package/dist/timing.d.ts +0 -18
- package/dist/timing.d.ts.map +0 -1
- package/dist/timing.js +0 -18
- package/dist/timing.js.map +0 -1
- package/dist/user-event.d.ts +0 -138
- package/dist/user-event.d.ts.map +0 -1
- package/dist/user-event.js +0 -411
- package/dist/user-event.js.map +0 -1
- package/dist/widget-text.d.ts +0 -69
- package/dist/widget-text.d.ts.map +0 -1
- package/dist/widget-text.js +0 -177
- package/dist/widget-text.js.map +0 -1
- package/dist/widget.d.ts +0 -3
- package/dist/widget.d.ts.map +0 -1
- package/dist/widget.js +0 -13
- package/dist/widget.js.map +0 -1
- package/src/bind-queries.ts +0 -52
- package/src/error-builder.ts +0 -102
- package/src/timing.ts +0 -17
- package/src/user-event.ts +0 -492
- package/src/widget-text.ts +0 -202
- package/src/widget.ts +0 -15
package/src/pretty-widget.ts
CHANGED
|
@@ -1,201 +1,218 @@
|
|
|
1
|
-
import * as Gtk from "@gtkx/
|
|
1
|
+
import type * as Gtk from "@gtkx/gi/gtk";
|
|
2
|
+
import { sortStringsBy } from "@gtkx/utils";
|
|
2
3
|
import { formatRole } from "./role-helpers.js";
|
|
3
|
-
import { type Container,
|
|
4
|
-
import {
|
|
4
|
+
import { type Container, roots } from "./traversal.js";
|
|
5
|
+
import { getWidgetNodeText } from "./widget-accessible-properties.js";
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
const INDENT = " ";
|
|
8
|
-
|
|
9
|
-
const debugIdMap = new WeakMap<Gtk.Widget, string>();
|
|
10
|
-
let nextDebugId = 0;
|
|
11
|
-
|
|
12
|
-
const getWidgetDebugId = (widget: Gtk.Widget): string => {
|
|
13
|
-
let id = debugIdMap.get(widget);
|
|
14
|
-
if (!id) {
|
|
15
|
-
id = String(nextDebugId++);
|
|
16
|
-
debugIdMap.set(widget, id);
|
|
17
|
-
}
|
|
18
|
-
return id;
|
|
19
|
-
};
|
|
7
|
+
type WidgetIdResolver = (widget: Gtk.Widget) => string;
|
|
20
8
|
|
|
21
9
|
/**
|
|
22
|
-
* Options
|
|
10
|
+
* Options controlling how a widget tree is rendered to a string by
|
|
11
|
+
* {@link prettyWidget} and {@link logWidget}.
|
|
23
12
|
*/
|
|
24
|
-
|
|
25
|
-
/**
|
|
13
|
+
type PrettyWidgetOptions = {
|
|
14
|
+
/** Truncates the output once it exceeds this many characters. */
|
|
26
15
|
maxLength?: number;
|
|
27
|
-
/**
|
|
16
|
+
/** Whether to apply ANSI color highlighting; defaults to the terminal capabilities. */
|
|
28
17
|
highlight?: boolean;
|
|
29
|
-
/**
|
|
30
|
-
|
|
18
|
+
/** Resolves an `id` attribute to show for each widget. */
|
|
19
|
+
getId?: WidgetIdResolver;
|
|
20
|
+
/** Stops descending past this depth, replacing deeper children with a summary line. */
|
|
21
|
+
maxDepth?: number;
|
|
31
22
|
};
|
|
32
23
|
|
|
33
|
-
type
|
|
24
|
+
type Colors = {
|
|
34
25
|
tag: (s: string) => string;
|
|
35
26
|
attr: (s: string) => string;
|
|
36
27
|
value: (s: string) => string;
|
|
37
|
-
text: (s: string) => string;
|
|
38
|
-
reset: string;
|
|
39
28
|
};
|
|
40
29
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return process.stdout?.isTTY ?? false;
|
|
30
|
+
type FormatContext = {
|
|
31
|
+
getId: WidgetIdResolver | undefined;
|
|
32
|
+
colors: Colors;
|
|
33
|
+
maxDepth: number | undefined;
|
|
46
34
|
};
|
|
47
35
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
yellow: "\x1b[33m",
|
|
51
|
-
green: "\x1b[32m",
|
|
52
|
-
reset: "\x1b[0m",
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const createColors = (enabled: boolean): HighlightColors => {
|
|
56
|
-
if (!enabled) {
|
|
57
|
-
const identity = (s: string): string => s;
|
|
58
|
-
return { tag: identity, attr: identity, value: identity, text: identity, reset: "" };
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
tag: (s) => `${ansi.cyan}${s}${ansi.reset}`,
|
|
62
|
-
attr: (s) => `${ansi.yellow}${s}${ansi.reset}`,
|
|
63
|
-
value: (s) => `${ansi.green}${s}${ansi.reset}`,
|
|
64
|
-
text: (s) => s,
|
|
65
|
-
reset: ansi.reset,
|
|
66
|
-
};
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const formatTagName = (widget: Gtk.Widget): string => {
|
|
70
|
-
return widget.constructor.name;
|
|
71
|
-
};
|
|
36
|
+
const DEFAULT_MAX_LENGTH = 7000;
|
|
37
|
+
const INDENT = " ";
|
|
72
38
|
|
|
73
|
-
const
|
|
74
|
-
|
|
39
|
+
const ansi = {
|
|
40
|
+
cyan: "\u{1B}[36m",
|
|
41
|
+
yellow: "\u{1B}[33m",
|
|
42
|
+
green: "\u{1B}[32m",
|
|
43
|
+
reset: "\u{1B}[0m",
|
|
75
44
|
};
|
|
76
45
|
|
|
77
|
-
const
|
|
46
|
+
const buildAttrs = (widget: Gtk.Widget, getId: WidgetIdResolver | undefined): [string, string][] => {
|
|
78
47
|
const attrs: [string, string][] = [];
|
|
79
48
|
|
|
80
|
-
if (
|
|
81
|
-
attrs.push(["id",
|
|
49
|
+
if (getId) {
|
|
50
|
+
attrs.push(["id", getId(widget)]);
|
|
82
51
|
}
|
|
83
52
|
|
|
84
53
|
const name = widget.getName();
|
|
54
|
+
|
|
85
55
|
if (name) {
|
|
86
56
|
attrs.push(["name", name]);
|
|
87
57
|
}
|
|
88
58
|
|
|
89
|
-
|
|
90
|
-
if (role !== undefined) {
|
|
91
|
-
attrs.push(["role", formatRole(role)]);
|
|
92
|
-
}
|
|
59
|
+
attrs.push(["role", formatRole(widget.getAccessibleRole())]);
|
|
93
60
|
|
|
94
61
|
if (!widget.getSensitive()) {
|
|
95
|
-
attrs.push(["
|
|
62
|
+
attrs.push(["accessible-disabled", "true"]);
|
|
96
63
|
}
|
|
97
64
|
|
|
98
65
|
if (!widget.getVisible()) {
|
|
99
|
-
attrs.push(["
|
|
66
|
+
attrs.push(["accessible-hidden", "true"]);
|
|
100
67
|
}
|
|
101
68
|
|
|
102
|
-
|
|
69
|
+
const idAttrs = attrs.filter(([key]) => key === "id");
|
|
70
|
+
|
|
71
|
+
const otherAttrs = sortStringsBy(
|
|
72
|
+
attrs.filter(([key]) => key !== "id"),
|
|
73
|
+
([key]) => key,
|
|
74
|
+
);
|
|
103
75
|
|
|
104
|
-
return
|
|
105
|
-
.sort(([a], [b]) => {
|
|
106
|
-
if (a === "id") return -1;
|
|
107
|
-
if (b === "id") return 1;
|
|
108
|
-
return a.localeCompare(b);
|
|
109
|
-
})
|
|
110
|
-
.map(([key, value]) => ` ${colors.attr(key)}=${colors.value(`"${escapeAttrValue(value)}"`)}`)
|
|
111
|
-
.join("");
|
|
76
|
+
return [...idAttrs, ...otherAttrs];
|
|
112
77
|
};
|
|
113
78
|
|
|
114
|
-
const
|
|
115
|
-
|
|
79
|
+
const shouldHighlight = (): boolean => {
|
|
80
|
+
if (typeof process === "undefined") {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (process.env.COLORS === "false" || process.env.NO_COLOR) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (process.env.COLORS === "true" || process.env.FORCE_COLOR) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return process.stdout.isTTY;
|
|
116
93
|
};
|
|
117
94
|
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
95
|
+
const createColors = (isEnabled: boolean): Colors => {
|
|
96
|
+
if (!isEnabled) {
|
|
97
|
+
const identity = (s: string): string => s;
|
|
98
|
+
|
|
99
|
+
return { tag: identity, attr: identity, value: identity };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
tag: (s) => `${ansi.cyan}${s}${ansi.reset}`,
|
|
104
|
+
attr: (s) => `${ansi.yellow}${s}${ansi.reset}`,
|
|
105
|
+
value: (s) => `${ansi.green}${s}${ansi.reset}`,
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const escapeAttrValue = (value: string): string => value.replaceAll('"', """);
|
|
110
|
+
|
|
111
|
+
const formatAttr = (key: string, value: string, colors: Colors): string => {
|
|
112
|
+
const quoted = `"${escapeAttrValue(value)}"`;
|
|
113
|
+
|
|
114
|
+
return ` ${colors.attr(key)}=${colors.value(quoted)}`;
|
|
115
|
+
};
|
|
124
116
|
|
|
117
|
+
const formatAttrs = (attrs: [string, string][], colors: Colors): string =>
|
|
118
|
+
attrs.map(([key, value]) => formatAttr(key, value, colors)).join("");
|
|
119
|
+
|
|
120
|
+
const countChildren = (widget: Gtk.Widget): number => {
|
|
121
|
+
let count = 0;
|
|
125
122
|
let child = widget.getFirstChild();
|
|
123
|
+
|
|
126
124
|
while (child) {
|
|
127
|
-
|
|
125
|
+
count += 1;
|
|
128
126
|
child = child.getNextSibling();
|
|
129
127
|
}
|
|
130
128
|
|
|
131
|
-
|
|
129
|
+
return count;
|
|
130
|
+
};
|
|
132
131
|
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
const formatHiddenChildrenLine = (widget: Gtk.Widget, depth: number, ctx: FormatContext): string => {
|
|
133
|
+
const { getId, colors } = ctx;
|
|
134
|
+
const indent = INDENT.repeat(depth);
|
|
135
|
+
const count = countChildren(widget);
|
|
136
|
+
const hint = getId ? ` (pass rootId="${getId(widget)}" or raise maxDepth to expand)` : "";
|
|
137
|
+
const plural = count === 1 ? "" : "s";
|
|
138
|
+
const summary = `… ${String(count)} child widget${plural} hidden${hint}`;
|
|
139
|
+
|
|
140
|
+
return `${indent}${INDENT}${colors.tag(summary)}\n`;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const formatChildren = (widget: Gtk.Widget, depth: number, ctx: FormatContext): string => {
|
|
144
|
+
let output = "";
|
|
145
|
+
let child = widget.getFirstChild();
|
|
146
|
+
|
|
147
|
+
while (child) {
|
|
148
|
+
output += formatWidget(child, depth + 1, ctx);
|
|
149
|
+
child = child.getNextSibling();
|
|
135
150
|
}
|
|
136
151
|
|
|
137
|
-
|
|
152
|
+
return output;
|
|
153
|
+
};
|
|
138
154
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
155
|
+
const formatWidget = (widget: Gtk.Widget, depth: number, ctx: FormatContext): string => {
|
|
156
|
+
const { getId, colors, maxDepth } = ctx;
|
|
157
|
+
const indent = INDENT.repeat(depth);
|
|
158
|
+
const tag = widget.constructor.name;
|
|
159
|
+
const attrs = formatAttrs(buildAttrs(widget, getId), colors);
|
|
160
|
+
const openTag = `${colors.tag("<")}${colors.tag(tag)}${attrs}${colors.tag(">")}`;
|
|
161
|
+
const closeTag = `${colors.tag("</")}${colors.tag(tag)}${colors.tag(">")}`;
|
|
162
|
+
const text = getWidgetNodeText(widget);
|
|
163
|
+
const firstChild = widget.getFirstChild();
|
|
164
|
+
|
|
165
|
+
if (!text && !firstChild) {
|
|
166
|
+
return `${indent}${openTag}\n`;
|
|
142
167
|
}
|
|
143
168
|
|
|
144
|
-
let
|
|
169
|
+
let output = `${indent}${openTag}\n`;
|
|
170
|
+
|
|
145
171
|
if (text) {
|
|
146
|
-
|
|
172
|
+
output += `${indent}${INDENT}${text}\n`;
|
|
147
173
|
}
|
|
148
|
-
|
|
149
|
-
|
|
174
|
+
|
|
175
|
+
if (firstChild && maxDepth !== undefined && depth >= maxDepth) {
|
|
176
|
+
output += formatHiddenChildrenLine(widget, depth, ctx);
|
|
177
|
+
output += `${indent}${closeTag}\n`;
|
|
178
|
+
|
|
179
|
+
return output;
|
|
150
180
|
}
|
|
151
|
-
result += `${indent}${closeTag}\n`;
|
|
152
181
|
|
|
153
|
-
|
|
182
|
+
output += formatChildren(widget, depth, ctx);
|
|
183
|
+
output += `${indent}${closeTag}\n`;
|
|
184
|
+
|
|
185
|
+
return output;
|
|
154
186
|
};
|
|
155
187
|
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
return printWidget(container, colors, 0, includeIds);
|
|
188
|
+
const resolveMaxLength = (options: PrettyWidgetOptions): number => {
|
|
189
|
+
const envLimit = process.env.DEBUG_PRINT_LIMIT ? Number(process.env.DEBUG_PRINT_LIMIT) : DEFAULT_MAX_LENGTH;
|
|
190
|
+
|
|
191
|
+
return options.maxLength ?? envLimit;
|
|
162
192
|
};
|
|
163
193
|
|
|
164
194
|
/**
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
* Renders the widget hierarchy in an HTML-like format with accessibility
|
|
168
|
-
* attributes like role, name, and text content.
|
|
169
|
-
*
|
|
170
|
-
* @param container - The container widget or application to format
|
|
171
|
-
* @param options - Formatting options for length and highlighting
|
|
172
|
-
* @returns Formatted string representation of the widget tree
|
|
195
|
+
* Renders a widget tree as an indented, HTML-like string showing each widget's
|
|
196
|
+
* tag, accessible attributes, and text content.
|
|
173
197
|
*
|
|
174
|
-
* @
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
* console.log(prettyWidget(application));
|
|
179
|
-
* // Output:
|
|
180
|
-
* // <GtkApplicationWindow role="window">
|
|
181
|
-
* // <GtkButton role="button">
|
|
182
|
-
* // Click me
|
|
183
|
-
* // </GtkButton>
|
|
184
|
-
* // </GtkApplicationWindow>
|
|
185
|
-
* ```
|
|
198
|
+
* @param container The scope whose widget tree is formatted.
|
|
199
|
+
* @param options Formatting options such as truncation length and highlighting.
|
|
200
|
+
* @returns The formatted representation of the tree.
|
|
186
201
|
*/
|
|
187
|
-
|
|
188
|
-
const
|
|
189
|
-
const maxLength = options.maxLength ?? envLimit;
|
|
190
|
-
const highlight = options.highlight ?? shouldHighlight();
|
|
191
|
-
const includeIds = options.includeIds ?? false;
|
|
202
|
+
const prettyWidget = (container: Container, options: PrettyWidgetOptions = {}): string => {
|
|
203
|
+
const maxLength = resolveMaxLength(options);
|
|
192
204
|
|
|
193
205
|
if (maxLength === 0) {
|
|
194
206
|
return "";
|
|
195
207
|
}
|
|
196
208
|
|
|
197
|
-
const
|
|
198
|
-
const
|
|
209
|
+
const isHighlight = options.highlight ?? shouldHighlight();
|
|
210
|
+
const colors = createColors(isHighlight);
|
|
211
|
+
let output = "";
|
|
212
|
+
|
|
213
|
+
for (const root of roots(container)) {
|
|
214
|
+
output += formatWidget(root, 0, { getId: options.getId, colors, maxDepth: options.maxDepth });
|
|
215
|
+
}
|
|
199
216
|
|
|
200
217
|
if (output.length > maxLength) {
|
|
201
218
|
return `${output.slice(0, maxLength)}...`;
|
|
@@ -203,3 +220,19 @@ export const prettyWidget = (container: Container, options: PrettyWidgetOptions
|
|
|
203
220
|
|
|
204
221
|
return output.trimEnd();
|
|
205
222
|
};
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Prints one or more widget trees to the console using {@link prettyWidget}.
|
|
226
|
+
*
|
|
227
|
+
* @param container A single scope or an array of scopes to format and print.
|
|
228
|
+
* @param options Formatting options passed through to {@link prettyWidget}.
|
|
229
|
+
*/
|
|
230
|
+
const logWidget = (container: Container | Container[], options?: PrettyWidgetOptions): void => {
|
|
231
|
+
const containers: Container[] = Array.isArray(container) ? container : [container];
|
|
232
|
+
|
|
233
|
+
for (const target of containers) {
|
|
234
|
+
console.log(prettyWidget(target, options));
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
export { prettyWidget, logWidget, type PrettyWidgetOptions };
|