tomation 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.cjs CHANGED
@@ -1,1977 +1 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
- var __publicField = (obj, key, value) => {
5
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
- return value;
7
- };
8
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
9
- class UIElement {
10
- constructor(name, selector, parent, postProcessFn) {
11
- __publicField(this, "name");
12
- __publicField(this, "selector");
13
- __publicField(this, "parent");
14
- __publicField(this, "postProcess");
15
- this.name = name;
16
- this.selector = selector;
17
- this.parent = parent || null;
18
- this.postProcess = postProcessFn;
19
- }
20
- getElementName() {
21
- let parent = "";
22
- if (this.parent) {
23
- parent = " in " + this.parent.getElementName();
24
- }
25
- return `${this.name}${parent}`;
26
- }
27
- }
28
- let document$1;
29
- const setDocument = (doc) => {
30
- document$1 = doc;
31
- };
32
- const SelectorBuilder = (query, filterFn) => {
33
- const selector = (root = document$1, postProcess) => {
34
- root = root || document$1;
35
- console.log("Searching elem from Root = ", root);
36
- const elementsFound = [];
37
- root.querySelectorAll(query).forEach((e) => {
38
- if (e.style.display !== "none") {
39
- elementsFound.push(e);
40
- }
41
- });
42
- let elemFound;
43
- if (filterFn) {
44
- console.log("Applying filter ", filterFn);
45
- console.log(" -- to " + elementsFound.length + "elements: ", elementsFound);
46
- elemFound = elementsFound.filter((elem, index, array) => {
47
- console.log("Apply filter to item " + index + ": ", elem);
48
- const match = filterFn(elem, index, array);
49
- console.log(` -> Item ${index} ${match ? "Match" : "Discarded"}`);
50
- return match;
51
- })[0];
52
- } else {
53
- elemFound = elementsFound[0];
54
- }
55
- if (elemFound && postProcess) {
56
- console.log("Apply post process to = ", elemFound);
57
- elemFound = postProcess(elemFound);
58
- }
59
- console.log("Return elem = ", elemFound);
60
- return elemFound;
61
- };
62
- return selector;
63
- };
64
- const selectorIdentifier = (selector, parent, postProcessFn) => ({
65
- /**
66
- * Sets the UI element identifier
67
- * @param uiElementId
68
- * @returns
69
- */
70
- as: (uiElementId) => {
71
- return new UIElement(uiElementId, selector, parent, postProcessFn);
72
- }
73
- });
74
- const postProcessResponse = (selector, parent) => ({
75
- ...selectorIdentifier(selector, parent),
76
- /**
77
- * Tansform the UI element that will be returned
78
- * @param postProcessFn
79
- * @returns
80
- */
81
- postProcess: (postProcessFn) => ({
82
- ...selectorIdentifier(selector, parent, postProcessFn)
83
- })
84
- });
85
- const selectorFilterResponse = (selector) => ({
86
- ...selectorIdentifier(selector, null),
87
- childOf: (parent) => ({
88
- ...postProcessResponse(selector, parent)
89
- }),
90
- /**
91
- * Tansform the UI element that will be returned
92
- * @param postProcessFn
93
- * @returns
94
- */
95
- postProcess: (postProcessFn) => ({
96
- ...selectorIdentifier(selector, null, postProcessFn)
97
- })
98
- });
99
- const selectorFilter = (query) => {
100
- return {
101
- where: (filterFn) => {
102
- return selectorFilterResponse(SelectorBuilder(query, filterFn));
103
- }
104
- };
105
- };
106
- const DIV = selectorFilter("div");
107
- const BUTTON = selectorFilter("button");
108
- const INPUT = selectorFilter("input");
109
- const TEXTAREA = selectorFilter("textarea");
110
- const identifiedBy = (id) => {
111
- return selectorFilterResponse(SelectorBuilder("#" + id));
112
- };
113
- const ELEMENT = (htmlTag) => {
114
- return selectorFilter(htmlTag);
115
- };
116
- let enableFilterLogs = false;
117
- const setFilterLogs = (enabled) => {
118
- enableFilterLogs = enabled;
119
- };
120
- const filterLog = (...args) => {
121
- if (enableFilterLogs) {
122
- console.log("[UIElement Filter]", ...args);
123
- }
124
- };
125
- const classIs = (className) => {
126
- return (elem) => {
127
- const result = elem.className == className;
128
- filterLog(`classIs('${className}') on`, elem, "=>", result);
129
- return result;
130
- };
131
- };
132
- const classIncludes = (className) => {
133
- return (elem) => {
134
- const result = elem.className.split(" ").includes(className);
135
- filterLog(`classIncludes('${className}') on`, elem, "=>", result);
136
- return result;
137
- };
138
- };
139
- const innerTextIs = (text) => {
140
- return (elem) => {
141
- var _a;
142
- const result = ((_a = elem.textContent) == null ? void 0 : _a.trim()) == text;
143
- filterLog(`innerTextIs('${text}') on`, elem, "=>", result);
144
- return result;
145
- };
146
- };
147
- const innerTextContains = (text) => {
148
- return (elem) => {
149
- const result = elem.innerText.trim().includes(text);
150
- filterLog(`innerTextContains('${text}') on`, elem, "=>", result);
151
- return result;
152
- };
153
- };
154
- const titleIs = (text) => {
155
- return (elem) => {
156
- const result = elem.title == text;
157
- filterLog(`titleIs('${text}') on`, elem, "=>", result);
158
- return result;
159
- };
160
- };
161
- const placeholderIs = (text) => {
162
- return (elem) => {
163
- const result = elem.placeholder === text;
164
- filterLog(`placeholderIs('${text}') on`, elem, "=>", result);
165
- return result;
166
- };
167
- };
168
- const isFirstElement = () => {
169
- return (elem, index) => {
170
- const result = index === 0;
171
- filterLog("isFirstElement on", elem, "index", index, "=>", result);
172
- return result;
173
- };
174
- };
175
- const elementIndexIs = (index) => {
176
- return (elem, elemIndex) => {
177
- const result = elemIndex === index;
178
- filterLog(`elementIndexIs(${index}) on`, elem, "elemIndex", elemIndex, "=>", result);
179
- return result;
180
- };
181
- };
182
- const firstChildTextIs = (text) => {
183
- return (elem) => {
184
- const result = (elem == null ? void 0 : elem.firstChild).innerText.trim() === text;
185
- filterLog(`firstChildTextIs('${text}') on`, elem, "=>", result);
186
- return result;
187
- };
188
- };
189
- const and = (conditions) => {
190
- return (elem, elemIndex) => {
191
- let response = true;
192
- let i = 0;
193
- while (response && i < conditions.length) {
194
- const condResult = conditions[i](elem, elemIndex);
195
- filterLog(`and condition[${i}] on`, elem, "elemIndex", elemIndex, "=>", condResult);
196
- response = response && condResult;
197
- i++;
198
- }
199
- filterLog("and final result on", elem, "elemIndex", elemIndex, "=>", response);
200
- return response;
201
- };
202
- };
203
- const is = {
204
- DIV,
205
- BUTTON,
206
- INPUT,
207
- TEXTAREA,
208
- ELEMENT,
209
- identifiedBy
210
- };
211
- let getRandomValues;
212
- const rnds8 = new Uint8Array(16);
213
- function rng() {
214
- if (!getRandomValues) {
215
- getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
216
- if (!getRandomValues) {
217
- throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
218
- }
219
- }
220
- return getRandomValues(rnds8);
221
- }
222
- const byteToHex = [];
223
- for (let i = 0; i < 256; ++i) {
224
- byteToHex.push((i + 256).toString(16).slice(1));
225
- }
226
- function unsafeStringify(arr, offset = 0) {
227
- return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
228
- }
229
- const randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
230
- const native = {
231
- randomUUID
232
- };
233
- function v4(options, buf, offset) {
234
- if (native.randomUUID && !buf && !options) {
235
- return native.randomUUID();
236
- }
237
- options = options || {};
238
- const rnds = options.random || (options.rng || rng)();
239
- rnds[6] = rnds[6] & 15 | 64;
240
- rnds[8] = rnds[8] & 63 | 128;
241
- if (buf) {
242
- offset = offset || 0;
243
- for (let i = 0; i < 16; ++i) {
244
- buf[offset + i] = rnds[i];
245
- }
246
- return buf;
247
- }
248
- return unsafeStringify(rnds);
249
- }
250
- const wait = (timeout = 2e3) => {
251
- return new Promise((resolve) => {
252
- setTimeout(() => {
253
- resolve(null);
254
- }, timeout);
255
- });
256
- };
257
- const updateStyle = (elem, props) => {
258
- const propsList = Object.entries(props).map(([key, value]) => ({
259
- key,
260
- value
261
- }));
262
- propsList.forEach((styleItem) => {
263
- const { key, value } = styleItem;
264
- elem.style[key] = value;
265
- });
266
- };
267
- class UIUtils {
268
- constructor(window2) {
269
- __publicField(this, "window");
270
- __publicField(this, "document");
271
- __publicField(this, "devToolsMessageContainer");
272
- __publicField(this, "devToolsCheckElementContainer");
273
- __publicField(this, "darkLayerLeft");
274
- __publicField(this, "darkLayerTop");
275
- __publicField(this, "darkLayerRight");
276
- __publicField(this, "darkLayerBottom");
277
- __publicField(this, "currentCheckElem");
278
- __publicField(this, "contextViewerContainer");
279
- __publicField(this, "devToolsAlertContainer");
280
- this.document = window2.document;
281
- this.window = window2;
282
- this.devToolsMessageContainer = this.createElement("DIV", {
283
- id: "dev-tools-message-container",
284
- styles: {
285
- width: "500px",
286
- backgroundColor: "rgba(0, 0, 0, 0.5)",
287
- color: "white",
288
- position: "fixed",
289
- bottom: "10px",
290
- right: "10px",
291
- fontFamily: "monospace",
292
- zIndex: "9999"
293
- },
294
- parent: this.document.body
295
- });
296
- this.devToolsAlertContainer = this.createElement("DIV", {
297
- id: "dev-tools-alert-container",
298
- styles: {
299
- width: "100%",
300
- height: "30px",
301
- backgroundColor: "#b00",
302
- color: "white",
303
- position: "absolute ",
304
- top: 0,
305
- fontFamily: "monospace",
306
- zIndex: "9999",
307
- display: "none",
308
- alignItems: "center",
309
- justifyContent: "center",
310
- padding: "5px"
311
- },
312
- parent: this.document.body
313
- });
314
- this.devToolsCheckElementContainer = this.createElement("DIV", {
315
- id: "dev-tools-check-element-container",
316
- styles: {
317
- width: "100%",
318
- height: this.document.body.clientHeight + "px",
319
- position: "absolute",
320
- top: "0px",
321
- left: "0px",
322
- zIndex: "9990",
323
- display: "none",
324
- opacity: "0",
325
- transition: "opacity .2s"
326
- },
327
- parent: this.document.body
328
- });
329
- const darkLayerStyle = {
330
- zIndex: "9991",
331
- backgroundColor: "rgba(0,0,0,0.3)",
332
- position: "absolute"
333
- };
334
- this.darkLayerLeft = this.createElement("DIV", {
335
- id: "dark-layer-left",
336
- styles: darkLayerStyle,
337
- parent: this.devToolsCheckElementContainer
338
- });
339
- this.darkLayerTop = this.createElement("DIV", {
340
- id: "dark-layer-top",
341
- styles: darkLayerStyle,
342
- parent: this.devToolsCheckElementContainer
343
- });
344
- this.darkLayerRight = this.createElement("DIV", {
345
- id: "dark-layer-right",
346
- styles: darkLayerStyle,
347
- parent: this.devToolsCheckElementContainer
348
- });
349
- this.darkLayerBottom = this.createElement("DIV", {
350
- id: "dark-layer-bottom",
351
- styles: darkLayerStyle,
352
- parent: this.devToolsCheckElementContainer
353
- });
354
- this.currentCheckElem = this.createElement("DIV", {
355
- id: "current-check-elem",
356
- parent: this.devToolsCheckElementContainer
357
- });
358
- this.contextViewerContainer = this.createElement("DIV", {
359
- id: "context-viewer-container",
360
- styles: {
361
- width: "100%",
362
- height: this.document.body.clientHeight + "px",
363
- position: "absolute",
364
- top: "0px",
365
- left: "0px",
366
- zIndex: "10000",
367
- display: "none"
368
- },
369
- parent: this.document.body
370
- });
371
- }
372
- createElement(tagName, props) {
373
- const elem = this.document.createElement(tagName);
374
- if (props) {
375
- if (props.id)
376
- elem.id = props == null ? void 0 : props.id;
377
- if (props.styles)
378
- updateStyle(elem, props.styles);
379
- if (props.parent)
380
- props.parent.appendChild(elem);
381
- }
382
- return elem;
383
- }
384
- /**
385
- *
386
- * @param message @deprecated
387
- */
388
- async logAction(message) {
389
- const messageElem = exports.AutomationInstance.document.createElement("DIV");
390
- messageElem.innerText = message;
391
- updateStyle(messageElem, {
392
- padding: "3px 10px",
393
- opacity: "1",
394
- transition: "opacity 1s"
395
- });
396
- this.devToolsMessageContainer.appendChild(messageElem);
397
- await wait(4e3);
398
- messageElem.style.opacity = "0";
399
- await wait(4e3);
400
- this.devToolsMessageContainer.removeChild(messageElem);
401
- await wait(1e3);
402
- }
403
- async checkElement(elem, name) {
404
- if (!elem)
405
- return;
406
- const rect = elem.getBoundingClientRect();
407
- const bodyBundingRect = this.document.body.getBoundingClientRect();
408
- this.darkLayerLeft.style.left = "0px";
409
- this.darkLayerLeft.style.top = rect.top + "px";
410
- this.darkLayerLeft.style.width = this.window.scrollX + rect.left + "px";
411
- this.darkLayerLeft.style.height = rect.height + "px";
412
- this.darkLayerTop.style.left = this.window.scrollX + "px";
413
- this.darkLayerTop.style.top = "0px";
414
- this.darkLayerTop.style.width = "100%";
415
- this.darkLayerTop.style.height = rect.top + "px";
416
- this.darkLayerRight.style.left = this.window.scrollX + rect.left + rect.width + "px";
417
- this.darkLayerRight.style.top = rect.top + "px";
418
- this.darkLayerRight.style.width = bodyBundingRect.width - (rect.left + rect.width) + "px";
419
- this.darkLayerRight.style.height = rect.height + "px";
420
- this.darkLayerBottom.style.left = this.window.scrollX + "px";
421
- this.darkLayerBottom.style.top = rect.top + rect.height + "px";
422
- this.darkLayerBottom.style.width = "100%";
423
- this.darkLayerBottom.style.height = bodyBundingRect.height - (rect.top + rect.height) + "px";
424
- this.currentCheckElem.id = `dev-tools-current-check-elem-${name}`;
425
- this.currentCheckElem.style.top = rect.top + "px";
426
- this.currentCheckElem.style.left = this.window.scrollX + rect.left + "px";
427
- this.currentCheckElem.style.height = rect.height + "px";
428
- this.currentCheckElem.style.width = rect.width + "px";
429
- this.currentCheckElem.style.boxShadow = "0px 0px 5px 2px lightgreen";
430
- this.currentCheckElem.style.position = "absolute";
431
- this.currentCheckElem.style.zIndex = "9992";
432
- this.devToolsCheckElementContainer.style.display = "block";
433
- this.devToolsCheckElementContainer.style.opacity = "1";
434
- await wait(200);
435
- }
436
- async showAlert(message) {
437
- const messageElem = exports.AutomationInstance.document.createElement("DIV");
438
- const body = exports.AutomationInstance.document.body;
439
- messageElem.innerText = message;
440
- updateStyle(body, {
441
- paddingTop: "30px"
442
- });
443
- updateStyle(this.devToolsAlertContainer, {
444
- display: "flex"
445
- });
446
- this.devToolsAlertContainer.appendChild(messageElem);
447
- }
448
- async hideAlert() {
449
- updateStyle(this.devToolsAlertContainer, {
450
- display: "none"
451
- });
452
- const body = exports.AutomationInstance.document.body;
453
- updateStyle(body, {
454
- paddingTop: "0"
455
- });
456
- if (this.devToolsAlertContainer.firstChild) {
457
- this.devToolsAlertContainer.removeChild(this.devToolsAlertContainer.firstChild);
458
- }
459
- }
460
- async hideCheckElementContainer() {
461
- this.devToolsCheckElementContainer.style.opacity = "0";
462
- await wait(200);
463
- this.devToolsCheckElementContainer.style.display = "none";
464
- }
465
- displayContext(context) {
466
- updateStyle(this.contextViewerContainer, {
467
- display: "flex",
468
- "background-color": "white",
469
- "position": "absolute",
470
- "top": "0px",
471
- "left": "0px",
472
- "z-index": "9999"
473
- });
474
- const contextViewerBefore = this.document.createElement("DIV");
475
- contextViewerBefore.id = "context-viewer-before";
476
- updateStyle(contextViewerBefore, {
477
- flex: "50%",
478
- width: "100%",
479
- height: "auto",
480
- border: "2px solid orange"
481
- });
482
- const contextViewerAfter = this.document.createElement("DIV");
483
- contextViewerAfter.id = "context-viewer-after";
484
- updateStyle(contextViewerAfter, {
485
- flex: "50%",
486
- width: "100%",
487
- height: "auto",
488
- border: "2px solid green"
489
- });
490
- const beforeHTML = this.document.createElement("DIV");
491
- beforeHTML.innerHTML = context.beforeHTML;
492
- setInputValues(beforeHTML, context.beforeInputValues);
493
- const afterHTML = this.document.createElement("DIV");
494
- afterHTML.innerHTML = context.afterHTML;
495
- setInputValues(afterHTML, context.afterInputValues);
496
- this.contextViewerContainer.appendChild(contextViewerBefore);
497
- contextViewerBefore.appendChild(beforeHTML);
498
- setTimeout(() => {
499
- this.contextViewerContainer.removeChild(contextViewerBefore);
500
- this.contextViewerContainer.appendChild(contextViewerAfter);
501
- contextViewerAfter.appendChild(afterHTML);
502
- setTimeout(() => {
503
- this.contextViewerContainer.removeChild(contextViewerAfter);
504
- updateStyle(this.contextViewerContainer, { display: "none" });
505
- }, 2e3);
506
- }, 2e3);
507
- }
508
- }
509
- const setInputValues = (html, valuesMap) => {
510
- html.querySelectorAll("input").forEach((input) => {
511
- const id = input.getAttribute("input-id") || "";
512
- input.value = valuesMap[id];
513
- });
514
- };
515
- const HTML_ELEMENT_REMOVED = null;
516
- const retry = async (currentAction, uiElement, parentElement, delay = 1e3, index = 0, maxTries = 10, untilRemoved = false) => {
517
- console.log("Automation Status: ", exports.AutomationInstance.status);
518
- if (exports.AutomationInstance.isPaused) {
519
- return new Promise((resolve, reject) => {
520
- exports.AutomationInstance.saveCurrentAction(async (action) => {
521
- if (action.status == "skipped") {
522
- return resolve(null);
523
- }
524
- try {
525
- const response = await retry(action, uiElement, parentElement, delay, index, maxTries, untilRemoved);
526
- resolve(response);
527
- } catch (error) {
528
- reject(error);
529
- }
530
- }, currentAction);
531
- });
532
- }
533
- if (exports.AutomationInstance.isStopped) {
534
- throw new Error("Test stopped manually");
535
- }
536
- console.groupCollapsed(`tries ${index}/${maxTries}`);
537
- if (currentAction) {
538
- currentAction.updateTries(index);
539
- await AbstractAction.notifyActionUpdated(currentAction);
540
- }
541
- if (index === maxTries) {
542
- console.groupEnd();
543
- if (untilRemoved) {
544
- throw new Error(`UI Element ${uiElement.getElementName() || "UNKNOWN"} still present after 10 tries`);
545
- } else {
546
- throw new Error(`UI Element ${uiElement.getElementName() || "UNKNOWN"} not found after 10 tries`);
547
- }
548
- } else {
549
- const elem = uiElement.selector(parentElement, uiElement.postProcess);
550
- console.groupEnd();
551
- if (elem) {
552
- if (untilRemoved) {
553
- await wait(delay);
554
- return await retry(currentAction, uiElement, parentElement, delay, ++index, maxTries, untilRemoved);
555
- } else {
556
- console.log("Element found = ", elem);
557
- return elem;
558
- }
559
- } else {
560
- if (untilRemoved) {
561
- console.log("Element removed.");
562
- return HTML_ELEMENT_REMOVED;
563
- } else {
564
- await wait(delay);
565
- return await retry(currentAction, uiElement, parentElement, delay, ++index, maxTries, untilRemoved);
566
- }
567
- }
568
- }
569
- };
570
- const waitForElement = async (currentAction, uiElement, delay = 1e3, maxTries = 10, untilRemoved = false) => {
571
- const elementName = uiElement == null ? void 0 : uiElement.getElementName();
572
- console.group("Looking for Element: " + elementName);
573
- let parentElement = null;
574
- if (uiElement.parent) {
575
- try {
576
- console.groupCollapsed("Look for Parent ", uiElement.parent.getElementName());
577
- parentElement = await waitForElement(currentAction, uiElement.parent, delay, maxTries, untilRemoved);
578
- console.groupEnd();
579
- } catch (e) {
580
- console.groupEnd();
581
- if (untilRemoved && e.message.includes("not found")) {
582
- console.log("Parent not found, so element was removed");
583
- console.groupEnd();
584
- return HTML_ELEMENT_REMOVED;
585
- } else {
586
- console.groupEnd();
587
- throw e;
588
- }
589
- }
590
- }
591
- try {
592
- console.log("Using parent element: ", parentElement);
593
- const elem = await retry(currentAction, uiElement, parentElement, delay, 0, maxTries, untilRemoved);
594
- console.groupEnd();
595
- return elem;
596
- } catch (e) {
597
- if (untilRemoved && e.message.includes("not found")) {
598
- console.log("Parent not found, so element was removed");
599
- console.groupEnd();
600
- return HTML_ELEMENT_REMOVED;
601
- } else {
602
- console.groupEnd();
603
- throw e;
604
- }
605
- }
606
- };
607
- var ACTION_STATUS = /* @__PURE__ */ ((ACTION_STATUS2) => {
608
- ACTION_STATUS2["WAITING"] = "waiting";
609
- ACTION_STATUS2["RUNNING"] = "running";
610
- ACTION_STATUS2["STOPPED"] = "stopped";
611
- ACTION_STATUS2["PAUSED"] = "paused";
612
- ACTION_STATUS2["SUCCESS"] = "success";
613
- ACTION_STATUS2["ERROR"] = "error";
614
- ACTION_STATUS2["SKIPPED"] = "skipped";
615
- return ACTION_STATUS2;
616
- })(ACTION_STATUS || {});
617
- class AbstractAction {
618
- constructor() {
619
- __publicField(this, "status");
620
- __publicField(this, "error");
621
- __publicField(this, "id");
622
- __publicField(this, "context");
623
- this.status = "waiting";
624
- this.error = "";
625
- this.id = v4();
626
- this.context = {
627
- beforeHTML: "",
628
- beforeInputValues: {},
629
- afterInputValues: {},
630
- afterHTML: "",
631
- url: "",
632
- startTimestamp: "",
633
- endTimestamp: ""
634
- };
635
- }
636
- getJSON() {
637
- return {
638
- id: this.id,
639
- description: this.getDescription(),
640
- context: this.context,
641
- status: this.status,
642
- error: this.error
643
- };
644
- }
645
- reset() {
646
- this.status = "waiting";
647
- this.error = "";
648
- this.resetAction();
649
- }
650
- getInputValuesFromPage() {
651
- const inputsMap = {};
652
- const inputs = exports.AutomationInstance.document.querySelectorAll("input");
653
- inputs.forEach((input, index) => {
654
- const id = `value-id-${index}`;
655
- input.setAttribute("input-id", id);
656
- inputsMap[id] = input.value;
657
- });
658
- return inputsMap;
659
- }
660
- async execute() {
661
- try {
662
- this.status = "running";
663
- this.context.beforeInputValues = this.getInputValuesFromPage();
664
- this.context.beforeHTML = exports.AutomationInstance.document.body.innerHTML;
665
- await AbstractAction.notifyActionUpdated(this);
666
- console.log("Action: ", this.getDescription());
667
- await this.executeAction();
668
- this.status = "success";
669
- this.error = "";
670
- if (exports.AutomationInstance.isStepByStepMode) {
671
- exports.AutomationInstance.pause();
672
- }
673
- } catch (e) {
674
- this.status = "error";
675
- this.error = e.message;
676
- if (e.message == "Test stopped manually") {
677
- throw Error("Error in Action " + this.getDescription() + ". Message: " + e.message);
678
- } else {
679
- this.status = "paused";
680
- exports.AutomationInstance.pause();
681
- }
682
- } finally {
683
- this.context.afterInputValues = this.getInputValuesFromPage();
684
- this.context.afterHTML = exports.AutomationInstance.document.body.innerHTML;
685
- await AbstractAction.notifyActionUpdated(this);
686
- }
687
- }
688
- static async notifyActionUpdated(action) {
689
- AutomationEvents.dispatch(EVENT_NAMES.ACTION_UPDATE, {
690
- action: action.getJSON()
691
- });
692
- }
693
- }
694
- class Action extends AbstractAction {
695
- constructor(name, steps) {
696
- super();
697
- __publicField(this, "name");
698
- __publicField(this, "stepsFn");
699
- __publicField(this, "steps");
700
- __publicField(this, "params");
701
- __publicField(this, "index");
702
- this.name = name;
703
- this.stepsFn = steps;
704
- this.steps = [];
705
- this.index = 0;
706
- }
707
- getDescription() {
708
- return this.name;
709
- }
710
- compileSteps() {
711
- super.reset();
712
- this.stepsFn(this.params);
713
- }
714
- stepsToJSON() {
715
- return this.steps.reduce((acc, curr) => {
716
- acc.push(curr.getJSON());
717
- return acc;
718
- }, []);
719
- }
720
- getJSON() {
721
- return {
722
- ...super.getJSON(),
723
- type: "Action",
724
- params: this.params,
725
- steps: this.stepsToJSON()
726
- };
727
- }
728
- resetAction() {
729
- this.steps.length = 0;
730
- this.index = 0;
731
- }
732
- async continue() {
733
- if (exports.AutomationInstance.isPaused) {
734
- return new Promise((resolve, reject) => {
735
- exports.AutomationInstance.saveCurrentAction(async (action) => {
736
- if (action.status == "skipped") {
737
- return resolve();
738
- }
739
- try {
740
- await action.continue();
741
- resolve();
742
- } catch (error) {
743
- reject(error);
744
- }
745
- }, this);
746
- });
747
- }
748
- if (exports.AutomationInstance.isStopped) {
749
- throw new Error("Test stopped manually");
750
- }
751
- if (this.index < this.steps.length) {
752
- const step = this.steps[this.index];
753
- try {
754
- await wait(exports.AutomationInstance.speed);
755
- await step.execute();
756
- if (!exports.AutomationInstance.isPaused) {
757
- this.index++;
758
- await this.continue();
759
- } else {
760
- return new Promise((resolve, reject) => {
761
- exports.AutomationInstance.saveCurrentAction(async (action) => {
762
- if (action.status == "skipped") {
763
- this.index++;
764
- await AbstractAction.notifyActionUpdated(step);
765
- await this.continue();
766
- return resolve();
767
- }
768
- try {
769
- await action.continue();
770
- resolve();
771
- } catch (error) {
772
- reject(error);
773
- }
774
- }, step);
775
- });
776
- }
777
- } catch (e) {
778
- throw e;
779
- }
780
- }
781
- }
782
- async executeAction() {
783
- this.index = 0;
784
- await this.continue();
785
- }
786
- setParams(params) {
787
- this.params = params;
788
- }
789
- addStep(action) {
790
- this.steps.push(action);
791
- }
792
- }
793
- class ActionOnElement extends AbstractAction {
794
- constructor(uiElement) {
795
- super();
796
- __publicField(this, "uiElement");
797
- __publicField(this, "element");
798
- __publicField(this, "tries");
799
- this.uiElement = uiElement;
800
- this.element = null;
801
- this.tries = 0;
802
- }
803
- getElementName() {
804
- var _a;
805
- return (_a = this.uiElement) == null ? void 0 : _a.getElementName();
806
- }
807
- updateTries(tries) {
808
- this.tries = tries;
809
- }
810
- resetTries() {
811
- this.tries = 0;
812
- }
813
- getJSON() {
814
- return {
815
- id: this.id,
816
- element: this.getElementName(),
817
- description: this.getDescription(),
818
- status: this.status,
819
- error: this.error,
820
- context: this.context,
821
- tries: this.tries
822
- };
823
- }
824
- /**
825
- *
826
- * @param uiElement
827
- * @param delay of each try. Defaults to 1 second
828
- */
829
- static waitForElement(currentAction, uiElement, delay = 1e3, maxTries = 10, untilRemoved = false) {
830
- const elementName = uiElement.getElementName();
831
- return new Promise(async (resolve, reject) => {
832
- var _a;
833
- const retry2 = async (parentElement2, delay2 = 1e3, index = 0, untilRemoved2 = false) => {
834
- console.groupCollapsed(`tries ${index}/${maxTries}`);
835
- currentAction.updateTries(index);
836
- await AbstractAction.notifyActionUpdated(currentAction);
837
- if (index === maxTries) {
838
- console.groupEnd();
839
- if (untilRemoved2) {
840
- throw new Error(`UI Element ${elementName || "UNKNOWN"} still present after 10 tries`);
841
- } else {
842
- throw new Error(`UI Element ${elementName || "UNKNOWN"} not found after 10 tries`);
843
- }
844
- } else {
845
- const elem = uiElement.selector(parentElement2, uiElement.postProcess);
846
- console.groupEnd();
847
- if (elem) {
848
- if (untilRemoved2) {
849
- await wait(delay2);
850
- return await retry2(parentElement2, delay2, ++index, untilRemoved2);
851
- } else {
852
- console.log("Element found = ", elem);
853
- return elem;
854
- }
855
- } else {
856
- if (untilRemoved2) {
857
- console.log("Element removed.");
858
- return null;
859
- } else {
860
- await wait(delay2);
861
- return await retry2(parentElement2, delay2, ++index, untilRemoved2);
862
- }
863
- }
864
- }
865
- };
866
- console.group("[Action On Element] Looking for Element: " + elementName);
867
- let parentElement = null;
868
- let parentSuccess = true;
869
- if (uiElement.parent) {
870
- console.groupCollapsed("Look for Parent ", uiElement.parent.getElementName());
871
- try {
872
- parentElement = await ActionOnElement.waitForElement(currentAction, uiElement.parent, delay, maxTries, untilRemoved);
873
- } catch (e) {
874
- parentSuccess = false;
875
- } finally {
876
- console.groupEnd();
877
- }
878
- }
879
- if (parentSuccess) {
880
- console.log("using parent element: ", parentElement);
881
- try {
882
- const elem = await retry2(parentElement, delay, 0, untilRemoved);
883
- console.groupEnd();
884
- resolve(elem);
885
- } catch (e) {
886
- console.groupEnd();
887
- reject(new Error(e.message));
888
- }
889
- } else {
890
- console.groupEnd();
891
- reject(new Error(`Parent ${(_a = uiElement.parent) == null ? void 0 : _a.getElementName()} of UI Element ${uiElement.name || "UNKNOWN"} not found`));
892
- }
893
- });
894
- }
895
- async executeAction() {
896
- var _a;
897
- try {
898
- this.element = await waitForElement(this, this.uiElement);
899
- (_a = this.element) == null ? void 0 : _a.setAttribute("test-id", this.getElementName());
900
- await exports.AutomationInstance.uiUtils.checkElement(this.element, this.getElementName());
901
- this.executeActionOnElement();
902
- await exports.AutomationInstance.uiUtils.hideCheckElementContainer();
903
- } catch (e) {
904
- throw Error(e.message);
905
- }
906
- }
907
- resetAction() {
908
- this.element = null;
909
- this.resetTries();
910
- }
911
- }
912
- class ClickAction extends ActionOnElement {
913
- constructor(uiElement) {
914
- super(uiElement);
915
- }
916
- executeActionOnElement() {
917
- var _a;
918
- return (_a = this.element) == null ? void 0 : _a.click();
919
- }
920
- getDescription() {
921
- return "Click in " + this.getElementName();
922
- }
923
- getJSON() {
924
- return {
925
- ...super.getJSON(),
926
- type: "Click"
927
- };
928
- }
929
- }
930
- class AssertTextIsAction extends ActionOnElement {
931
- constructor(uiElement, text) {
932
- super(uiElement);
933
- __publicField(this, "text");
934
- this.text = text;
935
- }
936
- executeActionOnElement() {
937
- var _a;
938
- const textIsEqual = ((_a = this.element) == null ? void 0 : _a.innerText) === this.text;
939
- if (!textIsEqual) {
940
- throw new Error(`Text in element ${this.getElementName()} is not '${this.text}'`);
941
- }
942
- }
943
- getDescription() {
944
- return `Assert that text in ${this.getElementName()} is '${this.text}'`;
945
- }
946
- getJSON() {
947
- return {
948
- ...super.getJSON(),
949
- type: "AssertTextIsAction",
950
- value: this.text
951
- };
952
- }
953
- }
954
- class AssertContainsTextAction extends ActionOnElement {
955
- constructor(uiElement, text) {
956
- super(uiElement);
957
- __publicField(this, "text");
958
- this.text = text;
959
- }
960
- executeActionOnElement() {
961
- var _a;
962
- const containsText = (_a = this.element) == null ? void 0 : _a.innerText.includes(this.text);
963
- if (!containsText) {
964
- throw new Error(`Text in element ${this.getElementName()} doesn't contain '${this.text}'`);
965
- }
966
- }
967
- getDescription() {
968
- return `Assert that ${this.getElementName()} contains '${this.text}'`;
969
- }
970
- getJSON() {
971
- return {
972
- ...super.getJSON(),
973
- type: "AssertContainsText",
974
- value: this.text
975
- };
976
- }
977
- }
978
- class AssertValueIsAction extends ActionOnElement {
979
- constructor(uiElement, value) {
980
- super(uiElement);
981
- __publicField(this, "value");
982
- this.value = value;
983
- }
984
- executeActionOnElement() {
985
- const valueIsEqual = this.element.value === this.value;
986
- if (!valueIsEqual) {
987
- throw new Error(`Value in element ${this.getElementName()} is not '${this.value}'`);
988
- }
989
- }
990
- getDescription() {
991
- return `Assert that value in ${this.getElementName()} is '${this.value}'`;
992
- }
993
- getJSON() {
994
- return {
995
- ...super.getJSON(),
996
- type: "AssertValueIsAction",
997
- value: this.value
998
- };
999
- }
1000
- }
1001
- class AssertExistsAction extends ActionOnElement {
1002
- constructor(uiElement) {
1003
- super(uiElement);
1004
- }
1005
- executeActionOnElement() {
1006
- const exists = !!this.element;
1007
- if (!exists) {
1008
- throw new Error(`Element ${this.getElementName()} doesn't exist`);
1009
- }
1010
- }
1011
- getDescription() {
1012
- return `Assert that ${this.getElementName()} exists`;
1013
- }
1014
- getJSON() {
1015
- return {
1016
- ...super.getJSON(),
1017
- type: "AssertExistsAction"
1018
- };
1019
- }
1020
- }
1021
- class AssertNotExistsAction extends ActionOnElement {
1022
- constructor(uiElement) {
1023
- super(uiElement);
1024
- }
1025
- async executeAction() {
1026
- var _a;
1027
- try {
1028
- this.element = await waitForElement(this, this.uiElement, 1e3, 5, true);
1029
- (_a = this.element) == null ? void 0 : _a.setAttribute("test-id", this.getElementName());
1030
- await exports.AutomationInstance.uiUtils.checkElement(this.element, this.getElementName());
1031
- this.executeActionOnElement();
1032
- await exports.AutomationInstance.uiUtils.hideCheckElementContainer();
1033
- } catch (e) {
1034
- throw Error(e.message);
1035
- }
1036
- }
1037
- executeActionOnElement() {
1038
- const exists = !!this.element;
1039
- if (exists) {
1040
- throw new Error(`Element ${this.getElementName()} was not expected to exist`);
1041
- }
1042
- }
1043
- getDescription() {
1044
- return `Assert that ${this.getElementName()} doesn't exist`;
1045
- }
1046
- getJSON() {
1047
- return {
1048
- ...super.getJSON(),
1049
- type: "AssertNotExistsAction"
1050
- };
1051
- }
1052
- }
1053
- class SelectAction extends ActionOnElement {
1054
- constructor(uiElement, value) {
1055
- super(uiElement);
1056
- __publicField(this, "value");
1057
- this.value = value;
1058
- }
1059
- executeActionOnElement() {
1060
- var _a, _b, _c, _d;
1061
- let inputElem = this.element;
1062
- if (((_a = this.element) == null ? void 0 : _a.tagName) !== "INPUT" && ((_b = this.element) == null ? void 0 : _b.tagName) !== "SELECT" && ((_c = this.element) == null ? void 0 : _c.tagName) !== "TEXTAREA") {
1063
- inputElem = (_d = this.element) == null ? void 0 : _d.querySelectorAll("input")[0];
1064
- if (!inputElem) {
1065
- throw new Error("Input element not found. Not able to type value in element " + this.getElementName());
1066
- }
1067
- }
1068
- inputElem.value = this.value;
1069
- inputElem.dispatchEvent(new Event("change"));
1070
- }
1071
- getDescription() {
1072
- return `Select value '${this.value}' in ${this.getElementName()}`;
1073
- }
1074
- getJSON() {
1075
- return {
1076
- ...super.getJSON(),
1077
- type: "Select",
1078
- value: this.value
1079
- };
1080
- }
1081
- }
1082
- class TypeAction extends ActionOnElement {
1083
- constructor(uiElement, value) {
1084
- super(uiElement);
1085
- __publicField(this, "value");
1086
- this.value = value;
1087
- }
1088
- executeActionOnElement() {
1089
- var _a, _b, _c, _d;
1090
- let inputElem = this.element;
1091
- if (((_a = this.element) == null ? void 0 : _a.tagName) !== "INPUT" && ((_b = this.element) == null ? void 0 : _b.tagName) !== "SELECT" && ((_c = this.element) == null ? void 0 : _c.tagName) !== "TEXTAREA") {
1092
- inputElem = (_d = this.element) == null ? void 0 : _d.querySelectorAll("input")[0];
1093
- if (!inputElem) {
1094
- throw new Error("Input element not found. Not able to type value in element " + this.getElementName());
1095
- }
1096
- }
1097
- inputElem.value = this.value;
1098
- inputElem.dispatchEvent(new Event("change"));
1099
- inputElem.dispatchEvent(new Event("keyup"));
1100
- }
1101
- getDescription() {
1102
- return `Type value '${this.value}' in ${this.getElementName()}`;
1103
- }
1104
- getJSON() {
1105
- return {
1106
- ...super.getJSON(),
1107
- type: "Type",
1108
- value: this.value
1109
- };
1110
- }
1111
- }
1112
- class TypePasswordAction extends ActionOnElement {
1113
- constructor(uiElement, value) {
1114
- super(uiElement);
1115
- __publicField(this, "value");
1116
- this.value = value;
1117
- }
1118
- executeActionOnElement() {
1119
- var _a, _b, _c, _d;
1120
- let inputElem = this.element;
1121
- if (((_a = this.element) == null ? void 0 : _a.tagName) !== "INPUT" && ((_b = this.element) == null ? void 0 : _b.tagName) !== "SELECT" && ((_c = this.element) == null ? void 0 : _c.tagName) !== "TEXTAREA") {
1122
- inputElem = (_d = this.element) == null ? void 0 : _d.querySelectorAll("input")[0];
1123
- if (!inputElem) {
1124
- throw new Error("Input element not found. Not able to type value in element " + this.getElementName());
1125
- }
1126
- }
1127
- inputElem.value = this.value;
1128
- inputElem.dispatchEvent(new Event("change"));
1129
- }
1130
- getDescription() {
1131
- return `Type a password in ${this.getElementName()}`;
1132
- }
1133
- getJSON() {
1134
- return {
1135
- ...super.getJSON(),
1136
- type: "TypePassword",
1137
- value: this.value
1138
- };
1139
- }
1140
- }
1141
- class PressEscKeyAction extends ActionOnElement {
1142
- constructor(uiElement) {
1143
- super(uiElement);
1144
- }
1145
- executeActionOnElement() {
1146
- var _a;
1147
- (_a = this.element) == null ? void 0 : _a.dispatchEvent(
1148
- new KeyboardEvent("keydown", {
1149
- altKey: false,
1150
- code: "Escape",
1151
- ctrlKey: false,
1152
- isComposing: false,
1153
- key: "Escape",
1154
- location: 0,
1155
- metaKey: false,
1156
- repeat: false,
1157
- shiftKey: false,
1158
- which: 27,
1159
- charCode: 0,
1160
- keyCode: 27
1161
- })
1162
- );
1163
- }
1164
- getDescription() {
1165
- return `Press Esc key in ${this.getElementName()}`;
1166
- }
1167
- getJSON() {
1168
- return {
1169
- ...super.getJSON(),
1170
- type: "PressEscKey"
1171
- };
1172
- }
1173
- }
1174
- class PressDownKeyAction extends ActionOnElement {
1175
- constructor(uiElement) {
1176
- super(uiElement);
1177
- }
1178
- executeActionOnElement() {
1179
- var _a;
1180
- (_a = this.element) == null ? void 0 : _a.dispatchEvent(
1181
- new KeyboardEvent("keyup", {
1182
- altKey: false,
1183
- code: "Down",
1184
- ctrlKey: false,
1185
- isComposing: false,
1186
- key: "Down",
1187
- location: 0,
1188
- metaKey: false,
1189
- repeat: false,
1190
- shiftKey: false,
1191
- which: 40,
1192
- charCode: 0,
1193
- keyCode: 40
1194
- })
1195
- );
1196
- }
1197
- getDescription() {
1198
- return `Press Down key in ${this.getElementName()}`;
1199
- }
1200
- getJSON() {
1201
- return {
1202
- ...super.getJSON(),
1203
- type: "PressDownKey"
1204
- };
1205
- }
1206
- }
1207
- class PressTabKeyAction extends ActionOnElement {
1208
- constructor(uiElement) {
1209
- super(uiElement);
1210
- }
1211
- executeActionOnElement() {
1212
- var _a;
1213
- (_a = this.element) == null ? void 0 : _a.dispatchEvent(
1214
- new KeyboardEvent("keydown", {
1215
- altKey: false,
1216
- code: "Tab",
1217
- ctrlKey: false,
1218
- isComposing: false,
1219
- key: "Tab",
1220
- location: 0,
1221
- metaKey: false,
1222
- repeat: false,
1223
- shiftKey: false,
1224
- which: 9,
1225
- charCode: 0,
1226
- keyCode: 9
1227
- })
1228
- );
1229
- }
1230
- getDescription() {
1231
- return `Press Tab key in ${this.getElementName()}`;
1232
- }
1233
- getJSON() {
1234
- return {
1235
- ...super.getJSON(),
1236
- type: "PressTabKey"
1237
- };
1238
- }
1239
- }
1240
- class UploadFileAction extends ActionOnElement {
1241
- constructor(uiElement, file) {
1242
- super(uiElement);
1243
- __publicField(this, "file");
1244
- this.file = file;
1245
- }
1246
- executeActionOnElement() {
1247
- const fileInput = this.element;
1248
- const dataTransfer = new DataTransfer();
1249
- dataTransfer.items.add(this.file);
1250
- const fileList = dataTransfer.files;
1251
- fileInput.files = fileList;
1252
- fileInput.dispatchEvent(new Event("change"));
1253
- function getParentForm(elem) {
1254
- var _a;
1255
- if (elem == null ? void 0 : elem.parentElement) {
1256
- if (((_a = elem.parentElement) == null ? void 0 : _a.tagName.toLowerCase()) === "form") {
1257
- return elem.parentElement;
1258
- } else {
1259
- return getParentForm(elem.parentElement);
1260
- }
1261
- } else {
1262
- return null;
1263
- }
1264
- }
1265
- const form = getParentForm(fileInput);
1266
- if (form) {
1267
- form.dispatchEvent(new Event("change"));
1268
- }
1269
- }
1270
- getDescription() {
1271
- return `Upload file in ${this.getElementName()}`;
1272
- }
1273
- getJSON() {
1274
- return {
1275
- ...super.getJSON(),
1276
- type: "UploadFile"
1277
- };
1278
- }
1279
- }
1280
- class SaveValueAction extends ActionOnElement {
1281
- constructor(uiElement, memorySlotName) {
1282
- super(uiElement);
1283
- __publicField(this, "memorySlotName");
1284
- this.memorySlotName = memorySlotName;
1285
- }
1286
- executeActionOnElement() {
1287
- var _a, _b, _c, _d;
1288
- let inputElem = this.element;
1289
- if (((_a = this.element) == null ? void 0 : _a.tagName) !== "INPUT" && ((_b = this.element) == null ? void 0 : _b.tagName) !== "SELECT" && ((_c = this.element) == null ? void 0 : _c.tagName) !== "TEXTAREA") {
1290
- inputElem = (_d = this.element) == null ? void 0 : _d.querySelectorAll("input")[0];
1291
- if (!inputElem) {
1292
- throw new Error("Input element not found. Not able to save value from element " + this.getElementName());
1293
- }
1294
- }
1295
- AutomationEvents.dispatch(EVENT_NAMES.SAVE_VALUE, {
1296
- memorySlotName: this.memorySlotName,
1297
- value: inputElem.value
1298
- });
1299
- }
1300
- getDescription() {
1301
- return `Save value of ${this.getElementName()} in ${this.memorySlotName}`;
1302
- }
1303
- getJSON() {
1304
- return {
1305
- ...super.getJSON(),
1306
- type: "SaveValue",
1307
- memorySlotName: this.memorySlotName
1308
- };
1309
- }
1310
- }
1311
- class WaitAction extends AbstractAction {
1312
- constructor(miliseconds) {
1313
- super();
1314
- __publicField(this, "miliseconds");
1315
- this.miliseconds = miliseconds;
1316
- }
1317
- getDescription() {
1318
- return "Wait " + this.miliseconds + " miliseconds";
1319
- }
1320
- getJSON() {
1321
- return {
1322
- ...super.getJSON(),
1323
- type: "Wait"
1324
- };
1325
- }
1326
- async executeAction() {
1327
- await wait(this.miliseconds);
1328
- }
1329
- resetAction() {
1330
- }
1331
- }
1332
- class WaitUntilElementRemovedAction extends AbstractAction {
1333
- constructor(uiElement) {
1334
- super();
1335
- __publicField(this, "uiElement");
1336
- __publicField(this, "tries");
1337
- this.uiElement = uiElement;
1338
- this.tries = 0;
1339
- }
1340
- updateTries(tries) {
1341
- this.tries = tries;
1342
- }
1343
- resetAction() {
1344
- this.tries = 0;
1345
- }
1346
- getElementName() {
1347
- var _a;
1348
- return (_a = this.uiElement) == null ? void 0 : _a.getElementName();
1349
- }
1350
- async executeAction() {
1351
- await waitForElement(this, this.uiElement, 1e3, 10, true);
1352
- }
1353
- getDescription() {
1354
- return "Wait until " + this.getElementName() + " is removed";
1355
- }
1356
- getJSON() {
1357
- return {
1358
- ...super.getJSON(),
1359
- type: "WaitUntilElementRemoved"
1360
- };
1361
- }
1362
- }
1363
- class PauseAction extends AbstractAction {
1364
- constructor() {
1365
- super();
1366
- }
1367
- getDescription() {
1368
- return "Paused";
1369
- }
1370
- getJSON() {
1371
- return {
1372
- ...super.getJSON(),
1373
- type: "Pause"
1374
- };
1375
- }
1376
- async executeAction() {
1377
- await exports.AutomationInstance.pause();
1378
- }
1379
- resetAction() {
1380
- }
1381
- }
1382
- class ManualAction extends AbstractAction {
1383
- constructor(description) {
1384
- super();
1385
- __publicField(this, "description");
1386
- this.description = description;
1387
- }
1388
- getDescription() {
1389
- return "Manual Step: " + this.description;
1390
- }
1391
- getJSON() {
1392
- return {
1393
- ...super.getJSON(),
1394
- type: "ManualStep"
1395
- };
1396
- }
1397
- async executeAction() {
1398
- await exports.AutomationInstance.uiUtils.showAlert("Waiting manual step...");
1399
- return new Promise((resolve, reject) => {
1400
- AutomationEvents.on(EVENT_NAMES.USER_ACCEPT, async () => {
1401
- await exports.AutomationInstance.uiUtils.hideAlert();
1402
- return resolve(true);
1403
- });
1404
- AutomationEvents.on(EVENT_NAMES.USER_REJECT, async () => {
1405
- await exports.AutomationInstance.uiUtils.hideAlert();
1406
- return reject();
1407
- });
1408
- });
1409
- }
1410
- resetAction() {
1411
- }
1412
- }
1413
- class ReloadPageAction extends AbstractAction {
1414
- constructor() {
1415
- super();
1416
- }
1417
- getDescription() {
1418
- return "Reload page";
1419
- }
1420
- getJSON() {
1421
- return {
1422
- ...super.getJSON(),
1423
- type: "ReloadPage"
1424
- };
1425
- }
1426
- async executeAction() {
1427
- await location.reload();
1428
- }
1429
- resetAction() {
1430
- }
1431
- }
1432
- const formatDate = (date) => {
1433
- return date.toLocaleDateString("en-US", { year: "numeric", month: "2-digit", day: "2-digit" });
1434
- };
1435
- const setDateFromToday = (numberOfDays) => {
1436
- const date = /* @__PURE__ */ new Date();
1437
- return formatDate(new Date(date.setDate(date.getDate() + numberOfDays)));
1438
- };
1439
- const setMonthFromToday = (numberOfMonths) => {
1440
- const date = /* @__PURE__ */ new Date();
1441
- return formatDate(new Date(date.setMonth(date.getMonth() + numberOfMonths)));
1442
- };
1443
- const tomorrow = setDateFromToday(1);
1444
- const yesterday = setDateFromToday(-1);
1445
- const nextWeek = setDateFromToday(7);
1446
- const lastWeek = setDateFromToday(-7);
1447
- const nextMonth = setMonthFromToday(1);
1448
- const lastMonth = setMonthFromToday(-1);
1449
- const DateUtils = {
1450
- formatDate,
1451
- today: formatDate(/* @__PURE__ */ new Date()),
1452
- tomorrow,
1453
- nextWeek,
1454
- nextMonth,
1455
- yesterday,
1456
- lastWeek,
1457
- lastMonth
1458
- };
1459
- class Logger {
1460
- constructor() {
1461
- __publicField(this, "enabled", false);
1462
- }
1463
- setEnabled(enabled) {
1464
- this.enabled = enabled;
1465
- }
1466
- log(...args) {
1467
- if (this.enabled) {
1468
- console.log("[tomation]", ...args);
1469
- }
1470
- }
1471
- groupCollapsed(...args) {
1472
- if (this.enabled) {
1473
- console.groupCollapsed("[tomation]", ...args);
1474
- }
1475
- }
1476
- groupEnd() {
1477
- if (this.enabled) {
1478
- console.groupEnd();
1479
- }
1480
- }
1481
- error(...args) {
1482
- if (this.enabled) {
1483
- console.error("[tomation]", ...args);
1484
- }
1485
- }
1486
- }
1487
- const logger = new Logger();
1488
- const setAutomationLogs = (enabled) => {
1489
- logger.setEnabled(enabled);
1490
- };
1491
- const _AutomationCompiler = class _AutomationCompiler {
1492
- static compileAction(action) {
1493
- const previousAction = _AutomationCompiler.currentAction;
1494
- _AutomationCompiler.currentAction = action;
1495
- action.compileSteps();
1496
- _AutomationCompiler.currentAction = previousAction;
1497
- }
1498
- static addAction(action) {
1499
- logger.log("Add action: ", action.getDescription());
1500
- _AutomationCompiler.currentAction.addStep(action);
1501
- }
1502
- static init(startAction) {
1503
- _AutomationCompiler.currentAction = startAction;
1504
- _AutomationCompiler.isCompiling = true;
1505
- logger.groupCollapsed("Compile: " + startAction.getDescription());
1506
- startAction.compileSteps();
1507
- _AutomationCompiler.isCompiling = false;
1508
- logger.log("Compilation finished");
1509
- logger.groupEnd();
1510
- }
1511
- };
1512
- __publicField(_AutomationCompiler, "currentAction");
1513
- __publicField(_AutomationCompiler, "isCompiling");
1514
- let AutomationCompiler = _AutomationCompiler;
1515
- var EVENT_NAMES = /* @__PURE__ */ ((EVENT_NAMES2) => {
1516
- EVENT_NAMES2["ACTION_UPDATE"] = "tomation-action-update";
1517
- EVENT_NAMES2["SAVE_VALUE"] = "tomation-save-value";
1518
- EVENT_NAMES2["REGISTER_TEST"] = "tomation-register-test";
1519
- EVENT_NAMES2["TEST_STARTED"] = "tomation-test-started";
1520
- EVENT_NAMES2["TEST_PASSED"] = "tomation-test-passed";
1521
- EVENT_NAMES2["TEST_FAILED"] = "tomation-test-failed";
1522
- EVENT_NAMES2["TEST_END"] = "tomation-test-end";
1523
- EVENT_NAMES2["TEST_STOP"] = "tomation-test-stop";
1524
- EVENT_NAMES2["USER_ACCEPT"] = "tomation-user-accept";
1525
- EVENT_NAMES2["USER_REJECT"] = "tomation-user-reject";
1526
- return EVENT_NAMES2;
1527
- })(EVENT_NAMES || {});
1528
- class EventDispatcher {
1529
- constructor() {
1530
- __publicField(this, "events");
1531
- this.events = /* @__PURE__ */ new Map();
1532
- }
1533
- on(eventName, callback) {
1534
- var _a;
1535
- if (!this.events.has(eventName)) {
1536
- this.events.set(eventName, []);
1537
- }
1538
- (_a = this.events.get(eventName)) == null ? void 0 : _a.push(callback);
1539
- }
1540
- off(eventName, callback) {
1541
- var _a;
1542
- if (this.events.has(eventName)) {
1543
- this.events.set(eventName, ((_a = this.events.get(eventName)) == null ? void 0 : _a.filter((cb) => cb !== callback)) || []);
1544
- }
1545
- }
1546
- dispatch(eventName, data) {
1547
- var _a;
1548
- if (this.events.has(eventName)) {
1549
- (_a = this.events.get(eventName)) == null ? void 0 : _a.forEach((callback) => {
1550
- console.log(`Dispatch Event ${eventName}:`, data);
1551
- callback(data);
1552
- });
1553
- }
1554
- }
1555
- }
1556
- const AutomationEvents = new EventDispatcher();
1557
- var TestSpeed = /* @__PURE__ */ ((TestSpeed2) => {
1558
- TestSpeed2[TestSpeed2["SLOW"] = 2e3] = "SLOW";
1559
- TestSpeed2[TestSpeed2["NORMAL"] = 1e3] = "NORMAL";
1560
- TestSpeed2[TestSpeed2["FAST"] = 200] = "FAST";
1561
- return TestSpeed2;
1562
- })(TestSpeed || {});
1563
- const _AutomationRunner = class _AutomationRunner {
1564
- static async start(startAction) {
1565
- if (_AutomationRunner.running) {
1566
- logger.error("Not able to run test while other test is running.");
1567
- throw new Error("Not able to run test while other test is running.");
1568
- }
1569
- _AutomationRunner.running = true;
1570
- exports.AutomationInstance.status = "Playing";
1571
- exports.AutomationInstance.runMode = "Normal";
1572
- logger.groupCollapsed("Start Action: ", startAction.getDescription());
1573
- AutomationEvents.dispatch("tomation-test-started", {
1574
- action: startAction == null ? void 0 : startAction.getJSON()
1575
- });
1576
- try {
1577
- await (startAction == null ? void 0 : startAction.execute());
1578
- AutomationEvents.dispatch("tomation-test-passed", { id: startAction.name });
1579
- } catch (e) {
1580
- AutomationEvents.dispatch("tomation-test-failed", { id: startAction.name });
1581
- exports.AutomationInstance.uiUtils.hideCheckElementContainer();
1582
- logger.error(`🤖 Error running task ${startAction.getDescription()}. Reason: ${e.message}`);
1583
- throw e;
1584
- } finally {
1585
- logger.groupEnd();
1586
- _AutomationRunner.running = false;
1587
- AutomationEvents.dispatch("tomation-test-end", {
1588
- action: startAction == null ? void 0 : startAction.getJSON()
1589
- });
1590
- }
1591
- }
1592
- };
1593
- __publicField(_AutomationRunner, "running", false);
1594
- let AutomationRunner = _AutomationRunner;
1595
- const TestsMap = {};
1596
- const Test = (id, steps) => {
1597
- console.log(`Registering Test: ${id}...`);
1598
- const action = new Action(id, steps);
1599
- AutomationCompiler.init(action);
1600
- console.log(`Compiled Test: ${id}`);
1601
- AutomationEvents.dispatch("tomation-register-test", { id, action: action.getJSON() });
1602
- console.log(`Registered Test: ${id} in TestsMap`);
1603
- TestsMap[id] = () => {
1604
- AutomationRunner.start(action);
1605
- };
1606
- };
1607
- const RunTest = (id) => {
1608
- if (!TestsMap[id]) {
1609
- console.log("Available Tests:", Object.keys(TestsMap));
1610
- throw new Error(`Test with id ${id} not found.`);
1611
- } else {
1612
- TestsMap[id]();
1613
- }
1614
- };
1615
- const Task = (id, steps) => {
1616
- return async (params) => {
1617
- const action = new Action(id, steps);
1618
- action.setParams(params);
1619
- if (!AutomationRunner.running && !AutomationCompiler.isCompiling) {
1620
- try {
1621
- logger.log(`Compilation of Task ${id} starts...`);
1622
- AutomationCompiler.init(action);
1623
- logger.log(`Compilation of Task ${id} Finished.`);
1624
- logger.log(`Start running Task ${id}...`);
1625
- await AutomationRunner.start(action);
1626
- logger.log(`End of Task ${id}: SUCCESS`);
1627
- } catch (e) {
1628
- logger.error("Error running task " + id + ". " + e.message);
1629
- }
1630
- } else {
1631
- logger.log(`Adding action ${id} to compilation stack`);
1632
- AutomationCompiler.addAction(action);
1633
- AutomationCompiler.compileAction(action);
1634
- }
1635
- };
1636
- };
1637
- const Click = (uiElement) => {
1638
- const action = new ClickAction(uiElement);
1639
- AutomationCompiler.addAction(action);
1640
- };
1641
- const Assert = (uiElement) => {
1642
- return {
1643
- textIs: (text) => {
1644
- AutomationCompiler.addAction(new AssertTextIsAction(uiElement, text));
1645
- },
1646
- containsText: (text) => {
1647
- AutomationCompiler.addAction(new AssertContainsTextAction(uiElement, text));
1648
- },
1649
- valueIs: (value) => {
1650
- AutomationCompiler.addAction(new AssertValueIsAction(uiElement, value));
1651
- },
1652
- exists: () => {
1653
- AutomationCompiler.addAction(new AssertExistsAction(uiElement));
1654
- },
1655
- notExists: () => {
1656
- AutomationCompiler.addAction(new AssertNotExistsAction(uiElement));
1657
- }
1658
- };
1659
- };
1660
- const Select = (value) => {
1661
- return {
1662
- in: (uiElement) => {
1663
- const action = new SelectAction(uiElement, value);
1664
- AutomationCompiler.addAction(action);
1665
- }
1666
- };
1667
- };
1668
- const Type = (value) => {
1669
- return {
1670
- in: (uiElement) => {
1671
- const action = new TypeAction(uiElement, value);
1672
- AutomationCompiler.addAction(action);
1673
- }
1674
- };
1675
- };
1676
- const ClearValue = () => {
1677
- return {
1678
- in: (uiElement) => {
1679
- const action = new TypeAction(uiElement, "");
1680
- AutomationCompiler.addAction(action);
1681
- }
1682
- };
1683
- };
1684
- const PressEscKey = () => {
1685
- return {
1686
- in: (uiElement) => {
1687
- AutomationCompiler.addAction(new PressEscKeyAction(uiElement));
1688
- }
1689
- };
1690
- };
1691
- const PressDownKey = () => {
1692
- return {
1693
- in: (uiElement) => {
1694
- AutomationCompiler.addAction(new PressDownKeyAction(uiElement));
1695
- }
1696
- };
1697
- };
1698
- const PressTabKey = () => {
1699
- return {
1700
- in: (uiElement) => {
1701
- AutomationCompiler.addAction(new PressTabKeyAction(uiElement));
1702
- }
1703
- };
1704
- };
1705
- const TypePassword = (value) => {
1706
- return {
1707
- in: (uiElement) => {
1708
- const action = new TypePasswordAction(uiElement, value);
1709
- AutomationCompiler.addAction(action);
1710
- }
1711
- };
1712
- };
1713
- const UploadFile = (file) => {
1714
- return {
1715
- in: (uiElement) => {
1716
- const action = new UploadFileAction(uiElement, file);
1717
- AutomationCompiler.addAction(action);
1718
- }
1719
- };
1720
- };
1721
- const SaveValue = (uiElement) => {
1722
- return {
1723
- in: (memorySlotName) => {
1724
- const action = new SaveValueAction(uiElement, memorySlotName);
1725
- AutomationCompiler.addAction(action);
1726
- }
1727
- };
1728
- };
1729
- const Wait = (miliseconds) => {
1730
- AutomationCompiler.addAction(new WaitAction(miliseconds));
1731
- };
1732
- Wait.untilElement = (uiElement) => {
1733
- return {
1734
- isRemoved: () => {
1735
- AutomationCompiler.addAction(new WaitUntilElementRemovedAction(uiElement));
1736
- }
1737
- };
1738
- };
1739
- const Pause = () => {
1740
- AutomationCompiler.addAction(new PauseAction());
1741
- };
1742
- const ManualTask = (description) => {
1743
- AutomationCompiler.addAction(new ManualAction(description));
1744
- };
1745
- const ReloadPage = () => {
1746
- AutomationCompiler.addAction(new ReloadPageAction());
1747
- };
1748
- class Automation {
1749
- constructor(window2) {
1750
- __publicField(this, "_document");
1751
- __publicField(this, "debug");
1752
- __publicField(this, "_uiUtils");
1753
- __publicField(this, "speed");
1754
- __publicField(this, "status");
1755
- __publicField(this, "runMode");
1756
- __publicField(this, "currentActionCallback");
1757
- __publicField(this, "currentAction");
1758
- this._document = window2.document;
1759
- this.debug = true;
1760
- this._uiUtils = new UIUtils(window2);
1761
- this.speed = 1e3;
1762
- this.status = "Stopped";
1763
- this.runMode = "Normal";
1764
- }
1765
- get document() {
1766
- return this._document;
1767
- }
1768
- get uiUtils() {
1769
- return this._uiUtils;
1770
- }
1771
- get isStepByStepMode() {
1772
- return this.runMode == "Step By Step";
1773
- }
1774
- get isStopped() {
1775
- return this.status == "Stopped";
1776
- }
1777
- get isPlaying() {
1778
- return this.status == "Playing";
1779
- }
1780
- get isPaused() {
1781
- return this.status == "Paused";
1782
- }
1783
- pause() {
1784
- logger.log("Pause Test");
1785
- this.status = "Paused";
1786
- }
1787
- continue() {
1788
- logger.log("Continue Test");
1789
- this.status = "Playing";
1790
- this.runMode = "Normal";
1791
- if (this.currentActionCallback && this.currentAction) {
1792
- logger.log("Continue: Executing current action callback");
1793
- this.currentActionCallback(this.currentAction);
1794
- this.currentActionCallback = void 0;
1795
- }
1796
- }
1797
- next() {
1798
- logger.log("Continue Test to Next Step...");
1799
- this.status = "Playing";
1800
- this.runMode = "Step By Step";
1801
- if (this.currentActionCallback && this.currentAction) {
1802
- logger.log("Next: Executing current action callback");
1803
- this.currentActionCallback(this.currentAction);
1804
- this.currentActionCallback = void 0;
1805
- }
1806
- }
1807
- stop() {
1808
- logger.log("Stop Test");
1809
- this.status = "Stopped";
1810
- if (this.currentActionCallback && this.currentAction) {
1811
- logger.log("Stop: Executing current action callback");
1812
- this.currentActionCallback(this.currentAction);
1813
- this.currentActionCallback = void 0;
1814
- }
1815
- AutomationEvents.dispatch(
1816
- "tomation-test-stop"
1817
- /* TEST_STOP */
1818
- );
1819
- }
1820
- retryAction() {
1821
- logger.log("Retry current step");
1822
- this.status = "Playing";
1823
- if (this.currentActionCallback && this.currentAction) {
1824
- if (this.currentAction.resetTries) {
1825
- logger.log("Retry: Resetting tries for current action");
1826
- this.currentAction.resetTries();
1827
- }
1828
- logger.log("Retry: Executing current action callback");
1829
- this.currentActionCallback(this.currentAction);
1830
- this.currentActionCallback = void 0;
1831
- }
1832
- }
1833
- skipAction() {
1834
- logger.log("Skip current step");
1835
- this.status = "Playing";
1836
- if (this.currentActionCallback && this.currentAction) {
1837
- this.currentAction.status = ACTION_STATUS.SKIPPED;
1838
- logger.log("Skip: Marked current action as SKIPPED");
1839
- AbstractAction.notifyActionUpdated(this.currentAction);
1840
- logger.log("Skip: Executing current action callback");
1841
- this.currentActionCallback(this.currentAction);
1842
- this.currentActionCallback = void 0;
1843
- }
1844
- }
1845
- saveCurrentAction(callback, action) {
1846
- logger.log("Save current action");
1847
- this.currentActionCallback = callback;
1848
- this.currentAction = action;
1849
- }
1850
- setDebug(value) {
1851
- setAutomationLogs(value);
1852
- }
1853
- }
1854
- exports.AutomationInstance = void 0;
1855
- const Setup = (window2, tests) => {
1856
- exports.AutomationInstance = new Automation(window2);
1857
- setDocument(exports.AutomationInstance.document);
1858
- tests == null ? void 0 : tests.forEach((installerFn) => installerFn());
1859
- return exports.AutomationInstance;
1860
- };
1861
- function tomation(options) {
1862
- const {
1863
- matches,
1864
- tests = [],
1865
- speed = "NORMAL",
1866
- debug = false
1867
- } = options;
1868
- const shouldRun = typeof matches === "string" ? document.location.href.includes(matches) : !!document.location.href.match(matches);
1869
- if (!shouldRun) {
1870
- console.log(`[tomation] URL "${document.location.href}" does not match "${matches}"`);
1871
- return;
1872
- }
1873
- try {
1874
- console.log("[tomation] Setting up messaging bridge with extension...");
1875
- Object.values(EVENT_NAMES).forEach((event) => {
1876
- console.log(`[tomation] Setting up listener for event "${event}"`);
1877
- AutomationEvents.on(event, (data) => {
1878
- console.log(`[tomation] Dispatching event "${event}" to extension`, data);
1879
- window.postMessage({
1880
- message: "injectedScript-to-contentScript",
1881
- sender: "tomation",
1882
- payload: {
1883
- cmd: event,
1884
- params: data
1885
- }
1886
- });
1887
- });
1888
- });
1889
- window.addEventListener("message", (event) => {
1890
- try {
1891
- console.log("[tomation] Received message from extension:", event.data);
1892
- const { message, sender, payload } = event.data || {};
1893
- const { cmd, params } = payload || {};
1894
- if (sender !== "web-extension")
1895
- return;
1896
- if (message === "contentScript-to-injectedScript") {
1897
- const commands = {
1898
- "run-test-request": () => RunTest(params == null ? void 0 : params.testId),
1899
- "reload-tests-request": () => Setup(window, tests || []),
1900
- "pause-test-request": () => exports.AutomationInstance.pause(),
1901
- "stop-test-request": () => exports.AutomationInstance.stop(),
1902
- "continue-test-request": () => exports.AutomationInstance.continue(),
1903
- "next-step-request": () => exports.AutomationInstance.next(),
1904
- "retry-action-request": () => exports.AutomationInstance.retryAction(),
1905
- "skip-action-request": () => exports.AutomationInstance.skipAction(),
1906
- "user-accept-request": () => AutomationEvents.dispatch(
1907
- "tomation-user-accept"
1908
- /* USER_ACCEPT */
1909
- ),
1910
- "user-reject-request": () => AutomationEvents.dispatch(
1911
- "tomation-user-reject"
1912
- /* USER_REJECT */
1913
- )
1914
- };
1915
- const commandFn = commands[cmd];
1916
- if (commandFn) {
1917
- console.log(`[tomation] Executing command "${cmd}" from extension`);
1918
- commandFn();
1919
- } else {
1920
- console.warn(`[tomation] Unknown command "${cmd}" from extension`);
1921
- }
1922
- return;
1923
- }
1924
- } catch (err) {
1925
- console.error("[tomation] Error handling message from extension:", err);
1926
- }
1927
- });
1928
- Setup(window, tests);
1929
- exports.AutomationInstance.setDebug(debug);
1930
- exports.AutomationInstance.speed = TestSpeed[speed];
1931
- console.log("[tomation] Ready ✓");
1932
- } catch (err) {
1933
- console.error("[tomation] Initialization failed:", err);
1934
- }
1935
- }
1936
- exports.ACTION_STATUS = ACTION_STATUS;
1937
- exports.Assert = Assert;
1938
- exports.AutomationEvents = AutomationEvents;
1939
- exports.ClearValue = ClearValue;
1940
- exports.Click = Click;
1941
- exports.DateUtils = DateUtils;
1942
- exports.EVENT_NAMES = EVENT_NAMES;
1943
- exports.ManualTask = ManualTask;
1944
- exports.Pause = Pause;
1945
- exports.PressDownKey = PressDownKey;
1946
- exports.PressEscKey = PressEscKey;
1947
- exports.PressTabKey = PressTabKey;
1948
- exports.ReloadPage = ReloadPage;
1949
- exports.RunTest = RunTest;
1950
- exports.SaveValue = SaveValue;
1951
- exports.Select = Select;
1952
- exports.SelectorBuilder = SelectorBuilder;
1953
- exports.Setup = Setup;
1954
- exports.Task = Task;
1955
- exports.Test = Test;
1956
- exports.TestSpeed = TestSpeed;
1957
- exports.Type = Type;
1958
- exports.TypePassword = TypePassword;
1959
- exports.UIElement = UIElement;
1960
- exports.UploadFile = UploadFile;
1961
- exports.Wait = Wait;
1962
- exports.and = and;
1963
- exports.classIncludes = classIncludes;
1964
- exports.classIs = classIs;
1965
- exports.default = tomation;
1966
- exports.elementIndexIs = elementIndexIs;
1967
- exports.firstChildTextIs = firstChildTextIs;
1968
- exports.innerTextContains = innerTextContains;
1969
- exports.innerTextIs = innerTextIs;
1970
- exports.is = is;
1971
- exports.isFirstElement = isFirstElement;
1972
- exports.placeholderIs = placeholderIs;
1973
- exports.setAutomationLogs = setAutomationLogs;
1974
- exports.setFilterLogs = setFilterLogs;
1975
- exports.titleIs = titleIs;
1976
- exports.tomation = tomation;
1977
- exports.wait = wait;
1
+ "use strict";var ce=Object.defineProperty;var le=(t,e,n)=>e in t?ce(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var i=(t,e,n)=>(le(t,typeof e!="symbol"?e+"":e,n),n);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});class Q{constructor(e,n,s,o){i(this,"name");i(this,"selector");i(this,"parent");i(this,"postProcess");this.name=e,this.selector=n,this.parent=s||null,this.postProcess=o}getElementName(){let e="";return this.parent&&(e=" in "+this.parent.getElementName()),`${this.name}${e}`}}let M;const ue=t=>{M=t},q=(t,e)=>(s=M,o)=>{s=s||M,console.log("Searching elem from Root = ",s);const a=[];s.querySelectorAll(t).forEach(c=>{c.style.display!=="none"&&a.push(c)});let r;return e?(console.log("Applying filter ",e),console.log(" -- to "+a.length+"elements: ",a),r=a.filter((c,y,x)=>{console.log("Apply filter to item "+y+": ",c);const m=e(c,y,x);return console.log(` -> Item ${y} ${m?"Match":"Discarded"}`),m})[0]):r=a[0],r&&o&&(console.log("Apply post process to = ",r),r=o(r)),console.log("Return elem = ",r),r},$=(t,e,n)=>({as:s=>new Q(s,t,e,n)}),he=(t,e)=>({...$(t,e),postProcess:n=>({...$(t,e,n)})}),Z=t=>({...$(t,null),childOf:e=>({...he(t,e)}),postProcess:e=>({...$(t,null,e)})}),O=t=>({where:e=>Z(q(t,e))}),de=O("div"),pe=O("button"),me=O("input"),ge=O("textarea"),ye=t=>Z(q("#"+t)),Ee=t=>O(t);let Y=!1;const we=t=>{Y=t},f=(...t)=>{Y&&console.log("[UIElement Filter]",...t)},fe=t=>e=>{const n=e.className==t;return f(`classIs('${t}') on`,e,"=>",n),n},Ae=t=>e=>{const n=e.className.split(" ").includes(t);return f(`classIncludes('${t}') on`,e,"=>",n),n},xe=t=>e=>{var s;const n=((s=e.textContent)==null?void 0:s.trim())==t;return f(`innerTextIs('${t}') on`,e,"=>",n),n},Ce=t=>e=>{const n=e.innerText.trim().includes(t);return f(`innerTextContains('${t}') on`,e,"=>",n),n},Te=t=>e=>{const n=e.title==t;return f(`titleIs('${t}') on`,e,"=>",n),n},ke=t=>e=>{const n=e.placeholder===t;return f(`placeholderIs('${t}') on`,e,"=>",n),n},Se=()=>(t,e)=>{const n=e===0;return f("isFirstElement on",t,"index",e,"=>",n),n},Ie=t=>(e,n)=>{const s=n===t;return f(`elementIndexIs(${t}) on`,e,"elemIndex",n,"=>",s),s},ve=t=>e=>{const n=(e==null?void 0:e.firstChild).innerText.trim()===t;return f(`firstChildTextIs('${t}') on`,e,"=>",n),n},Ne=t=>(e,n)=>{const s=t.every((o,a)=>{const r=o(e,n);return f(`and condition[${a}] on`,e,"elemIndex",n,"=>",r),r});return f("and final result on",e,"elemIndex",n,"=>",s),s},be={DIV:de,BUTTON:pe,INPUT:me,TEXTAREA:ge,ELEMENT:Ee,identifiedBy:ye};let P;const Oe=new Uint8Array(16);function De(){if(!P&&(P=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!P))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return P(Oe)}const p=[];for(let t=0;t<256;++t)p.push((t+256).toString(16).slice(1));function Pe(t,e=0){return(p[t[e+0]]+p[t[e+1]]+p[t[e+2]]+p[t[e+3]]+"-"+p[t[e+4]]+p[t[e+5]]+"-"+p[t[e+6]]+p[t[e+7]]+"-"+p[t[e+8]]+p[t[e+9]]+"-"+p[t[e+10]]+p[t[e+11]]+p[t[e+12]]+p[t[e+13]]+p[t[e+14]]+p[t[e+15]]).toLowerCase()}const Le=typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto),X={randomUUID:Le};function _(t,e,n){if(X.randomUUID&&!e&&!t)return X.randomUUID();t=t||{};const s=t.random||(t.rng||De)();if(s[6]=s[6]&15|64,s[8]=s[8]&63|128,e){n=n||0;for(let o=0;o<16;++o)e[n+o]=s[o];return e}return Pe(s)}const E=(t=2e3)=>new Promise(e=>{setTimeout(()=>{e(null)},t)}),A=(t,e)=>{Object.entries(e).map(([s,o])=>({key:s,value:o})).forEach(s=>{const{key:o,value:a}=s;t.style[o]=a})};class Ue{constructor(e){i(this,"window");i(this,"document");i(this,"devToolsMessageContainer");i(this,"devToolsCheckElementContainer");i(this,"darkLayerLeft");i(this,"darkLayerTop");i(this,"darkLayerRight");i(this,"darkLayerBottom");i(this,"currentCheckElem");i(this,"contextViewerContainer");i(this,"devToolsAlertContainer");this.document=e.document,this.window=e,this.devToolsMessageContainer=this.createElement("DIV",{id:"dev-tools-message-container",styles:{width:"500px",backgroundColor:"rgba(0, 0, 0, 0.5)",color:"white",position:"fixed",bottom:"10px",right:"10px",fontFamily:"monospace",zIndex:"9999"},parent:this.document.body}),this.devToolsAlertContainer=this.createElement("DIV",{id:"dev-tools-alert-container",styles:{width:"100%",height:"30px",backgroundColor:"#b00",color:"white",position:"absolute ",top:0,fontFamily:"monospace",zIndex:"9999",display:"none",alignItems:"center",justifyContent:"center",padding:"5px"},parent:this.document.body}),this.devToolsCheckElementContainer=this.createElement("DIV",{id:"dev-tools-check-element-container",styles:{width:"100%",height:this.document.body.clientHeight+"px",position:"absolute",top:"0px",left:"0px",zIndex:"9990",display:"none",opacity:"0",transition:"opacity .2s"},parent:this.document.body});const n={zIndex:"9991",backgroundColor:"rgba(0,0,0,0.3)",position:"absolute"};this.darkLayerLeft=this.createElement("DIV",{id:"dark-layer-left",styles:n,parent:this.devToolsCheckElementContainer}),this.darkLayerTop=this.createElement("DIV",{id:"dark-layer-top",styles:n,parent:this.devToolsCheckElementContainer}),this.darkLayerRight=this.createElement("DIV",{id:"dark-layer-right",styles:n,parent:this.devToolsCheckElementContainer}),this.darkLayerBottom=this.createElement("DIV",{id:"dark-layer-bottom",styles:n,parent:this.devToolsCheckElementContainer}),this.currentCheckElem=this.createElement("DIV",{id:"current-check-elem",parent:this.devToolsCheckElementContainer}),this.contextViewerContainer=this.createElement("DIV",{id:"context-viewer-container",styles:{width:"100%",height:this.document.body.clientHeight+"px",position:"absolute",top:"0px",left:"0px",zIndex:"10000",display:"none"},parent:this.document.body})}createElement(e,n){const s=this.document.createElement(e);return n&&(n.id&&(s.id=n==null?void 0:n.id),n.styles&&A(s,n.styles),n.parent&&n.parent.appendChild(s)),s}async logAction(e){const n=exports.AutomationInstance.document.createElement("DIV");n.innerText=e,A(n,{padding:"3px 10px",opacity:"1",transition:"opacity 1s"}),this.devToolsMessageContainer.appendChild(n),await E(4e3),n.style.opacity="0",await E(4e3),this.devToolsMessageContainer.removeChild(n),await E(1e3)}async checkElement(e,n){if(!e)return;const s=e.getBoundingClientRect(),o=this.document.body.getBoundingClientRect();this.darkLayerLeft.style.left="0px",this.darkLayerLeft.style.top=s.top+"px",this.darkLayerLeft.style.width=this.window.scrollX+s.left+"px",this.darkLayerLeft.style.height=s.height+"px",this.darkLayerTop.style.left=this.window.scrollX+"px",this.darkLayerTop.style.top="0px",this.darkLayerTop.style.width="100%",this.darkLayerTop.style.height=s.top+"px",this.darkLayerRight.style.left=this.window.scrollX+s.left+s.width+"px",this.darkLayerRight.style.top=s.top+"px",this.darkLayerRight.style.width=o.width-(s.left+s.width)+"px",this.darkLayerRight.style.height=s.height+"px",this.darkLayerBottom.style.left=this.window.scrollX+"px",this.darkLayerBottom.style.top=s.top+s.height+"px",this.darkLayerBottom.style.width="100%",this.darkLayerBottom.style.height=o.height-(s.top+s.height)+"px",this.currentCheckElem.id=`dev-tools-current-check-elem-${n}`,this.currentCheckElem.style.top=s.top+"px",this.currentCheckElem.style.left=this.window.scrollX+s.left+"px",this.currentCheckElem.style.height=s.height+"px",this.currentCheckElem.style.width=s.width+"px",this.currentCheckElem.style.boxShadow="0px 0px 5px 2px lightgreen",this.currentCheckElem.style.position="absolute",this.currentCheckElem.style.zIndex="9992",this.devToolsCheckElementContainer.style.display="block",this.devToolsCheckElementContainer.style.opacity="1",await E(200)}async showAlert(e){const n=exports.AutomationInstance.document.createElement("DIV"),s=exports.AutomationInstance.document.body;n.innerText=e,A(s,{paddingTop:"30px"}),A(this.devToolsAlertContainer,{display:"flex"}),this.devToolsAlertContainer.appendChild(n)}async hideAlert(){A(this.devToolsAlertContainer,{display:"none"});const e=exports.AutomationInstance.document.body;A(e,{paddingTop:"0"}),this.devToolsAlertContainer.firstChild&&this.devToolsAlertContainer.removeChild(this.devToolsAlertContainer.firstChild)}async hideCheckElementContainer(){this.devToolsCheckElementContainer.style.opacity="0",await E(200),this.devToolsCheckElementContainer.style.display="none"}displayContext(e){A(this.contextViewerContainer,{display:"flex","background-color":"white",position:"absolute",top:"0px",left:"0px","z-index":"9999"});const n=this.document.createElement("DIV");n.id="context-viewer-before",A(n,{flex:"50%",width:"100%",height:"auto",border:"2px solid orange"});const s=this.document.createElement("DIV");s.id="context-viewer-after",A(s,{flex:"50%",width:"100%",height:"auto",border:"2px solid green"});const o=this.document.createElement("DIV");o.innerHTML=e.beforeHTML,z(o,e.beforeInputValues);const a=this.document.createElement("DIV");a.innerHTML=e.afterHTML,z(a,e.afterInputValues),this.contextViewerContainer.appendChild(n),n.appendChild(o),setTimeout(()=>{this.contextViewerContainer.removeChild(n),this.contextViewerContainer.appendChild(s),s.appendChild(a),setTimeout(()=>{this.contextViewerContainer.removeChild(s),A(this.contextViewerContainer,{display:"none"})},2e3)},2e3)}}const z=(t,e)=>{t.querySelectorAll("input").forEach(n=>{const s=n.getAttribute("input-id")||"";n.value=e[s]})},W=null,L=async(t,e,n,s=1e3,o=0,a=10,r=!1)=>{if(console.log("Automation Status: ",exports.AutomationInstance.status),exports.AutomationInstance.isPaused)return new Promise((c,y)=>{exports.AutomationInstance.saveCurrentAction(async x=>{if(x.status=="skipped")return c(null);try{const m=await L(x,e,n,s,o,a,r);c(m)}catch(m){y(m)}},t)});if(exports.AutomationInstance.isStopped)throw new Error("Test stopped manually");if(console.groupCollapsed(`tries ${o}/${a}`),t&&(t.updateTries(o),await g.notifyActionUpdated(t)),o===a)throw console.groupEnd(),r?new Error(`UI Element ${e.getElementName()||"UNKNOWN"} still present after 10 tries`):new Error(`UI Element ${e.getElementName()||"UNKNOWN"} not found after 10 tries`);{const c=e.selector(n,e.postProcess);return console.groupEnd(),c?r?(await E(s),await L(t,e,n,s,++o,a,r)):(console.log("Element found = ",c),c):r?(console.log("Element removed."),W):(await E(s),await L(t,e,n,s,++o,a,r))}},J=async(t,e,n=1e3,s=10,o=!1)=>{const a=e==null?void 0:e.getElementName();console.group("Looking for Element: "+a);let r=null;if(e.parent)try{console.groupCollapsed("Look for Parent ",e.parent.getElementName()),r=await J(t,e.parent,n,s,o),console.groupEnd()}catch(c){if(console.groupEnd(),o&&c.message.includes("not found"))return console.log("Parent not found, so element was removed"),console.groupEnd(),W;throw console.groupEnd(),c}try{console.log("Using parent element: ",r);const c=await L(t,e,r,n,0,s,o);return console.groupEnd(),c}catch(c){if(o&&c.message.includes("not found"))return console.log("Parent not found, so element was removed"),console.groupEnd(),W;throw console.groupEnd(),c}};var H=(t=>(t.WAITING="waiting",t.RUNNING="running",t.STOPPED="stopped",t.PAUSED="paused",t.SUCCESS="success",t.ERROR="error",t.SKIPPED="skipped",t))(H||{});class g{constructor(){i(this,"status");i(this,"error");i(this,"id");i(this,"context");this.status="waiting",this.error="",this.id=_(),this.context={beforeHTML:"",beforeInputValues:{},afterInputValues:{},afterHTML:"",url:"",startTimestamp:"",endTimestamp:""}}getJSON(){return{id:this.id,description:this.getDescription(),context:this.context,status:this.status,error:this.error}}reset(){this.status="waiting",this.error="",this.resetAction()}getInputValuesFromPage(){const e={};return exports.AutomationInstance.document.querySelectorAll("input").forEach((s,o)=>{const a=`value-id-${o}`;s.setAttribute("input-id",a),e[a]=s.value}),e}async execute(){try{this.status="running",this.context.beforeInputValues=this.getInputValuesFromPage(),this.context.beforeHTML=exports.AutomationInstance.document.body.innerHTML,await g.notifyActionUpdated(this),console.log("Action: ",this.getDescription()),await this.executeAction(),this.status="success",this.error="",exports.AutomationInstance.isStepByStepMode&&exports.AutomationInstance.pause()}catch(e){if(this.status="error",this.error=e.message,e.message=="Test stopped manually")throw Error("Error in Action "+this.getDescription()+". Message: "+e.message);this.status="paused",exports.AutomationInstance.pause()}finally{this.context.afterInputValues=this.getInputValuesFromPage(),this.context.afterHTML=exports.AutomationInstance.document.body.innerHTML,await g.notifyActionUpdated(this)}}static async notifyActionUpdated(e){h.dispatch(k.ACTION_UPDATE,{action:e.getJSON()})}}class ee extends g{constructor(n,s){super();i(this,"name");i(this,"stepsFn");i(this,"steps");i(this,"params");i(this,"index");this.name=n,this.stepsFn=s,this.steps=[],this.index=0}getDescription(){return this.name}compileSteps(){super.reset(),this.stepsFn(this.params)}stepsToJSON(){return this.steps.reduce((n,s)=>(n.push(s.getJSON()),n),[])}getJSON(){return{...super.getJSON(),type:"Action",params:this.params,steps:this.stepsToJSON()}}resetAction(){this.steps.length=0,this.index=0}async continue(){if(exports.AutomationInstance.isPaused)return new Promise((n,s)=>{exports.AutomationInstance.saveCurrentAction(async o=>{if(o.status=="skipped")return n();try{await o.continue(),n()}catch(a){s(a)}},this)});if(exports.AutomationInstance.isStopped)throw new Error("Test stopped manually");if(this.index<this.steps.length){const n=this.steps[this.index];try{if(await E(exports.AutomationInstance.speed),await n.execute(),!exports.AutomationInstance.isPaused)this.index++,await this.continue();else return new Promise((s,o)=>{exports.AutomationInstance.saveCurrentAction(async a=>{if(a.status=="skipped")return this.index++,await g.notifyActionUpdated(n),await this.continue(),s();try{await a.continue(),s()}catch(r){o(r)}},n)})}catch(s){throw s}}}async executeAction(){this.index=0,await this.continue()}setParams(n){this.params=n}addStep(n){this.steps.push(n)}}class d extends g{constructor(n){super();i(this,"uiElement");i(this,"element");i(this,"tries");this.uiElement=n,this.element=null,this.tries=0}getElementName(){var n;return(n=this.uiElement)==null?void 0:n.getElementName()}updateTries(n){this.tries=n}resetTries(){this.tries=0}getJSON(){return{id:this.id,element:this.getElementName(),description:this.getDescription(),status:this.status,error:this.error,context:this.context,tries:this.tries}}static waitForElement(n,s,o=1e3,a=10,r=!1){const c=s.getElementName();return new Promise(async(y,x)=>{var I;const m=async(C,D=1e3,v=0,N=!1)=>{if(console.groupCollapsed(`tries ${v}/${a}`),n.updateTries(v),await g.notifyActionUpdated(n),v===a)throw console.groupEnd(),N?new Error(`UI Element ${c||"UNKNOWN"} still present after 10 tries`):new Error(`UI Element ${c||"UNKNOWN"} not found after 10 tries`);{const F=s.selector(C,s.postProcess);return console.groupEnd(),F?N?(await E(D),await m(C,D,++v,N)):(console.log("Element found = ",F),F):N?(console.log("Element removed."),null):(await E(D),await m(C,D,++v,N))}};console.group("[Action On Element] Looking for Element: "+c);let T=null,V=!0;if(s.parent){console.groupCollapsed("Look for Parent ",s.parent.getElementName());try{T=await d.waitForElement(n,s.parent,o,a,r)}catch{V=!1}finally{console.groupEnd()}}if(V){console.log("using parent element: ",T);try{const C=await m(T,o,0,r);console.groupEnd(),y(C)}catch(C){console.groupEnd(),x(new Error(C.message))}}else console.groupEnd(),x(new Error(`Parent ${(I=s.parent)==null?void 0:I.getElementName()} of UI Element ${s.name||"UNKNOWN"} not found`))})}async executeAction(){var n;try{this.element=await J(this,this.uiElement),(n=this.element)==null||n.setAttribute("test-id",this.getElementName()),await exports.AutomationInstance.uiUtils.checkElement(this.element,this.getElementName()),this.executeActionOnElement(),await exports.AutomationInstance.uiUtils.hideCheckElementContainer()}catch(s){throw Error(s.message)}}resetAction(){this.element=null,this.resetTries()}}class $e extends d{constructor(e){super(e)}executeActionOnElement(){var e;return(e=this.element)==null?void 0:e.click()}getDescription(){return"Click in "+this.getElementName()}getJSON(){return{...super.getJSON(),type:"Click"}}}class Re extends d{constructor(n,s){super(n);i(this,"text");this.text=s}executeActionOnElement(){var s;if(!(((s=this.element)==null?void 0:s.innerText)===this.text))throw new Error(`Text in element ${this.getElementName()} is not '${this.text}'`)}getDescription(){return`Assert that text in ${this.getElementName()} is '${this.text}'`}getJSON(){return{...super.getJSON(),type:"AssertTextIsAction",value:this.text}}}class Je extends d{constructor(n,s){super(n);i(this,"text");this.text=s}executeActionOnElement(){var s;if(!((s=this.element)==null?void 0:s.innerText.includes(this.text)))throw new Error(`Text in element ${this.getElementName()} doesn't contain '${this.text}'`)}getDescription(){return`Assert that ${this.getElementName()} contains '${this.text}'`}getJSON(){return{...super.getJSON(),type:"AssertContainsText",value:this.text}}}class Ke extends d{constructor(n,s){super(n);i(this,"value");this.value=s}executeActionOnElement(){if(!(this.element.value===this.value))throw new Error(`Value in element ${this.getElementName()} is not '${this.value}'`)}getDescription(){return`Assert that value in ${this.getElementName()} is '${this.value}'`}getJSON(){return{...super.getJSON(),type:"AssertValueIsAction",value:this.value}}}class Ve extends d{constructor(e){super(e)}executeActionOnElement(){if(!!!this.element)throw new Error(`Element ${this.getElementName()} doesn't exist`)}getDescription(){return`Assert that ${this.getElementName()} exists`}getJSON(){return{...super.getJSON(),type:"AssertExistsAction"}}}class Fe extends d{constructor(e){super(e)}async executeAction(){var e;try{this.element=await J(this,this.uiElement,1e3,5,!0),(e=this.element)==null||e.setAttribute("test-id",this.getElementName()),await exports.AutomationInstance.uiUtils.checkElement(this.element,this.getElementName()),this.executeActionOnElement(),await exports.AutomationInstance.uiUtils.hideCheckElementContainer()}catch(n){throw Error(n.message)}}executeActionOnElement(){if(!!this.element)throw new Error(`Element ${this.getElementName()} was not expected to exist`)}getDescription(){return`Assert that ${this.getElementName()} doesn't exist`}getJSON(){return{...super.getJSON(),type:"AssertNotExistsAction"}}}class Me extends d{constructor(n,s){super(n);i(this,"value");this.value=s}executeActionOnElement(){var s,o,a,r;let n=this.element;if(((s=this.element)==null?void 0:s.tagName)!=="INPUT"&&((o=this.element)==null?void 0:o.tagName)!=="SELECT"&&((a=this.element)==null?void 0:a.tagName)!=="TEXTAREA"&&(n=(r=this.element)==null?void 0:r.querySelectorAll("input")[0],!n))throw new Error("Input element not found. Not able to type value in element "+this.getElementName());n.value=this.value,n.dispatchEvent(new Event("change"))}getDescription(){return`Select value '${this.value}' in ${this.getElementName()}`}getJSON(){return{...super.getJSON(),type:"Select",value:this.value}}}class te extends d{constructor(n,s){super(n);i(this,"value");this.value=s}executeActionOnElement(){var s,o,a,r;let n=this.element;if(((s=this.element)==null?void 0:s.tagName)!=="INPUT"&&((o=this.element)==null?void 0:o.tagName)!=="SELECT"&&((a=this.element)==null?void 0:a.tagName)!=="TEXTAREA"&&(n=(r=this.element)==null?void 0:r.querySelectorAll("input")[0],!n))throw new Error("Input element not found. Not able to type value in element "+this.getElementName());n.value=this.value,n.dispatchEvent(new Event("change")),n.dispatchEvent(new Event("keyup",{bubbles:!0})),n.dispatchEvent(new Event("input",{bubbles:!0}))}getDescription(){return`Type value '${this.value}' in ${this.getElementName()}`}getJSON(){return{...super.getJSON(),type:"Type",value:this.value}}}class We extends d{constructor(n,s){super(n);i(this,"value");this.value=s}executeActionOnElement(){var s,o,a,r;let n=this.element;if(((s=this.element)==null?void 0:s.tagName)!=="INPUT"&&((o=this.element)==null?void 0:o.tagName)!=="SELECT"&&((a=this.element)==null?void 0:a.tagName)!=="TEXTAREA"&&(n=(r=this.element)==null?void 0:r.querySelectorAll("input")[0],!n))throw new Error("Input element not found. Not able to type value in element "+this.getElementName());n.value=this.value,n.dispatchEvent(new Event("change")),n.dispatchEvent(new Event("keyup",{bubbles:!0})),n.dispatchEvent(new Event("input",{bubbles:!0}))}getDescription(){return`Type a password in ${this.getElementName()}`}getJSON(){return{...super.getJSON(),type:"TypePassword",value:this.value}}}class Be extends d{constructor(e){super(e)}executeActionOnElement(){var e;(e=this.element)==null||e.dispatchEvent(new KeyboardEvent("keydown",{altKey:!1,code:"Escape",ctrlKey:!1,isComposing:!1,key:"Escape",location:0,metaKey:!1,repeat:!1,shiftKey:!1,which:27,charCode:0,keyCode:27}))}getDescription(){return`Press Esc key in ${this.getElementName()}`}getJSON(){return{...super.getJSON(),type:"PressEscKey"}}}class qe extends d{constructor(e){super(e)}executeActionOnElement(){var e;(e=this.element)==null||e.dispatchEvent(new KeyboardEvent("keyup",{altKey:!1,code:"Down",ctrlKey:!1,isComposing:!1,key:"Down",location:0,metaKey:!1,repeat:!1,shiftKey:!1,which:40,charCode:0,keyCode:40}))}getDescription(){return`Press Down key in ${this.getElementName()}`}getJSON(){return{...super.getJSON(),type:"PressDownKey"}}}class He extends d{constructor(e){super(e)}executeActionOnElement(){var e;(e=this.element)==null||e.dispatchEvent(new KeyboardEvent("keydown",{altKey:!1,code:"Tab",ctrlKey:!1,isComposing:!1,key:"Tab",location:0,metaKey:!1,repeat:!1,shiftKey:!1,which:9,charCode:0,keyCode:9}))}getDescription(){return`Press Tab key in ${this.getElementName()}`}getJSON(){return{...super.getJSON(),type:"PressTabKey"}}}class je extends d{constructor(e){super(e)}executeActionOnElement(){var e;(e=this.element)==null||e.dispatchEvent(new KeyboardEvent("keydown",{altKey:!1,code:"Enter",ctrlKey:!1,isComposing:!1,key:"Enter",location:0,metaKey:!1,repeat:!1,shiftKey:!1,which:13,charCode:0,keyCode:13}))}getDescription(){return`Press Enter key in ${this.getElementName()}`}getJSON(){return{...super.getJSON(),type:"PressEnterKey"}}}var ne=(t=>(t.ESCAPE="Escape",t.ENTER="Enter",t.TAB="Tab",t.ARROW_DOWN="ArrowDown",t.ARROW_UP="ArrowUp",t.ARROW_LEFT="ArrowLeft",t.ARROW_RIGHT="ArrowRight",t.BACKSPACE="Backspace",t.DELETE="Delete",t.SHIFT="Shift",t.CONTROL="Control",t.ALT="Alt",t.META="Meta",t))(ne||{});const G={Escape:27,Enter:13,Tab:9,ArrowDown:40,ArrowUp:38,ArrowLeft:37,ArrowRight:39,Backspace:8,Delete:46,Shift:16,Control:17,Alt:18,Meta:91};class Xe extends d{constructor(n,s){super(n);i(this,"key");this.key=s}executeActionOnElement(){var n;(n=this.element)==null||n.dispatchEvent(new KeyboardEvent("keydown",{key:this.key,code:this.key,keyCode:G[this.key],charCode:0,which:G[this.key],altKey:!1,ctrlKey:!1,metaKey:!1,shiftKey:!1,isComposing:!1,location:0,repeat:!1}))}getDescription(){return`Press ${this.key} key in ${this.getElementName()}`}getJSON(){return{...super.getJSON(),type:"PressKey",key:this.key}}}class ze extends d{constructor(n,s){super(n);i(this,"file");this.file=s}executeActionOnElement(){const n=this.element,s=new DataTransfer;s.items.add(this.file);const o=s.files;n.files=o,n.dispatchEvent(new Event("change"));function a(c){var y;return c!=null&&c.parentElement?((y=c.parentElement)==null?void 0:y.tagName.toLowerCase())==="form"?c.parentElement:a(c.parentElement):null}const r=a(n);r&&r.dispatchEvent(new Event("change"))}getDescription(){return`Upload file in ${this.getElementName()}`}getJSON(){return{...super.getJSON(),type:"UploadFile"}}}class Ge extends d{constructor(n,s){super(n);i(this,"memorySlotName");this.memorySlotName=s}executeActionOnElement(){var s,o,a,r;let n=this.element;if(((s=this.element)==null?void 0:s.tagName)!=="INPUT"&&((o=this.element)==null?void 0:o.tagName)!=="SELECT"&&((a=this.element)==null?void 0:a.tagName)!=="TEXTAREA"&&(n=(r=this.element)==null?void 0:r.querySelectorAll("input")[0],!n))throw new Error("Input element not found. Not able to save value from element "+this.getElementName());h.dispatch(k.SAVE_VALUE,{memorySlotName:this.memorySlotName,value:n.value})}getDescription(){return`Save value of ${this.getElementName()} in ${this.memorySlotName}`}getJSON(){return{...super.getJSON(),type:"SaveValue",memorySlotName:this.memorySlotName}}}class Qe extends g{constructor(n){super();i(this,"miliseconds");this.miliseconds=n}getDescription(){return"Wait "+this.miliseconds+" miliseconds"}getJSON(){return{...super.getJSON(),type:"Wait"}}async executeAction(){await E(this.miliseconds)}resetAction(){}}class Ze extends g{constructor(n){super();i(this,"uiElement");i(this,"tries");this.uiElement=n,this.tries=0}updateTries(n){this.tries=n}resetAction(){this.tries=0}getElementName(){var n;return(n=this.uiElement)==null?void 0:n.getElementName()}async executeAction(){await J(this,this.uiElement,1e3,10,!0)}getDescription(){return"Wait until "+this.getElementName()+" is removed"}getJSON(){return{...super.getJSON(),type:"WaitUntilElementRemoved"}}}class Ye extends g{constructor(){super()}getDescription(){return"Paused"}getJSON(){return{...super.getJSON(),type:"Pause"}}async executeAction(){await exports.AutomationInstance.pause()}resetAction(){}}class _e extends g{constructor(n){super();i(this,"description");this.description=n}getDescription(){return"Manual Step: "+this.description}getJSON(){return{...super.getJSON(),type:"ManualStep"}}async executeAction(){return await exports.AutomationInstance.uiUtils.showAlert("Waiting manual step..."),new Promise((n,s)=>{h.on(k.USER_ACCEPT,async()=>(await exports.AutomationInstance.uiUtils.hideAlert(),n(!0))),h.on(k.USER_REJECT,async()=>(await exports.AutomationInstance.uiUtils.hideAlert(),s()))})}resetAction(){}}class et extends g{constructor(){super()}getDescription(){return"Reload page"}getJSON(){return{...super.getJSON(),type:"ReloadPage"}}async executeAction(){await location.reload()}resetAction(){}}const R=t=>t.toLocaleDateString("en-US",{year:"numeric",month:"2-digit",day:"2-digit"}),K=t=>{const e=new Date;return R(new Date(e.setDate(e.getDate()+t)))},se=t=>{const e=new Date;return R(new Date(e.setMonth(e.getMonth()+t)))},tt=K(1),nt=K(-1),st=K(7),ot=K(-7),it=se(1),rt=se(-1),at={formatDate:R,today:R(new Date),tomorrow:tt,nextWeek:st,nextMonth:it,yesterday:nt,lastWeek:ot,lastMonth:rt};class ct{constructor(){i(this,"enabled",!1)}setEnabled(e){this.enabled=e}log(...e){this.enabled&&console.log("[tomation]",...e)}groupCollapsed(...e){this.enabled&&console.groupCollapsed("[tomation]",...e)}groupEnd(){this.enabled&&console.groupEnd()}error(...e){this.enabled&&console.error("[tomation]",...e)}}const l=new ct,oe=t=>{l.setEnabled(t)},w=class w{static compileAction(e){const n=w.currentAction;w.currentAction=e,e.compileSteps(),w.currentAction=n}static addAction(e){l.log("Add action: ",e.getDescription()),w.currentAction.addStep(e)}static init(e){w.currentAction=e,w.isCompiling=!0,l.groupCollapsed("Compile: "+e.getDescription()),e.compileSteps(),w.isCompiling=!1,l.log("Compilation finished"),l.groupEnd()}};i(w,"currentAction"),i(w,"isCompiling");let u=w;var k=(t=>(t.ACTION_UPDATE="tomation-action-update",t.SAVE_VALUE="tomation-save-value",t.REGISTER_TEST="tomation-register-test",t.TEST_STARTED="tomation-test-started",t.TEST_PASSED="tomation-test-passed",t.TEST_FAILED="tomation-test-failed",t.TEST_END="tomation-test-end",t.TEST_STOP="tomation-test-stop",t.TEST_PAUSE="tomation-test-pause",t.TEST_PLAY="tomation-test-play",t.USER_ACCEPT="tomation-user-accept",t.USER_REJECT="tomation-user-reject",t.SESSION_INIT="tomation-session-init",t))(k||{});class lt{constructor(){i(this,"events");this.events=new Map}on(e,n){var s;this.events.has(e)||this.events.set(e,[]),(s=this.events.get(e))==null||s.push(n)}off(e,n){var s;this.events.has(e)&&this.events.set(e,((s=this.events.get(e))==null?void 0:s.filter(o=>o!==n))||[])}dispatch(e,n){var s;this.events.has(e)&&((s=this.events.get(e))==null||s.forEach(o=>{console.log(`Dispatch Event ${e}:`,n),o(n)}))}}const h=new lt;var j=(t=>(t[t.SLOW=2e3]="SLOW",t[t.NORMAL=1e3]="NORMAL",t[t.FAST=200]="FAST",t))(j||{});const S=class S{static async start(e){if(S.running)throw l.error("Not able to run test while other test is running."),new Error("Not able to run test while other test is running.");S.running=!0,exports.AutomationInstance.status="Playing",exports.AutomationInstance.runMode="Normal",l.groupCollapsed("Start Action: ",e.getDescription()),h.dispatch("tomation-test-started",{action:e==null?void 0:e.getJSON()});try{await(e==null?void 0:e.execute()),h.dispatch("tomation-test-passed",{id:e.name})}catch(n){throw h.dispatch("tomation-test-failed",{id:e.name}),exports.AutomationInstance.uiUtils.hideCheckElementContainer(),l.error(`🤖 Error running task ${e.getDescription()}. Reason: ${n.message}`),n}finally{l.groupEnd(),S.running=!1,h.dispatch("tomation-test-end",{action:e==null?void 0:e.getJSON()})}}};i(S,"running",!1);let b=S;const U={},ut=(t,e)=>{console.log(`Registering Test: ${t}...`);const n=new ee(t,e);u.init(n),console.log(`Compiled Test: ${t}`),h.dispatch("tomation-register-test",{id:t,action:n.getJSON()}),console.log(`Registered Test: ${t} in TestsMap`),U[t]=()=>{b.start(n)}},ie=t=>{if(U[t])U[t]();else throw console.log("Available Tests:",Object.keys(U)),new Error(`Test with id ${t} not found.`)},ht=(t,e)=>async n=>{const s=new ee(t,e);if(s.setParams(n),!b.running&&!u.isCompiling)try{l.log(`Compilation of Task ${t} starts...`),u.init(s),l.log(`Compilation of Task ${t} Finished.`),l.log(`Start running Task ${t}...`),await b.start(s),l.log(`End of Task ${t}: SUCCESS`)}catch(o){l.error("Error running task "+t+". "+o.message)}else l.log(`Adding action ${t} to compilation stack`),u.addAction(s),u.compileAction(s)},dt=t=>{const e=new $e(t);u.addAction(e)},pt=t=>({textIs:e=>{u.addAction(new Re(t,e))},containsText:e=>{u.addAction(new Je(t,e))},valueIs:e=>{u.addAction(new Ke(t,e))},exists:()=>{u.addAction(new Ve(t))},notExists:()=>{u.addAction(new Fe(t))}}),mt=t=>({in:e=>{const n=new Me(e,t);u.addAction(n)}}),gt=t=>({in:e=>{const n=new te(e,t);u.addAction(n)}}),yt=()=>({in:t=>{const e=new te(t,"");u.addAction(e)}}),Et=()=>({in:t=>{u.addAction(new Be(t))}}),wt=()=>({in:t=>{u.addAction(new qe(t))}}),ft=()=>({in:t=>{u.addAction(new He(t))}}),At=()=>({in:t=>{u.addAction(new je(t))}}),xt=t=>({in:e=>{u.addAction(new Xe(e,t))}}),Ct=t=>({in:e=>{const n=new We(e,t);u.addAction(n)}}),Tt=t=>({in:e=>{const n=new ze(e,t);u.addAction(n)}}),kt=t=>({in:e=>{const n=new Ge(t,e);u.addAction(n)}}),re=t=>{u.addAction(new Qe(t))};re.untilElement=t=>({isRemoved:()=>{u.addAction(new Ze(t))}});const St=()=>{u.addAction(new Ye)},It=t=>{u.addAction(new _e(t))},vt=()=>{u.addAction(new et)};class Nt{constructor(e){i(this,"_document");i(this,"debug");i(this,"_uiUtils");i(this,"speed");i(this,"status");i(this,"runMode");i(this,"currentActionCallback");i(this,"currentAction");this._document=e.document,this.debug=!0,this._uiUtils=new Ue(e),this.speed=1e3,this.status="Stopped",this.runMode="Normal"}get document(){return this._document}get uiUtils(){return this._uiUtils}get isStepByStepMode(){return this.runMode=="Step By Step"}get isStopped(){return this.status=="Stopped"}get isPlaying(){return this.status=="Playing"}get isPaused(){return this.status=="Paused"}pause(){l.log("Pause Test"),this.status="Paused",h.dispatch("tomation-test-pause")}continue(){l.log("Continue Test"),this.status="Playing",this.runMode="Normal",h.dispatch("tomation-test-play"),this.currentActionCallback&&this.currentAction&&(l.log("Continue: Executing current action callback"),this.currentActionCallback(this.currentAction),this.currentActionCallback=void 0)}next(){l.log("Continue Test to Next Step..."),this.status="Playing",this.runMode="Step By Step",h.dispatch("tomation-test-play"),this.currentActionCallback&&this.currentAction&&(l.log("Next: Executing current action callback"),this.currentActionCallback(this.currentAction),this.currentActionCallback=void 0)}stop(){l.log("Stop Test"),this.status="Stopped",this.currentActionCallback&&this.currentAction&&(l.log("Stop: Executing current action callback"),this.currentActionCallback(this.currentAction),this.currentActionCallback=void 0),h.dispatch("tomation-test-stop")}retryAction(){l.log("Retry current step"),this.status="Playing",h.dispatch("tomation-test-play"),this.currentActionCallback&&this.currentAction&&(this.currentAction.resetTries&&(l.log("Retry: Resetting tries for current action"),this.currentAction.resetTries()),l.log("Retry: Executing current action callback"),this.currentActionCallback(this.currentAction),this.currentActionCallback=void 0)}skipAction(){l.log("Skip current step"),this.status="Playing",this.currentActionCallback&&this.currentAction&&(this.currentAction.status=H.SKIPPED,l.log("Skip: Marked current action as SKIPPED"),g.notifyActionUpdated(this.currentAction),l.log("Skip: Executing current action callback"),this.currentActionCallback(this.currentAction),this.currentActionCallback=void 0)}saveCurrentAction(e,n){l.log("Save current action"),this.currentActionCallback=e,this.currentAction=n}setDebug(e){oe(e)}}exports.AutomationInstance=void 0;const B=(t,e)=>(exports.AutomationInstance=new Nt(t),ue(exports.AutomationInstance.document),e==null||e.forEach(n=>n()),exports.AutomationInstance);function ae(t){const{matches:e,tests:n=[],speed:s="NORMAL",debug:o=!1}=t;if(!(typeof e=="string"?document.location.href.includes(e):!!document.location.href.match(e))){console.log(`[tomation] URL "${document.location.href}" does not match "${e}"`);return}try{console.log("[tomation] Setting up messaging bridge with extension..."),Object.values(k).forEach(r=>{console.log(`[tomation] Setting up listener for event "${r}"`),h.on(r,c=>{console.log(`[tomation] Dispatching event "${r}" to extension`,c),window.postMessage({message:"injectedScript-to-contentScript",sender:"tomation",payload:{cmd:r,params:c}})})}),window.addEventListener("message",r=>{try{console.log("[tomation] Received message from extension:",r.data);const{message:c,sender:y,payload:x}=r.data||{},{cmd:m,params:T}=x||{};if(y!=="web-extension")return;if(c==="contentScript-to-injectedScript"){const I={"run-test-request":()=>ie(T==null?void 0:T.testId),"reload-tests-request":()=>B(window,n||[]),"pause-test-request":()=>exports.AutomationInstance.pause(),"stop-test-request":()=>exports.AutomationInstance.stop(),"continue-test-request":()=>exports.AutomationInstance.continue(),"next-step-request":()=>exports.AutomationInstance.next(),"retry-action-request":()=>exports.AutomationInstance.retryAction(),"skip-action-request":()=>exports.AutomationInstance.skipAction(),"user-accept-request":()=>h.dispatch("tomation-user-accept"),"user-reject-request":()=>h.dispatch("tomation-user-reject")}[m];I?(console.log(`[tomation] Executing command "${m}" from extension`),I()):console.warn(`[tomation] Unknown command "${m}" from extension`);return}}catch(c){console.error("[tomation] Error handling message from extension:",c)}}),B(window,n),exports.AutomationInstance.setDebug(o),exports.AutomationInstance.speed=j[s],window.postMessage({message:"injectedScript-to-contentScript",sender:"tomation",payload:{cmd:"tomation-session-init",params:{speed:exports.AutomationInstance.speed,sessionId:_()}}}),console.log("[tomation] Ready ✓")}catch(r){console.error("[tomation] Initialization failed:",r)}}exports.ACTION_STATUS=H;exports.Assert=pt;exports.AutomationEvents=h;exports.ClearValue=yt;exports.Click=dt;exports.DateUtils=at;exports.EVENT_NAMES=k;exports.KEY_MAP=ne;exports.ManualTask=It;exports.Pause=St;exports.PressDownKey=wt;exports.PressEnterKey=At;exports.PressEscKey=Et;exports.PressKey=xt;exports.PressTabKey=ft;exports.ReloadPage=vt;exports.RunTest=ie;exports.SaveValue=kt;exports.Select=mt;exports.SelectorBuilder=q;exports.Setup=B;exports.Task=ht;exports.Test=ut;exports.TestSpeed=j;exports.Type=gt;exports.TypePassword=Ct;exports.UIElement=Q;exports.UploadFile=Tt;exports.Wait=re;exports.and=Ne;exports.classIncludes=Ae;exports.classIs=fe;exports.default=ae;exports.elementIndexIs=Ie;exports.firstChildTextIs=ve;exports.innerTextContains=Ce;exports.innerTextIs=xe;exports.is=be;exports.isFirstElement=Se;exports.placeholderIs=ke;exports.setAutomationLogs=oe;exports.setFilterLogs=we;exports.titleIs=Te;exports.tomation=ae;exports.wait=E;