intellitester 0.2.19 → 0.2.21
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/{chunk-LKSREGQS.js → chunk-CKUSY4ZM.js} +407 -65
- package/dist/chunk-CKUSY4ZM.js.map +1 -0
- package/dist/{chunk-LFCMPHWU.cjs → chunk-PP666GZQ.cjs} +412 -65
- package/dist/chunk-PP666GZQ.cjs.map +1 -0
- package/dist/cli/index.cjs +35 -43
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +2 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +52 -28
- package/dist/index.d.cts +987 -8
- package/dist/index.d.ts +987 -8
- package/dist/index.js +1 -1
- package/package.json +2 -1
- package/dist/chunk-LFCMPHWU.cjs.map +0 -1
- package/dist/chunk-LKSREGQS.js.map +0 -1
|
@@ -2,12 +2,13 @@ import { loadCleanupHandlers, executeCleanup, saveFailedCleanup } from './chunk-
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import fs2 from 'fs/promises';
|
|
4
4
|
import { parse } from 'yaml';
|
|
5
|
-
import
|
|
5
|
+
import { NumberDictionary, uniqueNamesGenerator, adjectives, animals } from 'unique-names-generator';
|
|
6
|
+
import crypto4 from 'crypto';
|
|
7
|
+
import { parsePhoneNumber, isValidPhoneNumber } from 'libphonenumber-js';
|
|
6
8
|
import path from 'path';
|
|
7
9
|
import { spawn } from 'child_process';
|
|
8
10
|
import { chromium, webkit, firefox } from 'playwright';
|
|
9
11
|
import prompts from 'prompts';
|
|
10
|
-
import { NumberDictionary, uniqueNamesGenerator, adjectives, animals } from 'unique-names-generator';
|
|
11
12
|
import { Client, Users, TablesDB, Storage, Teams } from 'node-appwrite';
|
|
12
13
|
import { Anthropic } from '@llamaindex/anthropic';
|
|
13
14
|
import { OpenAI } from '@llamaindex/openai';
|
|
@@ -128,7 +129,17 @@ var appwriteVerifyEmailActionSchema = z.object({
|
|
|
128
129
|
var debugActionSchema = z.object({
|
|
129
130
|
type: z.literal("debug")
|
|
130
131
|
}).describe("Pause execution and open Playwright Inspector for debugging");
|
|
131
|
-
var
|
|
132
|
+
var waitForSelectorActionSchema = z.object({
|
|
133
|
+
type: z.literal("waitForSelector"),
|
|
134
|
+
target: LocatorSchema,
|
|
135
|
+
state: z.enum(["enabled", "disabled", "visible", "hidden", "attached", "detached"]).describe("Element state to wait for"),
|
|
136
|
+
timeout: z.number().int().positive().optional().describe("Time to wait in milliseconds")
|
|
137
|
+
}).describe("Wait for an element to reach a specific state");
|
|
138
|
+
var failActionSchema = z.object({
|
|
139
|
+
type: z.literal("fail"),
|
|
140
|
+
message: nonEmptyString.describe("Error message to display when test fails")
|
|
141
|
+
}).describe("Explicitly fail the test with a custom message");
|
|
142
|
+
var BaseActionSchema = z.discriminatedUnion("type", [
|
|
132
143
|
navigateActionSchema,
|
|
133
144
|
tapActionSchema,
|
|
134
145
|
inputActionSchema,
|
|
@@ -149,8 +160,20 @@ var ActionSchema = z.discriminatedUnion("type", [
|
|
|
149
160
|
emailExtractLinkActionSchema,
|
|
150
161
|
emailClearActionSchema,
|
|
151
162
|
appwriteVerifyEmailActionSchema,
|
|
152
|
-
debugActionSchema
|
|
163
|
+
debugActionSchema,
|
|
164
|
+
waitForSelectorActionSchema,
|
|
165
|
+
failActionSchema
|
|
153
166
|
]);
|
|
167
|
+
var conditionalActionSchema = z.object({
|
|
168
|
+
type: z.literal("conditional"),
|
|
169
|
+
condition: z.object({
|
|
170
|
+
type: z.enum(["exists", "notExists", "visible", "hidden"]),
|
|
171
|
+
target: LocatorSchema
|
|
172
|
+
}).describe("Condition to check"),
|
|
173
|
+
then: z.array(BaseActionSchema).describe("Steps to execute if condition is true"),
|
|
174
|
+
else: z.array(BaseActionSchema).optional().describe("Steps to execute if condition is false")
|
|
175
|
+
}).describe("Execute steps conditionally based on element state");
|
|
176
|
+
var ActionSchema = z.union([BaseActionSchema, conditionalActionSchema]);
|
|
154
177
|
var defaultsSchema = z.object({
|
|
155
178
|
timeout: z.number().int().positive().optional().describe("Default timeout in milliseconds for all actions"),
|
|
156
179
|
screenshots: z.enum(["on-failure", "always", "never"]).optional().describe("When to capture screenshots during test execution")
|
|
@@ -491,6 +514,272 @@ function generateRandomUsername() {
|
|
|
491
514
|
return username;
|
|
492
515
|
}
|
|
493
516
|
|
|
517
|
+
// src/core/randomPhoto.ts
|
|
518
|
+
function generateRandomPhoto(dimensions) {
|
|
519
|
+
let width = 500;
|
|
520
|
+
let height = 500;
|
|
521
|
+
if (dimensions) {
|
|
522
|
+
if (dimensions.includes("x")) {
|
|
523
|
+
const [w, h] = dimensions.split("x").map((d) => parseInt(d.trim(), 10));
|
|
524
|
+
if (!isNaN(w) && w > 0) width = w;
|
|
525
|
+
if (!isNaN(h) && h > 0) height = h;
|
|
526
|
+
} else {
|
|
527
|
+
const size = parseInt(dimensions.trim(), 10);
|
|
528
|
+
if (!isNaN(size) && size > 0) {
|
|
529
|
+
width = size;
|
|
530
|
+
height = size;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
return `https://picsum.photos/${width}/${height}`;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// src/core/fillerText.ts
|
|
538
|
+
var LOREM_WORDS = [
|
|
539
|
+
"lorem",
|
|
540
|
+
"ipsum",
|
|
541
|
+
"dolor",
|
|
542
|
+
"sit",
|
|
543
|
+
"amet",
|
|
544
|
+
"consectetur",
|
|
545
|
+
"adipiscing",
|
|
546
|
+
"elit",
|
|
547
|
+
"sed",
|
|
548
|
+
"do",
|
|
549
|
+
"eiusmod",
|
|
550
|
+
"tempor",
|
|
551
|
+
"incididunt",
|
|
552
|
+
"ut",
|
|
553
|
+
"labore",
|
|
554
|
+
"et",
|
|
555
|
+
"dolore",
|
|
556
|
+
"magna",
|
|
557
|
+
"aliqua",
|
|
558
|
+
"enim",
|
|
559
|
+
"ad",
|
|
560
|
+
"minim",
|
|
561
|
+
"veniam",
|
|
562
|
+
"quis",
|
|
563
|
+
"nostrud",
|
|
564
|
+
"exercitation",
|
|
565
|
+
"ullamco",
|
|
566
|
+
"laboris",
|
|
567
|
+
"nisi",
|
|
568
|
+
"aliquip",
|
|
569
|
+
"ex",
|
|
570
|
+
"ea",
|
|
571
|
+
"commodo",
|
|
572
|
+
"consequat",
|
|
573
|
+
"duis",
|
|
574
|
+
"aute",
|
|
575
|
+
"irure",
|
|
576
|
+
"in",
|
|
577
|
+
"reprehenderit",
|
|
578
|
+
"voluptate",
|
|
579
|
+
"velit",
|
|
580
|
+
"esse",
|
|
581
|
+
"cillum",
|
|
582
|
+
"fugiat",
|
|
583
|
+
"nulla",
|
|
584
|
+
"pariatur",
|
|
585
|
+
"excepteur",
|
|
586
|
+
"sint",
|
|
587
|
+
"occaecat",
|
|
588
|
+
"cupidatat",
|
|
589
|
+
"non",
|
|
590
|
+
"proident",
|
|
591
|
+
"sunt",
|
|
592
|
+
"culpa",
|
|
593
|
+
"qui",
|
|
594
|
+
"officia",
|
|
595
|
+
"deserunt",
|
|
596
|
+
"mollit",
|
|
597
|
+
"anim",
|
|
598
|
+
"id",
|
|
599
|
+
"est",
|
|
600
|
+
"laborum",
|
|
601
|
+
"perspiciatis",
|
|
602
|
+
"unde",
|
|
603
|
+
"omnis",
|
|
604
|
+
"iste",
|
|
605
|
+
"natus",
|
|
606
|
+
"error",
|
|
607
|
+
"voluptatem",
|
|
608
|
+
"accusantium",
|
|
609
|
+
"doloremque",
|
|
610
|
+
"laudantium",
|
|
611
|
+
"totam",
|
|
612
|
+
"rem",
|
|
613
|
+
"aperiam",
|
|
614
|
+
"eaque",
|
|
615
|
+
"ipsa",
|
|
616
|
+
"quae",
|
|
617
|
+
"ab",
|
|
618
|
+
"illo",
|
|
619
|
+
"inventore",
|
|
620
|
+
"veritatis",
|
|
621
|
+
"quasi",
|
|
622
|
+
"architecto",
|
|
623
|
+
"beatae",
|
|
624
|
+
"vitae",
|
|
625
|
+
"dicta",
|
|
626
|
+
"explicabo",
|
|
627
|
+
"nemo",
|
|
628
|
+
"ipsam",
|
|
629
|
+
"quia",
|
|
630
|
+
"voluptas",
|
|
631
|
+
"aspernatur",
|
|
632
|
+
"aut",
|
|
633
|
+
"odit",
|
|
634
|
+
"fugit",
|
|
635
|
+
"consequuntur",
|
|
636
|
+
"magni",
|
|
637
|
+
"dolores",
|
|
638
|
+
"eos",
|
|
639
|
+
"ratione",
|
|
640
|
+
"sequi",
|
|
641
|
+
"nesciunt",
|
|
642
|
+
"neque",
|
|
643
|
+
"porro",
|
|
644
|
+
"quisquam",
|
|
645
|
+
"nihil",
|
|
646
|
+
"impedit",
|
|
647
|
+
"quo",
|
|
648
|
+
"minus"
|
|
649
|
+
];
|
|
650
|
+
function generateFillerText(wordCount) {
|
|
651
|
+
let count = 50;
|
|
652
|
+
if (wordCount !== void 0) {
|
|
653
|
+
const parsed = typeof wordCount === "string" ? parseInt(wordCount.trim(), 10) : wordCount;
|
|
654
|
+
if (!isNaN(parsed) && parsed > 0) {
|
|
655
|
+
count = parsed;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
const words = [];
|
|
659
|
+
if (count >= 2) {
|
|
660
|
+
words.push("Lorem", "ipsum");
|
|
661
|
+
count -= 2;
|
|
662
|
+
}
|
|
663
|
+
for (let i = 0; i < count; i++) {
|
|
664
|
+
const randomIndex = Math.floor(Math.random() * LOREM_WORDS.length);
|
|
665
|
+
words.push(LOREM_WORDS[randomIndex]);
|
|
666
|
+
}
|
|
667
|
+
let result = words.join(" ");
|
|
668
|
+
const resultWords = result.split(" ");
|
|
669
|
+
const sentenceWords = [];
|
|
670
|
+
let sentenceLength = 0;
|
|
671
|
+
const nextSentenceLength = () => 8 + Math.floor(Math.random() * 5);
|
|
672
|
+
let targetLength = nextSentenceLength();
|
|
673
|
+
for (let i = 0; i < resultWords.length; i++) {
|
|
674
|
+
let word = resultWords[i];
|
|
675
|
+
if (sentenceLength === 0) {
|
|
676
|
+
word = word.charAt(0).toUpperCase() + word.slice(1);
|
|
677
|
+
}
|
|
678
|
+
sentenceWords.push(word);
|
|
679
|
+
sentenceLength++;
|
|
680
|
+
if (sentenceLength >= targetLength && i < resultWords.length - 1) {
|
|
681
|
+
sentenceWords[sentenceWords.length - 1] += ".";
|
|
682
|
+
sentenceLength = 0;
|
|
683
|
+
targetLength = nextSentenceLength();
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
result = sentenceWords.join(" ");
|
|
687
|
+
if (!result.endsWith(".")) {
|
|
688
|
+
result += ".";
|
|
689
|
+
}
|
|
690
|
+
return result;
|
|
691
|
+
}
|
|
692
|
+
function generateRandomEmail(domain) {
|
|
693
|
+
const randomPart = crypto4.randomBytes(3).toString("hex");
|
|
694
|
+
const emailDomain = domain?.trim() || "test.local";
|
|
695
|
+
return `test-${randomPart}@${emailDomain}`;
|
|
696
|
+
}
|
|
697
|
+
var COUNTRY_FORMATS = {
|
|
698
|
+
US: {
|
|
699
|
+
areaCode: () => {
|
|
700
|
+
const areaCodes = ["201", "212", "213", "310", "312", "404", "415", "512", "617", "702", "713", "718", "805", "818", "917"];
|
|
701
|
+
return areaCodes[Math.floor(Math.random() * areaCodes.length)];
|
|
702
|
+
},
|
|
703
|
+
subscriber: () => String(Math.floor(Math.random() * 9e6) + 1e6).slice(0, 7)
|
|
704
|
+
},
|
|
705
|
+
GB: {
|
|
706
|
+
areaCode: () => {
|
|
707
|
+
const areaCodes = ["20", "121", "131", "141", "151", "161", "171", "181"];
|
|
708
|
+
return areaCodes[Math.floor(Math.random() * areaCodes.length)];
|
|
709
|
+
},
|
|
710
|
+
subscriber: () => String(Math.floor(Math.random() * 9e7) + 1e7).slice(0, 8)
|
|
711
|
+
},
|
|
712
|
+
DE: {
|
|
713
|
+
areaCode: () => {
|
|
714
|
+
const areaCodes = ["30", "40", "69", "89", "211", "221", "341", "351"];
|
|
715
|
+
return areaCodes[Math.floor(Math.random() * areaCodes.length)];
|
|
716
|
+
},
|
|
717
|
+
subscriber: () => String(Math.floor(Math.random() * 9e6) + 1e6).slice(0, 7)
|
|
718
|
+
},
|
|
719
|
+
FR: {
|
|
720
|
+
areaCode: () => {
|
|
721
|
+
const areaCodes = ["1", "2", "3", "4", "5"];
|
|
722
|
+
return areaCodes[Math.floor(Math.random() * areaCodes.length)];
|
|
723
|
+
},
|
|
724
|
+
subscriber: () => String(Math.floor(Math.random() * 9e7) + 1e7).slice(0, 8)
|
|
725
|
+
},
|
|
726
|
+
AU: {
|
|
727
|
+
areaCode: () => {
|
|
728
|
+
const areaCodes = ["2", "3", "7", "8"];
|
|
729
|
+
return areaCodes[Math.floor(Math.random() * areaCodes.length)];
|
|
730
|
+
},
|
|
731
|
+
subscriber: () => String(Math.floor(Math.random() * 9e7) + 1e7).slice(0, 8)
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
function generateRandomPhone(country = "US") {
|
|
735
|
+
const countryCode = country.toUpperCase();
|
|
736
|
+
const format = COUNTRY_FORMATS[countryCode] || COUNTRY_FORMATS["US"];
|
|
737
|
+
for (let i = 0; i < 10; i++) {
|
|
738
|
+
const areaCode2 = format.areaCode();
|
|
739
|
+
const subscriber2 = format.subscriber();
|
|
740
|
+
const nationalNumber = areaCode2 + subscriber2;
|
|
741
|
+
try {
|
|
742
|
+
const phoneNumber = parsePhoneNumber(nationalNumber, countryCode);
|
|
743
|
+
if (phoneNumber && isValidPhoneNumber(phoneNumber.number)) {
|
|
744
|
+
return phoneNumber.format("E.164");
|
|
745
|
+
}
|
|
746
|
+
} catch {
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
const fallbackFormat = COUNTRY_FORMATS[countryCode] || COUNTRY_FORMATS["US"];
|
|
750
|
+
const areaCode = fallbackFormat.areaCode();
|
|
751
|
+
const subscriber = fallbackFormat.subscriber();
|
|
752
|
+
const callingCodes = {
|
|
753
|
+
US: "1",
|
|
754
|
+
GB: "44",
|
|
755
|
+
DE: "49",
|
|
756
|
+
FR: "33",
|
|
757
|
+
AU: "61"
|
|
758
|
+
};
|
|
759
|
+
const callingCode = callingCodes[countryCode] || "1";
|
|
760
|
+
return `+${callingCode}${areaCode}${subscriber}`;
|
|
761
|
+
}
|
|
762
|
+
function interpolateVariables(value, variables) {
|
|
763
|
+
return value.replace(/\{\{(\w+)(?::([^}]+))?\}\}/g, (match, name, param) => {
|
|
764
|
+
switch (name) {
|
|
765
|
+
case "uuid":
|
|
766
|
+
return crypto4.randomUUID().split("-")[0];
|
|
767
|
+
case "randomUsername":
|
|
768
|
+
return generateRandomUsername();
|
|
769
|
+
case "randomPhoto":
|
|
770
|
+
return generateRandomPhoto(param);
|
|
771
|
+
case "fillerText":
|
|
772
|
+
return generateFillerText(param);
|
|
773
|
+
case "randomEmail":
|
|
774
|
+
return generateRandomEmail(param);
|
|
775
|
+
case "randomPhone":
|
|
776
|
+
return generateRandomPhone(param);
|
|
777
|
+
default:
|
|
778
|
+
return variables.get(name) ?? match;
|
|
779
|
+
}
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
|
|
494
783
|
// src/integrations/email/inbucketClient.ts
|
|
495
784
|
var InbucketClient = class {
|
|
496
785
|
constructor(config) {
|
|
@@ -1025,17 +1314,6 @@ async function startTrackingServer(options) {
|
|
|
1025
1314
|
|
|
1026
1315
|
// src/executors/web/playwrightExecutor.ts
|
|
1027
1316
|
var defaultScreenshotDir = path.join(process.cwd(), "artifacts", "screenshots");
|
|
1028
|
-
function interpolateVariables(value, variables) {
|
|
1029
|
-
return value.replace(/\{\{(\w+)\}\}/g, (match, varName) => {
|
|
1030
|
-
if (varName === "uuid") {
|
|
1031
|
-
return crypto2.randomUUID().split("-")[0];
|
|
1032
|
-
}
|
|
1033
|
-
if (varName === "randomUsername") {
|
|
1034
|
-
return generateRandomUsername();
|
|
1035
|
-
}
|
|
1036
|
-
return variables.get(varName) ?? match;
|
|
1037
|
-
});
|
|
1038
|
-
}
|
|
1039
1317
|
var resolveUrl = (value, baseUrl) => {
|
|
1040
1318
|
if (!baseUrl) return value;
|
|
1041
1319
|
try {
|
|
@@ -1096,6 +1374,14 @@ var runWait = async (page, action) => {
|
|
|
1096
1374
|
}
|
|
1097
1375
|
await page.waitForTimeout(action.timeout ?? 1e3);
|
|
1098
1376
|
};
|
|
1377
|
+
var waitForCondition = async (checkFn, timeout, errorMessage) => {
|
|
1378
|
+
const start = Date.now();
|
|
1379
|
+
while (Date.now() - start < timeout) {
|
|
1380
|
+
if (await checkFn()) return;
|
|
1381
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
1382
|
+
}
|
|
1383
|
+
throw new Error(errorMessage);
|
|
1384
|
+
};
|
|
1099
1385
|
var runScroll = async (page, action) => {
|
|
1100
1386
|
if (action.target) {
|
|
1101
1387
|
const handle = resolveLocator(page, action.target);
|
|
@@ -1531,6 +1817,91 @@ async function executeActionWithRetry(page, action, index, options) {
|
|
|
1531
1817
|
await page.pause();
|
|
1532
1818
|
break;
|
|
1533
1819
|
}
|
|
1820
|
+
case "waitForSelector": {
|
|
1821
|
+
const wsAction = action;
|
|
1822
|
+
const handle = resolveLocator(page, wsAction.target);
|
|
1823
|
+
const timeout = wsAction.timeout ?? 3e4;
|
|
1824
|
+
if (debugMode) {
|
|
1825
|
+
console.log(`[DEBUG] Waiting for element to be ${wsAction.state}:`, wsAction.target);
|
|
1826
|
+
}
|
|
1827
|
+
switch (wsAction.state) {
|
|
1828
|
+
case "visible":
|
|
1829
|
+
case "hidden":
|
|
1830
|
+
case "attached":
|
|
1831
|
+
case "detached":
|
|
1832
|
+
await handle.waitFor({ state: wsAction.state, timeout });
|
|
1833
|
+
break;
|
|
1834
|
+
case "enabled":
|
|
1835
|
+
await waitForCondition(
|
|
1836
|
+
() => handle.isEnabled(),
|
|
1837
|
+
timeout,
|
|
1838
|
+
`Element did not become enabled within ${timeout}ms`
|
|
1839
|
+
);
|
|
1840
|
+
break;
|
|
1841
|
+
case "disabled":
|
|
1842
|
+
await waitForCondition(
|
|
1843
|
+
() => handle.isDisabled(),
|
|
1844
|
+
timeout,
|
|
1845
|
+
`Element did not become disabled within ${timeout}ms`
|
|
1846
|
+
);
|
|
1847
|
+
break;
|
|
1848
|
+
}
|
|
1849
|
+
break;
|
|
1850
|
+
}
|
|
1851
|
+
case "conditional": {
|
|
1852
|
+
const condAction = action;
|
|
1853
|
+
const handle = resolveLocator(page, condAction.condition.target);
|
|
1854
|
+
let conditionMet = false;
|
|
1855
|
+
if (debugMode) {
|
|
1856
|
+
console.log(`[DEBUG] Checking condition ${condAction.condition.type}:`, condAction.condition.target);
|
|
1857
|
+
}
|
|
1858
|
+
try {
|
|
1859
|
+
switch (condAction.condition.type) {
|
|
1860
|
+
case "exists":
|
|
1861
|
+
await handle.waitFor({ state: "attached", timeout: 500 });
|
|
1862
|
+
conditionMet = true;
|
|
1863
|
+
break;
|
|
1864
|
+
case "notExists":
|
|
1865
|
+
try {
|
|
1866
|
+
await handle.waitFor({ state: "detached", timeout: 500 });
|
|
1867
|
+
conditionMet = true;
|
|
1868
|
+
} catch {
|
|
1869
|
+
conditionMet = false;
|
|
1870
|
+
}
|
|
1871
|
+
break;
|
|
1872
|
+
case "visible":
|
|
1873
|
+
conditionMet = await handle.isVisible();
|
|
1874
|
+
break;
|
|
1875
|
+
case "hidden":
|
|
1876
|
+
conditionMet = !await handle.isVisible();
|
|
1877
|
+
break;
|
|
1878
|
+
}
|
|
1879
|
+
} catch {
|
|
1880
|
+
conditionMet = condAction.condition.type === "notExists";
|
|
1881
|
+
}
|
|
1882
|
+
if (debugMode) {
|
|
1883
|
+
console.log(`[DEBUG] Condition result: ${conditionMet}`);
|
|
1884
|
+
}
|
|
1885
|
+
const stepsToRun = conditionMet ? condAction.then : condAction.else ?? [];
|
|
1886
|
+
for (const [nestedIdx, nestedAction] of stepsToRun.entries()) {
|
|
1887
|
+
if (debugMode) {
|
|
1888
|
+
console.log(`[DEBUG] Executing nested step ${nestedIdx + 1}: ${nestedAction.type}`);
|
|
1889
|
+
}
|
|
1890
|
+
await executeActionWithRetry(page, nestedAction, index, {
|
|
1891
|
+
baseUrl,
|
|
1892
|
+
context,
|
|
1893
|
+
screenshotDir,
|
|
1894
|
+
debugMode,
|
|
1895
|
+
interactive,
|
|
1896
|
+
aiConfig
|
|
1897
|
+
});
|
|
1898
|
+
}
|
|
1899
|
+
break;
|
|
1900
|
+
}
|
|
1901
|
+
case "fail": {
|
|
1902
|
+
const failAction = action;
|
|
1903
|
+
throw new Error(failAction.message);
|
|
1904
|
+
}
|
|
1534
1905
|
default:
|
|
1535
1906
|
throw new Error(`Unsupported action type: ${action.type}`);
|
|
1536
1907
|
}
|
|
@@ -1575,7 +1946,7 @@ var runWebTest = async (test, options = {}) => {
|
|
|
1575
1946
|
const headless = !(options.headed ?? false);
|
|
1576
1947
|
const screenshotDir = options.screenshotDir ?? defaultScreenshotDir;
|
|
1577
1948
|
const defaultTimeout = options.defaultTimeoutMs ?? 3e4;
|
|
1578
|
-
const sessionId =
|
|
1949
|
+
const sessionId = crypto4.randomUUID();
|
|
1579
1950
|
const trackingServer = new TrackingServer();
|
|
1580
1951
|
await trackingServer.start();
|
|
1581
1952
|
process.env.INTELLITESTER_SESSION_ID = sessionId;
|
|
@@ -1881,19 +2252,14 @@ var getBrowser2 = (browser) => {
|
|
|
1881
2252
|
};
|
|
1882
2253
|
function interpolateWorkflowVariables(value, currentVariables, testResults) {
|
|
1883
2254
|
return value.replace(/\{\{([^}]+)\}\}/g, (match, path3) => {
|
|
1884
|
-
if (path3.includes(".")) {
|
|
2255
|
+
if (path3.includes(".") && !path3.includes(":")) {
|
|
1885
2256
|
const [testId, _varName] = path3.split(".", 2);
|
|
1886
2257
|
testResults.find((t) => t.id === testId);
|
|
1887
2258
|
console.warn(`Cross-test variable interpolation {{${path3}}} not yet fully implemented`);
|
|
1888
2259
|
return match;
|
|
1889
2260
|
}
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
}
|
|
1893
|
-
if (path3 === "randomUsername") {
|
|
1894
|
-
return generateRandomUsername();
|
|
1895
|
-
}
|
|
1896
|
-
return currentVariables.get(path3) ?? match;
|
|
2261
|
+
const result = interpolateVariables(`{{${path3}}}`, currentVariables);
|
|
2262
|
+
return result;
|
|
1897
2263
|
});
|
|
1898
2264
|
}
|
|
1899
2265
|
async function runTestInWorkflow(test, page, context, options, _workflowDir, workflowBaseUrl) {
|
|
@@ -1909,16 +2275,8 @@ async function runTestInWorkflow(test, page, context, options, _workflowDir, wor
|
|
|
1909
2275
|
return value;
|
|
1910
2276
|
}
|
|
1911
2277
|
};
|
|
1912
|
-
const
|
|
1913
|
-
return value
|
|
1914
|
-
if (varName === "uuid") {
|
|
1915
|
-
return crypto2.randomUUID().split("-")[0];
|
|
1916
|
-
}
|
|
1917
|
-
if (varName === "randomUsername") {
|
|
1918
|
-
return generateRandomUsername();
|
|
1919
|
-
}
|
|
1920
|
-
return context.variables.get(varName) ?? match;
|
|
1921
|
-
});
|
|
2278
|
+
const interpolate = (value) => {
|
|
2279
|
+
return interpolateVariables(value, context.variables);
|
|
1922
2280
|
};
|
|
1923
2281
|
const resolveLocator2 = (locator) => {
|
|
1924
2282
|
if (locator.testId) return page.getByTestId(locator.testId);
|
|
@@ -1941,7 +2299,7 @@ async function runTestInWorkflow(test, page, context, options, _workflowDir, wor
|
|
|
1941
2299
|
try {
|
|
1942
2300
|
switch (action.type) {
|
|
1943
2301
|
case "navigate": {
|
|
1944
|
-
const interpolated =
|
|
2302
|
+
const interpolated = interpolate(action.value);
|
|
1945
2303
|
const baseUrl = test.config?.web?.baseUrl ?? workflowBaseUrl;
|
|
1946
2304
|
const target = resolveUrl2(interpolated, baseUrl);
|
|
1947
2305
|
if (debugMode) console.log(` [DEBUG] Navigating to: ${target}`);
|
|
@@ -1955,7 +2313,7 @@ async function runTestInWorkflow(test, page, context, options, _workflowDir, wor
|
|
|
1955
2313
|
break;
|
|
1956
2314
|
}
|
|
1957
2315
|
case "input": {
|
|
1958
|
-
const interpolated =
|
|
2316
|
+
const interpolated = interpolate(action.value);
|
|
1959
2317
|
if (debugMode) console.log(` [DEBUG] Input: ${interpolated}`);
|
|
1960
2318
|
const handle = resolveLocator2(action.target);
|
|
1961
2319
|
await handle.fill(interpolated);
|
|
@@ -1974,7 +2332,7 @@ async function runTestInWorkflow(test, page, context, options, _workflowDir, wor
|
|
|
1974
2332
|
break;
|
|
1975
2333
|
}
|
|
1976
2334
|
case "select": {
|
|
1977
|
-
const interpolated =
|
|
2335
|
+
const interpolated = interpolate(action.value);
|
|
1978
2336
|
if (debugMode) console.log(` [DEBUG] Selecting: ${interpolated}`);
|
|
1979
2337
|
const handle = resolveLocator2(action.target);
|
|
1980
2338
|
await handle.selectOption(interpolated);
|
|
@@ -2013,7 +2371,7 @@ async function runTestInWorkflow(test, page, context, options, _workflowDir, wor
|
|
|
2013
2371
|
const handle = resolveLocator2(action.target);
|
|
2014
2372
|
await handle.waitFor({ state: "visible" });
|
|
2015
2373
|
if (action.value) {
|
|
2016
|
-
const interpolated =
|
|
2374
|
+
const interpolated = interpolate(action.value);
|
|
2017
2375
|
const text = (await handle.textContent())?.trim() ?? "";
|
|
2018
2376
|
if (!text.includes(interpolated)) {
|
|
2019
2377
|
throw new Error(
|
|
@@ -2054,7 +2412,7 @@ async function runTestInWorkflow(test, page, context, options, _workflowDir, wor
|
|
|
2054
2412
|
case "setVar": {
|
|
2055
2413
|
let value;
|
|
2056
2414
|
if (action.value) {
|
|
2057
|
-
value =
|
|
2415
|
+
value = interpolate(action.value);
|
|
2058
2416
|
} else if (action.from === "response") {
|
|
2059
2417
|
throw new Error("setVar from response not yet implemented");
|
|
2060
2418
|
} else if (action.from === "element") {
|
|
@@ -2072,7 +2430,7 @@ async function runTestInWorkflow(test, page, context, options, _workflowDir, wor
|
|
|
2072
2430
|
if (!context.emailClient) {
|
|
2073
2431
|
throw new Error("Email client not configured");
|
|
2074
2432
|
}
|
|
2075
|
-
const mailbox =
|
|
2433
|
+
const mailbox = interpolate(action.mailbox);
|
|
2076
2434
|
context.lastEmail = await context.emailClient.waitForEmail(mailbox, {
|
|
2077
2435
|
timeout: action.timeout,
|
|
2078
2436
|
subjectContains: action.subjectContains
|
|
@@ -2117,7 +2475,7 @@ async function runTestInWorkflow(test, page, context, options, _workflowDir, wor
|
|
|
2117
2475
|
if (!context.emailClient) {
|
|
2118
2476
|
throw new Error("Email client not configured");
|
|
2119
2477
|
}
|
|
2120
|
-
const mailbox =
|
|
2478
|
+
const mailbox = interpolate(action.mailbox);
|
|
2121
2479
|
await context.emailClient.clearMailbox(mailbox);
|
|
2122
2480
|
break;
|
|
2123
2481
|
}
|
|
@@ -2337,7 +2695,7 @@ function inferCleanupConfig(config) {
|
|
|
2337
2695
|
async function runWorkflowWithContext(workflow, workflowFilePath, options) {
|
|
2338
2696
|
const { page, executionContext, skipCleanup = false, sessionId: providedSessionId, testStartTime: providedTestStartTime } = options;
|
|
2339
2697
|
const workflowDir = path.dirname(workflowFilePath);
|
|
2340
|
-
const sessionId = providedSessionId ??
|
|
2698
|
+
const sessionId = providedSessionId ?? crypto4.randomUUID();
|
|
2341
2699
|
const testStartTime = providedTestStartTime ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
2342
2700
|
console.log(`
|
|
2343
2701
|
Starting workflow: ${workflow.name}`);
|
|
@@ -2356,11 +2714,7 @@ Starting workflow: ${workflow.name}`);
|
|
|
2356
2714
|
if (workflow.variables) {
|
|
2357
2715
|
for (const [key, value] of Object.entries(workflow.variables)) {
|
|
2358
2716
|
if (!executionContext.variables.has(key)) {
|
|
2359
|
-
const interpolated = value
|
|
2360
|
-
if (varName === "uuid") return crypto2.randomUUID().split("-")[0];
|
|
2361
|
-
if (varName === "randomUsername") return generateRandomUsername();
|
|
2362
|
-
return executionContext.variables.get(varName) ?? match;
|
|
2363
|
-
});
|
|
2717
|
+
const interpolated = interpolateVariables(value, executionContext.variables);
|
|
2364
2718
|
executionContext.variables.set(key, interpolated);
|
|
2365
2719
|
}
|
|
2366
2720
|
}
|
|
@@ -2390,15 +2744,7 @@ Starting workflow: ${workflow.name}`);
|
|
|
2390
2744
|
}
|
|
2391
2745
|
if (test.variables) {
|
|
2392
2746
|
for (const [key, value] of Object.entries(test.variables)) {
|
|
2393
|
-
const interpolated = value
|
|
2394
|
-
if (varName === "uuid") {
|
|
2395
|
-
return crypto2.randomUUID().split("-")[0];
|
|
2396
|
-
}
|
|
2397
|
-
if (varName === "randomUsername") {
|
|
2398
|
-
return generateRandomUsername();
|
|
2399
|
-
}
|
|
2400
|
-
return executionContext.variables.get(varName) ?? match;
|
|
2401
|
-
});
|
|
2747
|
+
const interpolated = interpolateVariables(value, executionContext.variables);
|
|
2402
2748
|
executionContext.variables.set(key, interpolated);
|
|
2403
2749
|
}
|
|
2404
2750
|
}
|
|
@@ -2537,7 +2883,7 @@ ${"=".repeat(60)}`);
|
|
|
2537
2883
|
}
|
|
2538
2884
|
async function runWorkflow(workflow, workflowFilePath, options = {}) {
|
|
2539
2885
|
const workflowDir = path.dirname(workflowFilePath);
|
|
2540
|
-
const sessionId =
|
|
2886
|
+
const sessionId = crypto4.randomUUID();
|
|
2541
2887
|
const testStartTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
2542
2888
|
let trackingServer = null;
|
|
2543
2889
|
try {
|
|
@@ -2594,11 +2940,7 @@ async function runWorkflow(workflow, workflowFilePath, options = {}) {
|
|
|
2594
2940
|
};
|
|
2595
2941
|
if (workflow.variables) {
|
|
2596
2942
|
for (const [key, value] of Object.entries(workflow.variables)) {
|
|
2597
|
-
const interpolated = value
|
|
2598
|
-
if (varName === "uuid") return crypto2.randomUUID().split("-")[0];
|
|
2599
|
-
if (varName === "randomUsername") return generateRandomUsername();
|
|
2600
|
-
return executionContext.variables.get(varName) ?? match;
|
|
2601
|
-
});
|
|
2943
|
+
const interpolated = interpolateVariables(value, executionContext.variables);
|
|
2602
2944
|
executionContext.variables.set(key, interpolated);
|
|
2603
2945
|
}
|
|
2604
2946
|
}
|
|
@@ -2717,6 +3059,6 @@ Collected ${serverResources.length} server-tracked resources`);
|
|
|
2717
3059
|
}
|
|
2718
3060
|
}
|
|
2719
3061
|
|
|
2720
|
-
export { ActionSchema, IntellitesterConfigSchema, LocatorSchema, TestConfigSchema, TestDefinitionSchema, cleanupConfigSchema, cleanupDiscoverSchema, collectMissingEnvVars, createAIProvider, createTestContext, generateRandomUsername, isPipelineContent, isPipelineFile, isWorkflowContent, isWorkflowFile, killServer, loadIntellitesterConfig, loadPipelineDefinition, loadTestDefinition, loadWorkflowDefinition, parseIntellitesterConfig, parsePipelineDefinition, parseTestDefinition, parseWorkflowDefinition, previewConfigSchema, runWebTest, runWorkflow, runWorkflowWithContext, setupAppwriteTracking, startTrackingServer, startWebServer };
|
|
2721
|
-
//# sourceMappingURL=chunk-
|
|
2722
|
-
//# sourceMappingURL=chunk-
|
|
3062
|
+
export { ActionSchema, IntellitesterConfigSchema, LocatorSchema, TestConfigSchema, TestDefinitionSchema, cleanupConfigSchema, cleanupDiscoverSchema, collectMissingEnvVars, createAIProvider, createTestContext, generateFillerText, generateRandomEmail, generateRandomPhone, generateRandomPhoto, generateRandomUsername, interpolateVariables, isPipelineContent, isPipelineFile, isWorkflowContent, isWorkflowFile, killServer, loadIntellitesterConfig, loadPipelineDefinition, loadTestDefinition, loadWorkflowDefinition, parseIntellitesterConfig, parsePipelineDefinition, parseTestDefinition, parseWorkflowDefinition, previewConfigSchema, runWebTest, runWorkflow, runWorkflowWithContext, setupAppwriteTracking, startTrackingServer, startWebServer };
|
|
3063
|
+
//# sourceMappingURL=chunk-CKUSY4ZM.js.map
|
|
3064
|
+
//# sourceMappingURL=chunk-CKUSY4ZM.js.map
|