@testmuai/playwright-bindings 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +51 -0
  3. package/dist/capability.d.ts +60 -0
  4. package/dist/capability.d.ts.map +1 -0
  5. package/dist/capability.js +212 -0
  6. package/dist/capability.js.map +1 -0
  7. package/dist/config.d.ts +12 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +16 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/configure.d.ts +30 -0
  12. package/dist/configure.d.ts.map +1 -0
  13. package/dist/configure.js +53 -0
  14. package/dist/configure.js.map +1 -0
  15. package/dist/errors.d.ts +4 -0
  16. package/dist/errors.d.ts.map +1 -0
  17. package/dist/errors.js +7 -0
  18. package/dist/errors.js.map +1 -0
  19. package/dist/healPatch.d.ts +11 -0
  20. package/dist/healPatch.d.ts.map +1 -0
  21. package/dist/healPatch.js +82 -0
  22. package/dist/healPatch.js.map +1 -0
  23. package/dist/helpers/assertion.d.ts +23 -0
  24. package/dist/helpers/assertion.d.ts.map +1 -0
  25. package/dist/helpers/assertion.js +87 -0
  26. package/dist/helpers/assertion.js.map +1 -0
  27. package/dist/helpers/drag.d.ts +3 -0
  28. package/dist/helpers/drag.d.ts.map +1 -0
  29. package/dist/helpers/drag.js +7 -0
  30. package/dist/helpers/drag.js.map +1 -0
  31. package/dist/helpers/executeApi.d.ts +34 -0
  32. package/dist/helpers/executeApi.d.ts.map +1 -0
  33. package/dist/helpers/executeApi.js +83 -0
  34. package/dist/helpers/executeApi.js.map +1 -0
  35. package/dist/helpers/executeDb.d.ts +9 -0
  36. package/dist/helpers/executeDb.d.ts.map +1 -0
  37. package/dist/helpers/executeDb.js +23 -0
  38. package/dist/helpers/executeDb.js.map +1 -0
  39. package/dist/helpers/executeJs.d.ts +16 -0
  40. package/dist/helpers/executeJs.d.ts.map +1 -0
  41. package/dist/helpers/executeJs.js +58 -0
  42. package/dist/helpers/executeJs.js.map +1 -0
  43. package/dist/helpers/kaneCli.d.ts +2 -0
  44. package/dist/helpers/kaneCli.d.ts.map +1 -0
  45. package/dist/helpers/kaneCli.js +5 -0
  46. package/dist/helpers/kaneCli.js.map +1 -0
  47. package/dist/helpers/math.d.ts +6 -0
  48. package/dist/helpers/math.d.ts.map +1 -0
  49. package/dist/helpers/math.js +70 -0
  50. package/dist/helpers/math.js.map +1 -0
  51. package/dist/helpers/network.d.ts +23 -0
  52. package/dist/helpers/network.d.ts.map +1 -0
  53. package/dist/helpers/network.js +67 -0
  54. package/dist/helpers/network.js.map +1 -0
  55. package/dist/helpers/smartui.d.ts +3 -0
  56. package/dist/helpers/smartui.d.ts.map +1 -0
  57. package/dist/helpers/smartui.js +11 -0
  58. package/dist/helpers/smartui.js.map +1 -0
  59. package/dist/helpers/tabs.d.ts +3 -0
  60. package/dist/helpers/tabs.d.ts.map +1 -0
  61. package/dist/helpers/tabs.js +13 -0
  62. package/dist/helpers/tabs.js.map +1 -0
  63. package/dist/helpers/vision.d.ts +48 -0
  64. package/dist/helpers/vision.d.ts.map +1 -0
  65. package/dist/helpers/vision.js +169 -0
  66. package/dist/helpers/vision.js.map +1 -0
  67. package/dist/helpers/wait.d.ts +3 -0
  68. package/dist/helpers/wait.d.ts.map +1 -0
  69. package/dist/helpers/wait.js +21 -0
  70. package/dist/helpers/wait.js.map +1 -0
  71. package/dist/http.d.ts +12 -0
  72. package/dist/http.d.ts.map +1 -0
  73. package/dist/http.js +29 -0
  74. package/dist/http.js.map +1 -0
  75. package/dist/index.d.ts +56 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +34 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/log.d.ts +22 -0
  80. package/dist/log.d.ts.map +1 -0
  81. package/dist/log.js +43 -0
  82. package/dist/log.js.map +1 -0
  83. package/dist/reporters/index.d.ts +10 -0
  84. package/dist/reporters/index.d.ts.map +1 -0
  85. package/dist/reporters/index.js +7 -0
  86. package/dist/reporters/index.js.map +1 -0
  87. package/dist/reporters/local.d.ts +11 -0
  88. package/dist/reporters/local.d.ts.map +1 -0
  89. package/dist/reporters/local.js +29 -0
  90. package/dist/reporters/local.js.map +1 -0
  91. package/dist/reporters/lt.d.ts +15 -0
  92. package/dist/reporters/lt.d.ts.map +1 -0
  93. package/dist/reporters/lt.js +48 -0
  94. package/dist/reporters/lt.js.map +1 -0
  95. package/dist/reporters/null.d.ts +10 -0
  96. package/dist/reporters/null.d.ts.map +1 -0
  97. package/dist/reporters/null.js +9 -0
  98. package/dist/reporters/null.js.map +1 -0
  99. package/dist/session.d.ts +2 -0
  100. package/dist/session.d.ts.map +1 -0
  101. package/dist/session.js +61 -0
  102. package/dist/session.js.map +1 -0
  103. package/dist/step.d.ts +14 -0
  104. package/dist/step.d.ts.map +1 -0
  105. package/dist/step.js +36 -0
  106. package/dist/step.js.map +1 -0
  107. package/dist/test.d.ts +10 -0
  108. package/dist/test.d.ts.map +1 -0
  109. package/dist/test.js +5 -0
  110. package/dist/test.js.map +1 -0
  111. package/dist/testConfig.d.ts +11 -0
  112. package/dist/testConfig.d.ts.map +1 -0
  113. package/dist/testConfig.js +82 -0
  114. package/dist/testConfig.js.map +1 -0
  115. package/dist/vars.d.ts +61 -0
  116. package/dist/vars.d.ts.map +1 -0
  117. package/dist/vars.js +656 -0
  118. package/dist/vars.js.map +1 -0
  119. package/package.json +63 -0
@@ -0,0 +1,13 @@
1
+ export async function switchTab(context, index) {
2
+ let pages = context.pages();
3
+ if (index >= pages.length) {
4
+ await context.waitForEvent('page', { timeout: 5000 }).catch(() => null);
5
+ pages = context.pages();
6
+ }
7
+ const target = pages[index];
8
+ if (!target)
9
+ throw new Error(`Tab index ${index} does not exist (have ${pages.length})`);
10
+ await target.bringToFront();
11
+ return target;
12
+ }
13
+ //# sourceMappingURL=tabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../src/helpers/tabs.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAuB,EAAE,KAAa;IACpE,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAC5B,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QAC1B,MAAM,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACxE,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5B,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,aAAa,KAAK,yBAAyB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IACzF,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;IAC5B,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,48 @@
1
+ import type { Page } from 'playwright';
2
+ export interface VisionCoordinates {
3
+ x: number;
4
+ y: number;
5
+ }
6
+ /**
7
+ * Get coordinates for a described element via vision API.
8
+ *
9
+ * When smart is ON: always uses vision API. No fallback to (x, y) — if the
10
+ * API can't find the element or errors, raises instead of silently using
11
+ * stale coordinates that may click the wrong thing. Matches Python
12
+ * `get_vision_coordinates` behavior (commit 13d9f6b).
13
+ *
14
+ * When smart is OFF: returns the passed-in coordinates directly, or null
15
+ * if neither provided.
16
+ */
17
+ export declare function getVisionCoordinates(page: Page, description: string, actionType: string, x?: number, y?: number): Promise<VisionCoordinates | null>;
18
+ /**
19
+ * Extract a value from the page using a screenshot + analyzer API (visual mode).
20
+ *
21
+ * Smart-gated: returns null when smart is OFF.
22
+ */
23
+ export declare function visionQuery(page: Page, description: string, returnType?: string): Promise<string | null>;
24
+ /**
25
+ * Extract a value from a DOM element using analyzer API (textual/DOM mode).
26
+ *
27
+ * NOTE: Python does a 5-step CDP flow (DOM.enable → Accessibility.getFullAXTree →
28
+ * identify via LLM → Runtime.callFunctionOn snapshot → extract via LLM).
29
+ * For v0.1, simplified to a single API call with mode='textual_extract'.
30
+ * Full CDP port deferred.
31
+ *
32
+ * Smart-gated: returns null when smart is OFF.
33
+ */
34
+ export declare function textualQuery(page: Page, description: string, returnType?: string): Promise<string | null>;
35
+ /**
36
+ * Poll the vision wait API until the described condition is met.
37
+ *
38
+ * Smart-gated: returns false immediately when smart is OFF.
39
+ * Returns true when condition met, false when max retries exhausted.
40
+ */
41
+ export declare function visionWait(page: Page, description: string, timeoutMs?: number): Promise<boolean>;
42
+ /**
43
+ * Get vision coordinates and execute click or scroll at those coordinates.
44
+ *
45
+ * Smart-gated via getVisionCoordinates: no-ops when smart is OFF or element not found.
46
+ */
47
+ export declare function visionAction(page: Page, description: string, actionType: string, direction?: string, amount?: number): Promise<void>;
48
+ //# sourceMappingURL=vision.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vision.d.ts","sourceRoot":"","sources":["../../src/helpers/vision.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAOvC,MAAM,WAAW,iBAAiB;IAAG,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;CAAE;AAE5D;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,CAAC,CAAC,EAAE,MAAM,EACV,CAAC,CAAC,EAAE,MAAM,GACT,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CA0BnC;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAsB9G;AAED;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAsB/G;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAyBtG;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,SAAS,SAAS,EAClB,MAAM,SAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAaf"}
@@ -0,0 +1,169 @@
1
+ import { config } from '../config.js';
2
+ import { fetchWithAuth } from '../http.js';
3
+ import { log, preview } from '../log.js';
4
+ const AI_HOST = () => process.env['TESTMU_AI_API_HOST'] ?? 'http://localhost:8000';
5
+ /**
6
+ * Get coordinates for a described element via vision API.
7
+ *
8
+ * When smart is ON: always uses vision API. No fallback to (x, y) — if the
9
+ * API can't find the element or errors, raises instead of silently using
10
+ * stale coordinates that may click the wrong thing. Matches Python
11
+ * `get_vision_coordinates` behavior (commit 13d9f6b).
12
+ *
13
+ * When smart is OFF: returns the passed-in coordinates directly, or null
14
+ * if neither provided.
15
+ */
16
+ export async function getVisionCoordinates(page, description, actionType, x, y) {
17
+ if (!config.current.smart) {
18
+ if (x !== undefined && y !== undefined)
19
+ return { x, y };
20
+ return null;
21
+ }
22
+ log.helper(`[get_vision_coordinates] query=${preview(description, 60)}`);
23
+ const shot = await page.screenshot();
24
+ const viewport = page.viewportSize?.() ?? { width: 1920, height: 1080 };
25
+ const resp = await fetchWithAuth(`${AI_HOST()}/api/v1/vision/coordinates`, {
26
+ method: 'POST',
27
+ headers: { 'content-type': 'application/json' },
28
+ body: JSON.stringify({
29
+ screenshot_b64: shot.toString('base64'),
30
+ action_instruction: description,
31
+ action_type: actionType,
32
+ width: viewport.width,
33
+ height: viewport.height,
34
+ }),
35
+ });
36
+ if (!resp.ok)
37
+ throw new Error(`Vision API error: ${resp.status}`);
38
+ const body = (await resp.json());
39
+ if (!body.found || body.x === undefined || body.y === undefined) {
40
+ throw new Error(`Vision API: element not found for query=${JSON.stringify(description)}`);
41
+ }
42
+ log.helper(`[get_vision_coordinates] found (${body.x}, ${body.y})`);
43
+ return { x: body.x, y: body.y };
44
+ }
45
+ /**
46
+ * Extract a value from the page using a screenshot + analyzer API (visual mode).
47
+ *
48
+ * Smart-gated: returns null when smart is OFF.
49
+ */
50
+ export async function visionQuery(page, description, returnType) {
51
+ if (!config.current.smart)
52
+ return null;
53
+ log.helper(`[vision_query] query=${preview(description, 80)}`);
54
+ const shot = (await page.screenshot()).toString('base64');
55
+ try {
56
+ const resp = await fetchWithAuth(`${AI_HOST()}/api/v1/analyzer`, {
57
+ method: 'POST',
58
+ headers: { 'content-type': 'application/json' },
59
+ body: JSON.stringify({
60
+ type: 'visual',
61
+ query: description,
62
+ screenshot_b64: shot,
63
+ return_type: returnType ?? 'string',
64
+ }),
65
+ });
66
+ if (!resp.ok)
67
+ return null;
68
+ const body = (await resp.json());
69
+ log.helper(`[vision_query] result=${preview(body.extracted_value ?? null, 120)}`);
70
+ return body.extracted_value ?? null;
71
+ }
72
+ catch {
73
+ return null;
74
+ }
75
+ }
76
+ /**
77
+ * Extract a value from a DOM element using analyzer API (textual/DOM mode).
78
+ *
79
+ * NOTE: Python does a 5-step CDP flow (DOM.enable → Accessibility.getFullAXTree →
80
+ * identify via LLM → Runtime.callFunctionOn snapshot → extract via LLM).
81
+ * For v0.1, simplified to a single API call with mode='textual_extract'.
82
+ * Full CDP port deferred.
83
+ *
84
+ * Smart-gated: returns null when smart is OFF.
85
+ */
86
+ export async function textualQuery(page, description, returnType) {
87
+ if (!config.current.smart)
88
+ return null;
89
+ log.helper(`[textual_query] query=${preview(description, 80)}`);
90
+ const shot = (await page.screenshot()).toString('base64');
91
+ try {
92
+ const resp = await fetchWithAuth(`${AI_HOST()}/api/v1/analyzer`, {
93
+ method: 'POST',
94
+ headers: { 'content-type': 'application/json' },
95
+ body: JSON.stringify({
96
+ type: 'dom',
97
+ query: description,
98
+ screenshot_b64: shot,
99
+ return_type: returnType ?? 'string',
100
+ }),
101
+ });
102
+ if (!resp.ok)
103
+ return null;
104
+ const body = (await resp.json());
105
+ log.helper(`[textual_query] result=${preview(body.extracted_value ?? null, 120)}`);
106
+ return body.extracted_value ?? null;
107
+ }
108
+ catch {
109
+ return null;
110
+ }
111
+ }
112
+ /**
113
+ * Poll the vision wait API until the described condition is met.
114
+ *
115
+ * Smart-gated: returns false immediately when smart is OFF.
116
+ * Returns true when condition met, false when max retries exhausted.
117
+ */
118
+ export async function visionWait(page, description, timeoutMs = 30_000) {
119
+ if (!config.current.smart)
120
+ return false;
121
+ log.helper(`[vision_wait] query=${preview(description, 80)}`);
122
+ const retries = 5;
123
+ const interval = Math.max(1000, Math.floor(timeoutMs / retries));
124
+ for (let i = 0; i < retries; i++) {
125
+ const shot = (await page.screenshot()).toString('base64');
126
+ try {
127
+ const resp = await fetchWithAuth(`${AI_HOST()}/api/v1/wait/check`, {
128
+ method: 'POST',
129
+ headers: { 'content-type': 'application/json' },
130
+ body: JSON.stringify({ screenshot_b64: shot, query: description }),
131
+ });
132
+ if (resp.ok) {
133
+ const body = (await resp.json());
134
+ log.helper(`[vision_wait] attempt ${i + 1}/${retries} waiting=${body.waiting}`);
135
+ if (body.waiting === false)
136
+ return true;
137
+ }
138
+ }
139
+ catch {
140
+ // continue polling on transient error
141
+ }
142
+ if (i < retries - 1)
143
+ await new Promise(r => setTimeout(r, interval));
144
+ }
145
+ log.helper(`[vision_wait] max retries exhausted, continuing`);
146
+ return false;
147
+ }
148
+ /**
149
+ * Get vision coordinates and execute click or scroll at those coordinates.
150
+ *
151
+ * Smart-gated via getVisionCoordinates: no-ops when smart is OFF or element not found.
152
+ */
153
+ export async function visionAction(page, description, actionType, direction = 'down', amount = 300) {
154
+ log.helper(`[vision_action] action=${actionType} query=${preview(description, 60)}`);
155
+ const coords = await getVisionCoordinates(page, description, actionType);
156
+ if (!coords)
157
+ return;
158
+ log.helper(`[vision_action] executing ${actionType} at (${coords.x}, ${coords.y})`);
159
+ if (actionType === 'click') {
160
+ await page.mouse.click(coords.x, coords.y);
161
+ }
162
+ else if (actionType === 'scroll') {
163
+ const dx = direction === 'left' ? -amount : direction === 'right' ? amount : 0;
164
+ const dy = direction === 'up' ? -amount : direction === 'down' ? amount : 0;
165
+ await page.mouse.move(coords.x, coords.y);
166
+ await page.mouse.wheel(dx, dy);
167
+ }
168
+ }
169
+ //# sourceMappingURL=vision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vision.js","sourceRoot":"","sources":["../../src/helpers/vision.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,OAAO,GAAG,GAAW,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,uBAAuB,CAAC;AAI3F;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAU,EACV,WAAmB,EACnB,UAAkB,EAClB,CAAU,EACV,CAAU;IAEV,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS;YAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QACxD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,GAAG,CAAC,MAAM,CAAC,kCAAkC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;IACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACxE,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,GAAG,OAAO,EAAE,4BAA4B,EAAE;QACzE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,cAAc,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACvC,kBAAkB,EAAE,WAAW;YAC/B,WAAW,EAAE,UAAU;YACvB,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,MAAM,EAAE,QAAQ,CAAC,MAAM;SACxB,CAAC;KACH,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAClE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAgD,CAAC;IAChF,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,SAAS,IAAI,IAAI,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,2CAA2C,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,GAAG,CAAC,MAAM,CAAC,mCAAmC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACpE,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAU,EAAE,WAAmB,EAAE,UAAmB;IACpF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACvC,GAAG,CAAC,MAAM,CAAC,wBAAwB,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC1D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,GAAG,OAAO,EAAE,kBAAkB,EAAE;YAC/D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,WAAW;gBAClB,cAAc,EAAE,IAAI;gBACpB,WAAW,EAAE,UAAU,IAAI,QAAQ;aACpC,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAC1B,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAiC,CAAC;QACjE,GAAG,CAAC,MAAM,CAAC,yBAAyB,OAAO,CAAC,IAAI,CAAC,eAAe,IAAI,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAU,EAAE,WAAmB,EAAE,UAAmB;IACrF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACvC,GAAG,CAAC,MAAM,CAAC,yBAAyB,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC1D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,GAAG,OAAO,EAAE,kBAAkB,EAAE;YAC/D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,IAAI,EAAE,KAAK;gBACX,KAAK,EAAE,WAAW;gBAClB,cAAc,EAAE,IAAI;gBACpB,WAAW,EAAE,UAAU,IAAI,QAAQ;aACpC,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAC1B,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAiC,CAAC;QACjE,GAAG,CAAC,MAAM,CAAC,0BAA0B,OAAO,CAAC,IAAI,CAAC,eAAe,IAAI,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACnF,OAAO,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAU,EAAE,WAAmB,EAAE,SAAS,GAAG,MAAM;IAClF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACxC,GAAG,CAAC,MAAM,CAAC,uBAAuB,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,CAAC,CAAC;IAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC;IACjE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC1D,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,GAAG,OAAO,EAAE,oBAAoB,EAAE;gBACjE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;aACnE,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAA0B,CAAC;gBAC1D,GAAG,CAAC,MAAM,CAAC,yBAAyB,CAAC,GAAG,CAAC,IAAI,OAAO,YAAY,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;gBAChF,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK;oBAAE,OAAO,IAAI,CAAC;YAC1C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,sCAAsC;QACxC,CAAC;QACD,IAAI,CAAC,GAAG,OAAO,GAAG,CAAC;YAAE,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7E,CAAC;IACD,GAAG,CAAC,MAAM,CAAC,iDAAiD,CAAC,CAAC;IAC9D,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAU,EACV,WAAmB,EACnB,UAAkB,EAClB,SAAS,GAAG,MAAM,EAClB,MAAM,GAAG,GAAG;IAEZ,GAAG,CAAC,MAAM,CAAC,0BAA0B,UAAU,UAAU,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;IACzE,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,GAAG,CAAC,MAAM,CAAC,6BAA6B,UAAU,QAAQ,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;IACpF,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QAC3B,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;SAAM,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,EAAE,GAAG,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,MAAM,EAAE,GAAG,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5E,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACjC,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Page } from 'playwright';
2
+ export declare function checkUntilCondition(page: Page, condition: string): Promise<boolean>;
3
+ //# sourceMappingURL=wait.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait.d.ts","sourceRoot":"","sources":["../../src/helpers/wait.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAOvC,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAczF"}
@@ -0,0 +1,21 @@
1
+ import { config } from '../config.js';
2
+ import { fetchWithAuth } from '../http.js';
3
+ import { log, preview } from '../log.js';
4
+ const AI_HOST = () => process.env['TESTMU_AI_API_HOST'] ?? 'http://localhost:8000';
5
+ export async function checkUntilCondition(page, condition) {
6
+ if (!config.current.smart) {
7
+ log.helper(`[check_until_condition] smart is OFF — returning False (condition skipped)`);
8
+ return false;
9
+ }
10
+ log.helper(`[check_until_condition] condition=${preview(condition, 80)}`);
11
+ const shot = (await page.screenshot()).toString('base64');
12
+ const resp = await fetchWithAuth(`${AI_HOST()}/api/v1/wait/check`, {
13
+ method: 'POST', headers: { 'content-type': 'application/json' },
14
+ body: JSON.stringify({ screenshot_b64: shot, query: condition }),
15
+ });
16
+ if (!resp.ok)
17
+ return false;
18
+ const body = (await resp.json());
19
+ return body.waiting === false;
20
+ }
21
+ //# sourceMappingURL=wait.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait.js","sourceRoot":"","sources":["../../src/helpers/wait.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,OAAO,GAAG,GAAW,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,uBAAuB,CAAC;AAE3F,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAU,EAAE,SAAiB;IACrE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC1B,GAAG,CAAC,MAAM,CAAC,4EAA4E,CAAC,CAAC;QACzF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,GAAG,CAAC,MAAM,CAAC,qCAAqC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAC1E,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,GAAG,OAAO,EAAE,oBAAoB,EAAE;QACjE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/D,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;KACjE,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IAC3B,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAA0B,CAAC;IAC1D,OAAO,IAAI,CAAC,OAAO,KAAK,KAAK,CAAC;AAChC,CAAC"}
package/dist/http.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Shared fetch wrapper with LT Basic auth + session tracking headers.
3
+ *
4
+ * All ATMS/vision/automind HTTP calls go through fetchWithAuth.
5
+ * - Adds Authorization: Basic base64(LT_USERNAME:LT_ACCESS_KEY) when env vars present.
6
+ * - Adds x-session-id when TESTMUAI_SESSION_ID is set.
7
+ * - Adds x-source (defaults to "local"; forge sets TESTMUAI_SOURCE=hyperexecute
8
+ * in all cloud YAML paths).
9
+ */
10
+ export declare function ltAuthHeader(): string | null;
11
+ export declare function fetchWithAuth(url: string, init?: RequestInit): Promise<Response>;
12
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAM5C;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAY1F"}
package/dist/http.js ADDED
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Shared fetch wrapper with LT Basic auth + session tracking headers.
3
+ *
4
+ * All ATMS/vision/automind HTTP calls go through fetchWithAuth.
5
+ * - Adds Authorization: Basic base64(LT_USERNAME:LT_ACCESS_KEY) when env vars present.
6
+ * - Adds x-session-id when TESTMUAI_SESSION_ID is set.
7
+ * - Adds x-source (defaults to "local"; forge sets TESTMUAI_SOURCE=hyperexecute
8
+ * in all cloud YAML paths).
9
+ */
10
+ export function ltAuthHeader() {
11
+ const user = process.env['LT_USERNAME'];
12
+ const key = process.env['LT_ACCESS_KEY'];
13
+ if (!user || !key)
14
+ return null;
15
+ const encoded = Buffer.from(`${user}:${key}`).toString('base64');
16
+ return `Basic ${encoded}`;
17
+ }
18
+ export async function fetchWithAuth(url, init = {}) {
19
+ const auth = ltAuthHeader();
20
+ const headers = { ...(init.headers ?? {}) };
21
+ if (auth)
22
+ headers['Authorization'] = auth;
23
+ const sessionId = process.env['TESTMUAI_SESSION_ID'];
24
+ if (sessionId)
25
+ headers['x-session-id'] = sessionId;
26
+ headers['x-source'] = process.env['TESTMUAI_SOURCE'] ?? 'local';
27
+ return fetch(url, { ...init, headers });
28
+ }
29
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,UAAU,YAAY;IAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACzC,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACjE,OAAO,SAAS,OAAO,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,OAAoB,EAAE;IACrE,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;IAC5B,MAAM,OAAO,GAA2B,EAAE,GAAG,CAAC,IAAI,CAAC,OAAiC,IAAI,EAAE,CAAC,EAAE,CAAC;IAE9F,IAAI,IAAI;QAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC;IAE1C,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACrD,IAAI,SAAS;QAAE,OAAO,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAEnD,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,OAAO,CAAC;IAEhE,OAAO,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { configure } from './configure.js';
2
+ import { test } from './test.js';
3
+ import { step, done } from './step.js';
4
+ import { run } from './session.js';
5
+ import { v, setVar, vAsync } from './vars.js';
6
+ import { TestmuConfigError } from './errors.js';
7
+ import { executeJs } from './helpers/executeJs.js';
8
+ import { executeApi } from './helpers/executeApi.js';
9
+ import { executeDb } from './helpers/executeDb.js';
10
+ import { visionQuery, textualQuery, visionWait, visionAction, getVisionCoordinates } from './helpers/vision.js';
11
+ import { verifyAssertion, evaluateBranch } from './helpers/assertion.js';
12
+ import { evaluateNetworkAssertion, networkQuery } from './helpers/network.js';
13
+ import { evaluateMath } from './helpers/math.js';
14
+ import { smartuiSnapshot } from './helpers/smartui.js';
15
+ import { switchTab } from './helpers/tabs.js';
16
+ import { clickDrag } from './helpers/drag.js';
17
+ import { checkUntilCondition } from './helpers/wait.js';
18
+ import { executeKaneCli } from './helpers/kaneCli.js';
19
+ declare const testmu: {
20
+ configure: typeof configure;
21
+ test: typeof test;
22
+ step: typeof step;
23
+ done: typeof done;
24
+ run: typeof run;
25
+ executeJs: typeof executeJs;
26
+ executeApi: typeof executeApi;
27
+ executeDb: typeof executeDb;
28
+ visionQuery: typeof visionQuery;
29
+ textualQuery: typeof textualQuery;
30
+ visionWait: typeof visionWait;
31
+ visionAction: typeof visionAction;
32
+ getVisionCoordinates: typeof getVisionCoordinates;
33
+ verifyAssertion: typeof verifyAssertion;
34
+ evaluateBranch: typeof evaluateBranch;
35
+ evaluateNetworkAssertion: typeof evaluateNetworkAssertion;
36
+ networkQuery: typeof networkQuery;
37
+ evaluateMath: typeof evaluateMath;
38
+ smartuiSnapshot: typeof smartuiSnapshot;
39
+ switchTab: typeof switchTab;
40
+ clickDrag: typeof clickDrag;
41
+ checkUntilCondition: typeof checkUntilCondition;
42
+ executeKaneCli: typeof executeKaneCli;
43
+ };
44
+ export default testmu;
45
+ export { v, setVar, vAsync, TestmuConfigError };
46
+ export type { ConfigureOptions, GlobalVariable } from './configure.js';
47
+ export type { RunTarget, Config } from './config.js';
48
+ export type { Reporter } from './reporters/index.js';
49
+ export type { TestFn, RegisteredTest } from './test.js';
50
+ export type { ApiRequest, ApiResponse, Authorization } from './helpers/executeApi.js';
51
+ export type { DbRequest } from './helpers/executeDb.js';
52
+ export type { AssertionTree, AssertionResult, SubCheck } from './helpers/assertion.js';
53
+ export type { NetworkNode, NetworkLeaf, NetworkComposite, NetworkQueryOptions } from './helpers/network.js';
54
+ export type { VisionCoordinates } from './helpers/vision.js';
55
+ export { ExecuteJsError } from './helpers/executeJs.js';
56
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EACL,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,oBAAoB,EAC1E,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAKtD,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;CASX,CAAC;AAEF,eAAe,MAAM,CAAC;AACtB,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;AAChD,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACvE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrD,YAAY,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACxD,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACtF,YAAY,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvF,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC5G,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,34 @@
1
+ import { configure } from './configure.js';
2
+ import { test } from './test.js';
3
+ import { step, done } from './step.js';
4
+ import { run } from './session.js';
5
+ import { v, setVar, vAsync } from './vars.js';
6
+ import { TestmuConfigError } from './errors.js';
7
+ import { executeJs } from './helpers/executeJs.js';
8
+ import { executeApi } from './helpers/executeApi.js';
9
+ import { executeDb } from './helpers/executeDb.js';
10
+ import { visionQuery, textualQuery, visionWait, visionAction, getVisionCoordinates, } from './helpers/vision.js';
11
+ import { verifyAssertion, evaluateBranch } from './helpers/assertion.js';
12
+ import { evaluateNetworkAssertion, networkQuery } from './helpers/network.js';
13
+ import { evaluateMath } from './helpers/math.js';
14
+ import { smartuiSnapshot } from './helpers/smartui.js';
15
+ import { switchTab } from './helpers/tabs.js';
16
+ import { clickDrag } from './helpers/drag.js';
17
+ import { checkUntilCondition } from './helpers/wait.js';
18
+ import { executeKaneCli } from './helpers/kaneCli.js';
19
+ import { installHealPatch } from './healPatch.js';
20
+ installHealPatch();
21
+ const testmu = {
22
+ configure, test, step, done, run,
23
+ executeJs, executeApi, executeDb,
24
+ visionQuery, textualQuery, visionWait, visionAction, getVisionCoordinates,
25
+ verifyAssertion, evaluateBranch,
26
+ evaluateNetworkAssertion, networkQuery,
27
+ evaluateMath, smartuiSnapshot,
28
+ switchTab, clickDrag,
29
+ checkUntilCondition, executeKaneCli,
30
+ };
31
+ export default testmu;
32
+ export { v, setVar, vAsync, TestmuConfigError };
33
+ export { ExecuteJsError } from './helpers/executeJs.js';
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EACL,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,oBAAoB,GAC1E,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,gBAAgB,EAAE,CAAC;AAEnB,MAAM,MAAM,GAAG;IACb,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG;IAChC,SAAS,EAAE,UAAU,EAAE,SAAS;IAChC,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,oBAAoB;IACzE,eAAe,EAAE,cAAc;IAC/B,wBAAwB,EAAE,YAAY;IACtC,YAAY,EAAE,eAAe;IAC7B,SAAS,EAAE,SAAS;IACpB,mBAAmB,EAAE,cAAc;CACpC,CAAC;AAEF,eAAe,MAAM,CAAC;AACtB,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;AAUhD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/log.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Minimal logging facade matching Python's `_log = logging.getLogger("testmu")`
3
+ * indentation convention:
4
+ * - [TEST ...] lines — no indent
5
+ * - [STEP N] / [STEP N FAIL] — 2-space indent (set by reporters)
6
+ * - [helper_name] lines — 4-space indent (set by helpers via this module)
7
+ */
8
+ export declare const log: {
9
+ /** Top-level event (no indent) — typically used by reporters for [TEST ...]. */
10
+ test(msg: string): void;
11
+ /** Step boundary (2-space indent) — used by reporters for [STEP N]. */
12
+ step(msg: string): void;
13
+ /** Helper internal lifecycle log (4-space indent) — used by helpers. */
14
+ helper(msg: string): void;
15
+ /** Warning (no indent enforced — caller decides). */
16
+ warn(msg: string): void;
17
+ /** Error (no indent enforced — caller decides). */
18
+ error(msg: string): void;
19
+ };
20
+ /** Preview a string capped at maxLen chars (matches Python's `description[:80]`). */
21
+ export declare function preview(s: unknown, maxLen?: number): string;
22
+ //# sourceMappingURL=log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,eAAO,MAAM,GAAG;IACd,gFAAgF;cACtE,MAAM,GAAG,IAAI;IAGvB,uEAAuE;cAC7D,MAAM,GAAG,IAAI;IAGvB,wEAAwE;gBAC5D,MAAM,GAAG,IAAI;IAGzB,qDAAqD;cAC3C,MAAM,GAAG,IAAI;IAGvB,mDAAmD;eACxC,MAAM,GAAG,IAAI;CAGzB,CAAC;AAEF,qFAAqF;AACrF,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,SAAK,GAAG,MAAM,CAGvD"}
package/dist/log.js ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Minimal logging facade matching Python's `_log = logging.getLogger("testmu")`
3
+ * indentation convention:
4
+ * - [TEST ...] lines — no indent
5
+ * - [STEP N] / [STEP N FAIL] — 2-space indent (set by reporters)
6
+ * - [helper_name] lines — 4-space indent (set by helpers via this module)
7
+ */
8
+ function ts() {
9
+ // Match Python's "YYYY-MM-DD HH:MM:SS,mmm" format
10
+ const d = new Date();
11
+ const pad = (n, w = 2) => n.toString().padStart(w, '0');
12
+ const date = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
13
+ const time = `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())},${pad(d.getMilliseconds(), 3)}`;
14
+ return `${date} ${time}`;
15
+ }
16
+ export const log = {
17
+ /** Top-level event (no indent) — typically used by reporters for [TEST ...]. */
18
+ test(msg) {
19
+ console.log(`[${ts()}] [INFO] ${msg}`);
20
+ },
21
+ /** Step boundary (2-space indent) — used by reporters for [STEP N]. */
22
+ step(msg) {
23
+ console.log(`[${ts()}] [INFO] ${msg}`);
24
+ },
25
+ /** Helper internal lifecycle log (4-space indent) — used by helpers. */
26
+ helper(msg) {
27
+ console.log(`[${ts()}] [INFO] ${msg}`);
28
+ },
29
+ /** Warning (no indent enforced — caller decides). */
30
+ warn(msg) {
31
+ console.warn(`[${ts()}] [WARN] ${msg}`);
32
+ },
33
+ /** Error (no indent enforced — caller decides). */
34
+ error(msg) {
35
+ console.error(`[${ts()}] [ERROR] ${msg}`);
36
+ },
37
+ };
38
+ /** Preview a string capped at maxLen chars (matches Python's `description[:80]`). */
39
+ export function preview(s, maxLen = 80) {
40
+ const str = typeof s === 'string' ? s : JSON.stringify(s);
41
+ return str.length <= maxLen ? str : str.slice(0, maxLen) + '…';
42
+ }
43
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,SAAS,EAAE;IACT,kDAAkD;IAClD,MAAM,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;IACrB,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,CAAC,GAAG,CAAC,EAAU,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACxE,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;IAC/E,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;IACjH,OAAO,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,gFAAgF;IAChF,IAAI,CAAC,GAAW;QACd,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,YAAY,GAAG,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,uEAAuE;IACvE,IAAI,CAAC,GAAW;QACd,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,cAAc,GAAG,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,wEAAwE;IACxE,MAAM,CAAC,GAAW;QAChB,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,gBAAgB,GAAG,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,qDAAqD;IACrD,IAAI,CAAC,GAAW;QACd,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,GAAG,EAAE,CAAC,CAAC;IAC1C,CAAC;IACD,mDAAmD;IACnD,KAAK,CAAC,GAAW;QACf,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,aAAa,GAAG,EAAE,CAAC,CAAC;IAC5C,CAAC;CACF,CAAC;AAEF,qFAAqF;AACrF,MAAM,UAAU,OAAO,CAAC,CAAU,EAAE,MAAM,GAAG,EAAE;IAC7C,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC1D,OAAO,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC;AACjE,CAAC"}
@@ -0,0 +1,10 @@
1
+ export interface Reporter {
2
+ beginTest(name: string): Promise<void>;
3
+ passTest(): Promise<void>;
4
+ failTest(error: unknown): Promise<void>;
5
+ beginStep(description: string): Promise<void>;
6
+ endStep(description: string, ok: boolean, error?: unknown): Promise<void>;
7
+ attachScreenshot(data: Buffer): Promise<void>;
8
+ }
9
+ export declare function createReporter(): Reporter;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reporters/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAMD,wBAAgB,cAAc,IAAI,QAAQ,CAEzC"}
@@ -0,0 +1,7 @@
1
+ import { LocalReporter } from './local.js';
2
+ import { LTReporter } from './lt.js';
3
+ import { config } from '../config.js';
4
+ export function createReporter() {
5
+ return config.current.runTarget === 'cloud' ? new LTReporter() : new LocalReporter();
6
+ }
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reporters/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,MAAM,UAAU,cAAc;IAC5B,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,aAAa,EAAE,CAAC;AACvF,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Reporter } from './index.js';
2
+ export declare class LocalReporter implements Reporter {
3
+ private stepNum;
4
+ beginTest(name: string): Promise<void>;
5
+ passTest(): Promise<void>;
6
+ failTest(error: unknown): Promise<void>;
7
+ beginStep(description: string): Promise<void>;
8
+ endStep(_description: string, ok: boolean, error?: unknown): Promise<void>;
9
+ attachScreenshot(_data: Buffer): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/reporters/local.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,qBAAa,aAAc,YAAW,QAAQ;IAC5C,OAAO,CAAC,OAAO,CAAK;IAEd,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvC,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7C,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAO1E,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGrD"}
@@ -0,0 +1,29 @@
1
+ import { log } from '../log.js';
2
+ export class LocalReporter {
3
+ stepNum = 0;
4
+ async beginTest(name) {
5
+ this.stepNum = 0;
6
+ log.test(`[TEST START] ${name}`);
7
+ }
8
+ async passTest() {
9
+ log.test(`[TEST PASS] (${this.stepNum} steps)`);
10
+ }
11
+ async failTest(error) {
12
+ const msg = error instanceof Error ? error.message : String(error);
13
+ log.test(`[TEST FAIL] at step ${this.stepNum} — ${msg}`);
14
+ }
15
+ async beginStep(description) {
16
+ this.stepNum += 1;
17
+ log.step(`[STEP ${this.stepNum}] ${description}`);
18
+ }
19
+ async endStep(_description, ok, error) {
20
+ if (!ok) {
21
+ const msg = error instanceof Error ? error.message : String(error ?? '');
22
+ log.step(`[STEP ${this.stepNum} FAIL] ${msg}`);
23
+ }
24
+ }
25
+ async attachScreenshot(_data) {
26
+ log.step(`[SCREENSHOT] ${_data.length} bytes`);
27
+ }
28
+ }
29
+ //# sourceMappingURL=local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/reporters/local.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAEhC,MAAM,OAAO,aAAa;IAChB,OAAO,GAAG,CAAC,CAAC;IAEpB,KAAK,CAAC,SAAS,CAAC,IAAY;QAC1B,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,GAAG,CAAC,IAAI,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,GAAG,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,OAAO,SAAS,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAAc;QAC3B,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnE,GAAG,CAAC,IAAI,CAAC,uBAAuB,IAAI,CAAC,OAAO,MAAM,GAAG,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,WAAmB;QACjC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;QAClB,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,YAAoB,EAAE,EAAW,EAAE,KAAe;QAC9D,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YACzE,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,UAAU,GAAG,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,KAAa;QAClC,GAAG,CAAC,IAAI,CAAC,gBAAgB,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAC;IACjD,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ import type { Page } from 'playwright';
2
+ import type { Reporter } from './index.js';
3
+ export declare class LTReporter implements Reporter {
4
+ private page;
5
+ private stepNum;
6
+ _setPage(page: Page): void;
7
+ private action;
8
+ beginTest(name: string): Promise<void>;
9
+ passTest(): Promise<void>;
10
+ failTest(error: unknown): Promise<void>;
11
+ beginStep(description: string): Promise<void>;
12
+ endStep(description: string, ok: boolean, error?: unknown): Promise<void>;
13
+ attachScreenshot(_data: Buffer): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=lt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lt.d.ts","sourceRoot":"","sources":["../../src/reporters/lt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,qBAAa,UAAW,YAAW,QAAQ;IACzC,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,OAAO,CAAK;IAEpB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;YAIZ,MAAM;IAUd,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAKzB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvC,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7C,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAQzE,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGrD"}