intellitester 0.2.35 → 0.2.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +185 -2
- package/dist/{chunk-EPN5OT5I.js → chunk-2KTVH32L.js} +72 -6
- package/dist/chunk-2KTVH32L.js.map +1 -0
- package/dist/{chunk-DPT2LVTT.cjs → chunk-FPXDBPCY.cjs} +30 -15
- package/dist/chunk-FPXDBPCY.cjs.map +1 -0
- package/dist/{chunk-64V2U2Y4.js → chunk-ML5CBUF7.js} +30 -16
- package/dist/chunk-ML5CBUF7.js.map +1 -0
- package/dist/{chunk-CBPY7B6L.cjs → chunk-PXHFBOEI.cjs} +74 -8
- package/dist/chunk-PXHFBOEI.cjs.map +1 -0
- package/dist/cli/index.cjs +933 -39
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +896 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +39 -35
- package/dist/index.d.cts +798 -11
- package/dist/index.d.ts +798 -11
- package/dist/index.js +2 -2
- package/dist/{loader-6IZ4CERA.cjs → loader-2DVZWBH3.cjs} +16 -16
- package/dist/{loader-6IZ4CERA.cjs.map → loader-2DVZWBH3.cjs.map} +1 -1
- package/dist/{loader-JSTO36JJ.js → loader-B46MGIWG.js} +3 -3
- package/dist/{loader-JSTO36JJ.js.map → loader-B46MGIWG.js.map} +1 -1
- package/package.json +1 -1
- package/schemas/test.schema.json +25 -0
- package/dist/chunk-64V2U2Y4.js.map +0 -1
- package/dist/chunk-CBPY7B6L.cjs.map +0 -1
- package/dist/chunk-DPT2LVTT.cjs.map +0 -1
- package/dist/chunk-EPN5OT5I.js.map +0 -1
package/README.md
CHANGED
|
@@ -12,6 +12,33 @@ npx playwright install chromium
|
|
|
12
12
|
npx playwright install
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
## AI Assistant Integration
|
|
16
|
+
|
|
17
|
+
IntelliTester can generate comprehensive documentation for AI assistants (Claude, GPT, etc.) to help them write effective tests.
|
|
18
|
+
|
|
19
|
+
### Generate Guide
|
|
20
|
+
|
|
21
|
+
Use the `guide` command to create an `intellitester_guide.md` file in your project:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
intellitester guide
|
|
25
|
+
# Or use the alias:
|
|
26
|
+
intellitester init-guide
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This generates a detailed reference document that AI assistants can read to understand:
|
|
30
|
+
- All action types and their syntax
|
|
31
|
+
- Target selector options (testId, text, css, xpath, role, description)
|
|
32
|
+
- Variable interpolation and built-in generators
|
|
33
|
+
- Best practices for test organization
|
|
34
|
+
- Common testing patterns (login flows, form submissions, email verification)
|
|
35
|
+
- Configuration options for tests, workflows, and pipelines
|
|
36
|
+
|
|
37
|
+
The guide is particularly useful when:
|
|
38
|
+
- Using AI assistants to generate test files
|
|
39
|
+
- Onboarding team members who use AI coding tools
|
|
40
|
+
- Maintaining consistent test patterns across a team
|
|
41
|
+
|
|
15
42
|
## Editor Configuration
|
|
16
43
|
|
|
17
44
|
IntelliTester provides JSON schemas for YAML configuration files to enable autocomplete and validation in VS Code and other editors.
|
|
@@ -25,7 +52,8 @@ Add this to your `.vscode/settings.json` (or workspace settings):
|
|
|
25
52
|
"yaml.schemas": {
|
|
26
53
|
"./node_modules/intellitester/schemas/intellitester.config.schema.json": "intellitester.config.yaml",
|
|
27
54
|
"./node_modules/intellitester/schemas/test.schema.json": "*.test.yaml",
|
|
28
|
-
"./node_modules/intellitester/schemas/workflow.schema.json": "*.workflow.yaml"
|
|
55
|
+
"./node_modules/intellitester/schemas/workflow.schema.json": "*.workflow.yaml",
|
|
56
|
+
"./node_modules/intellitester/schemas/pipeline.schema.json": "*.pipeline.yaml"
|
|
29
57
|
}
|
|
30
58
|
}
|
|
31
59
|
```
|
|
@@ -45,7 +73,8 @@ If you're working on IntelliTester itself or want to use local schemas, use thes
|
|
|
45
73
|
"yaml.schemas": {
|
|
46
74
|
"./schemas/intellitester.config.schema.json": "intellitester.config.yaml",
|
|
47
75
|
"./schemas/test.schema.json": "*.test.yaml",
|
|
48
|
-
"./schemas/workflow.schema.json": "*.workflow.yaml"
|
|
76
|
+
"./schemas/workflow.schema.json": "*.workflow.yaml",
|
|
77
|
+
"./schemas/pipeline.schema.json": "*.pipeline.yaml"
|
|
49
78
|
}
|
|
50
79
|
}
|
|
51
80
|
```
|
|
@@ -84,6 +113,37 @@ When execution pauses, you can:
|
|
|
84
113
|
- Examine selectors and elements
|
|
85
114
|
- Continue execution when ready
|
|
86
115
|
|
|
116
|
+
## Fast-Fail Conditions (errorIf)
|
|
117
|
+
|
|
118
|
+
Use `errorIf` to fail a step immediately when a condition is met, without waiting for timeouts:
|
|
119
|
+
|
|
120
|
+
```yaml
|
|
121
|
+
steps:
|
|
122
|
+
- type: tap
|
|
123
|
+
target: { testId: login-btn }
|
|
124
|
+
errorIf: not-found # Fail immediately if element not found
|
|
125
|
+
|
|
126
|
+
- type: assert
|
|
127
|
+
target: { testId: welcome-msg }
|
|
128
|
+
errorIf: not-visible # Fail if element exists but not visible
|
|
129
|
+
|
|
130
|
+
- type: input
|
|
131
|
+
target: { testId: email }
|
|
132
|
+
value: test@example.com
|
|
133
|
+
errorIf: disabled # Fail if input is disabled
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Available conditions:**
|
|
137
|
+
|
|
138
|
+
| Condition | Description |
|
|
139
|
+
|-----------|-------------|
|
|
140
|
+
| `not-found` | Element doesn't exist in DOM |
|
|
141
|
+
| `not-visible` | Element exists but not visible |
|
|
142
|
+
| `disabled` | Element is disabled |
|
|
143
|
+
| `empty` | Element has no text content |
|
|
144
|
+
|
|
145
|
+
> **Note:** `testId` now matches `data-testid`, `id`, and `class` attributes in that order.
|
|
146
|
+
|
|
87
147
|
## Resource Cleanup
|
|
88
148
|
|
|
89
149
|
IntelliTester automatically tracks resources created during tests and cleans them up after execution. This ensures tests don't leave behind database rows, files, users, or other artifacts.
|
|
@@ -215,3 +275,126 @@ intellitester run --session-id my-session --track-dir .intellitester/track
|
|
|
215
275
|
```
|
|
216
276
|
|
|
217
277
|
If `INTELLITESTER_TRACK_URL` is set, `track()` will send HTTP requests and also append to the track file (when available). If only the file is set, `track()` writes locally.
|
|
278
|
+
|
|
279
|
+
## Pipelines & Workflows
|
|
280
|
+
|
|
281
|
+
IntelliTester supports three levels of test organization:
|
|
282
|
+
|
|
283
|
+
### Test Files (`*.test.yaml`)
|
|
284
|
+
|
|
285
|
+
A single test with a sequence of steps. The most basic building block.
|
|
286
|
+
|
|
287
|
+
```yaml
|
|
288
|
+
name: Login Test
|
|
289
|
+
platform: web
|
|
290
|
+
variables:
|
|
291
|
+
EMAIL: test@example.com
|
|
292
|
+
steps:
|
|
293
|
+
- type: navigate
|
|
294
|
+
value: /login
|
|
295
|
+
- type: input
|
|
296
|
+
target: { testId: email }
|
|
297
|
+
value: ${EMAIL}
|
|
298
|
+
- type: input
|
|
299
|
+
target: { testId: password }
|
|
300
|
+
value: secret123
|
|
301
|
+
- type: tap
|
|
302
|
+
target: { text: Sign In }
|
|
303
|
+
- type: assert
|
|
304
|
+
target: { text: Welcome }
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Workflows (`*.workflow.yaml`)
|
|
308
|
+
|
|
309
|
+
Multiple tests run in sequence with a shared browser session. Tests share cookies, local storage, and authentication state.
|
|
310
|
+
|
|
311
|
+
```yaml
|
|
312
|
+
name: User Onboarding
|
|
313
|
+
platform: web
|
|
314
|
+
config:
|
|
315
|
+
web:
|
|
316
|
+
baseUrl: http://localhost:3000
|
|
317
|
+
continueOnFailure: false
|
|
318
|
+
tests:
|
|
319
|
+
- file: ./signup.test.yaml
|
|
320
|
+
id: signup
|
|
321
|
+
- file: ./verify-email.test.yaml
|
|
322
|
+
id: verify
|
|
323
|
+
variables:
|
|
324
|
+
EMAIL: ${signup.EMAIL}
|
|
325
|
+
- file: ./complete-profile.test.yaml
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Pipelines (`*.pipeline.yaml`)
|
|
329
|
+
|
|
330
|
+
Multiple workflows with shared browser session, dependencies, and variables. Pipelines orchestrate complex test suites with control over execution order and failure handling.
|
|
331
|
+
|
|
332
|
+
```yaml
|
|
333
|
+
name: Full E2E Suite
|
|
334
|
+
platform: web
|
|
335
|
+
on_failure: skip # skip | fail | ignore
|
|
336
|
+
cleanup_on_failure: true
|
|
337
|
+
config:
|
|
338
|
+
web:
|
|
339
|
+
baseUrl: http://localhost:3000
|
|
340
|
+
webServer:
|
|
341
|
+
command: npm run dev
|
|
342
|
+
url: http://localhost:3000
|
|
343
|
+
reuseExistingServer: true
|
|
344
|
+
timeout: 30000
|
|
345
|
+
workflows:
|
|
346
|
+
- file: ./auth.workflow.yaml
|
|
347
|
+
id: auth
|
|
348
|
+
on_failure: fail # Stop pipeline if auth fails
|
|
349
|
+
|
|
350
|
+
- file: ./dashboard.workflow.yaml
|
|
351
|
+
id: dashboard
|
|
352
|
+
depends_on: [auth]
|
|
353
|
+
variables:
|
|
354
|
+
USER_TOKEN: ${auth.TOKEN}
|
|
355
|
+
|
|
356
|
+
- file: ./settings.workflow.yaml
|
|
357
|
+
depends_on: [auth]
|
|
358
|
+
on_failure: ignore # Continue even if settings tests fail
|
|
359
|
+
|
|
360
|
+
- file: ./cleanup.workflow.yaml
|
|
361
|
+
depends_on: [dashboard, settings]
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Pipeline Features
|
|
365
|
+
|
|
366
|
+
**Workflow Properties:**
|
|
367
|
+
|
|
368
|
+
| Property | Description |
|
|
369
|
+
|----------|-------------|
|
|
370
|
+
| `file` | Path to the workflow file (required) |
|
|
371
|
+
| `id` | Identifier for referencing in `depends_on` and variable passing |
|
|
372
|
+
| `depends_on` | Array of workflow IDs that must complete first |
|
|
373
|
+
| `variables` | Variables to inject, can reference outputs from dependencies |
|
|
374
|
+
| `on_failure` | How to handle failure: `skip`, `fail`, or `ignore` |
|
|
375
|
+
|
|
376
|
+
**Failure Handling (`on_failure`):**
|
|
377
|
+
|
|
378
|
+
- `skip` - Skip dependent workflows, continue independent ones (default)
|
|
379
|
+
- `fail` - Stop the entire pipeline immediately
|
|
380
|
+
- `ignore` - Continue as if the workflow succeeded
|
|
381
|
+
|
|
382
|
+
**Web Server (`config.webServer`):**
|
|
383
|
+
|
|
384
|
+
Start a dev server automatically before running tests:
|
|
385
|
+
|
|
386
|
+
```yaml
|
|
387
|
+
config:
|
|
388
|
+
webServer:
|
|
389
|
+
command: npm run dev # Command to start server
|
|
390
|
+
url: http://localhost:3000 # Wait for this URL
|
|
391
|
+
reuseExistingServer: true # Use existing if running
|
|
392
|
+
timeout: 30000 # Startup timeout (ms)
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
**Shared Browser Session:**
|
|
396
|
+
|
|
397
|
+
All workflows in a pipeline share the same browser context, preserving:
|
|
398
|
+
- Cookies and session storage
|
|
399
|
+
- Authentication state
|
|
400
|
+
- Local storage data
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { loadTestDefinition } from './chunk-
|
|
1
|
+
import { loadTestDefinition } from './chunk-ML5CBUF7.js';
|
|
2
2
|
import { track } from './chunk-2BFRS6ZZ.js';
|
|
3
3
|
import { loadCleanupHandlers, executeCleanup, saveFailedCleanup } from './chunk-O4H5QO5P.js';
|
|
4
4
|
import { NumberDictionary, uniqueNamesGenerator, adjectives, animals } from 'unique-names-generator';
|
|
@@ -1036,7 +1036,11 @@ var resolveUrl = (value, baseUrl) => {
|
|
|
1036
1036
|
}
|
|
1037
1037
|
};
|
|
1038
1038
|
var resolveLocator = (page, locator) => {
|
|
1039
|
-
if (locator.testId)
|
|
1039
|
+
if (locator.testId) {
|
|
1040
|
+
return page.locator(
|
|
1041
|
+
`[data-testid="${locator.testId}"], #${CSS.escape(locator.testId)}, .${CSS.escape(locator.testId)}`
|
|
1042
|
+
).first();
|
|
1043
|
+
}
|
|
1040
1044
|
if (locator.text) return page.getByText(locator.text);
|
|
1041
1045
|
if (locator.css) return page.locator(locator.css);
|
|
1042
1046
|
if (locator.xpath) return page.locator(`xpath=${locator.xpath}`);
|
|
@@ -1048,6 +1052,49 @@ var resolveLocator = (page, locator) => {
|
|
|
1048
1052
|
if (locator.description) return page.getByText(locator.description);
|
|
1049
1053
|
throw new Error("No usable selector found for locator");
|
|
1050
1054
|
};
|
|
1055
|
+
var checkErrorIf = async (page, locator, errorIf) => {
|
|
1056
|
+
if (!errorIf) return;
|
|
1057
|
+
const handle = resolveLocator(page, locator);
|
|
1058
|
+
switch (errorIf) {
|
|
1059
|
+
case "not-found": {
|
|
1060
|
+
const count = await handle.count();
|
|
1061
|
+
if (count === 0) {
|
|
1062
|
+
throw new Error(`errorIf: Element not found in DOM (testId/selector: ${JSON.stringify(locator)})`);
|
|
1063
|
+
}
|
|
1064
|
+
break;
|
|
1065
|
+
}
|
|
1066
|
+
case "not-visible": {
|
|
1067
|
+
const count = await handle.count();
|
|
1068
|
+
if (count > 0) {
|
|
1069
|
+
const isVisible = await handle.isVisible();
|
|
1070
|
+
if (!isVisible) {
|
|
1071
|
+
throw new Error(`errorIf: Element exists but is not visible (testId/selector: ${JSON.stringify(locator)})`);
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
break;
|
|
1075
|
+
}
|
|
1076
|
+
case "disabled": {
|
|
1077
|
+
const count = await handle.count();
|
|
1078
|
+
if (count > 0) {
|
|
1079
|
+
const isDisabled = await handle.isDisabled();
|
|
1080
|
+
if (isDisabled) {
|
|
1081
|
+
throw new Error(`errorIf: Element is disabled (testId/selector: ${JSON.stringify(locator)})`);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
break;
|
|
1085
|
+
}
|
|
1086
|
+
case "empty": {
|
|
1087
|
+
const count = await handle.count();
|
|
1088
|
+
if (count > 0) {
|
|
1089
|
+
const text = await handle.textContent();
|
|
1090
|
+
if (!text || text.trim() === "") {
|
|
1091
|
+
throw new Error(`errorIf: Element has no text content (testId/selector: ${JSON.stringify(locator)})`);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
break;
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
};
|
|
1051
1098
|
async function ensureScreenshotDir(dir) {
|
|
1052
1099
|
await fs.mkdir(dir, { recursive: true });
|
|
1053
1100
|
}
|
|
@@ -1379,6 +1426,7 @@ async function executeActionWithRetry(page, action, index, options) {
|
|
|
1379
1426
|
if (debugMode) {
|
|
1380
1427
|
console.log(`[DEBUG] Tapping element:`, action.target);
|
|
1381
1428
|
}
|
|
1429
|
+
await checkErrorIf(page, action.target, action.errorIf);
|
|
1382
1430
|
await runTap(page, action.target);
|
|
1383
1431
|
break;
|
|
1384
1432
|
}
|
|
@@ -1388,17 +1436,20 @@ async function executeActionWithRetry(page, action, index, options) {
|
|
|
1388
1436
|
console.log(`[DEBUG] Inputting value into element:`, action.target);
|
|
1389
1437
|
console.log(`[DEBUG] Value: ${interpolated}`);
|
|
1390
1438
|
}
|
|
1439
|
+
await checkErrorIf(page, action.target, action.errorIf);
|
|
1391
1440
|
await runInput(page, action.target, action.value, context);
|
|
1392
1441
|
break;
|
|
1393
1442
|
}
|
|
1394
1443
|
case "clear": {
|
|
1395
1444
|
if (debugMode) console.log(`[DEBUG] Clearing element:`, action.target);
|
|
1445
|
+
await checkErrorIf(page, action.target, action.errorIf);
|
|
1396
1446
|
const handle = resolveLocator(page, action.target);
|
|
1397
1447
|
await handle.clear();
|
|
1398
1448
|
break;
|
|
1399
1449
|
}
|
|
1400
1450
|
case "hover": {
|
|
1401
1451
|
if (debugMode) console.log(`[DEBUG] Hovering element:`, action.target);
|
|
1452
|
+
await checkErrorIf(page, action.target, action.errorIf);
|
|
1402
1453
|
const handle = resolveLocator(page, action.target);
|
|
1403
1454
|
await handle.hover();
|
|
1404
1455
|
break;
|
|
@@ -1406,18 +1457,21 @@ async function executeActionWithRetry(page, action, index, options) {
|
|
|
1406
1457
|
case "select": {
|
|
1407
1458
|
const interpolated = interpolateVariables(action.value, context.variables);
|
|
1408
1459
|
if (debugMode) console.log(`[DEBUG] Selecting: ${interpolated}`);
|
|
1460
|
+
await checkErrorIf(page, action.target, action.errorIf);
|
|
1409
1461
|
const handle = resolveLocator(page, action.target);
|
|
1410
1462
|
await handle.selectOption(interpolated);
|
|
1411
1463
|
break;
|
|
1412
1464
|
}
|
|
1413
1465
|
case "check": {
|
|
1414
1466
|
if (debugMode) console.log(`[DEBUG] Checking:`, action.target);
|
|
1467
|
+
await checkErrorIf(page, action.target, action.errorIf);
|
|
1415
1468
|
const handle = resolveLocator(page, action.target);
|
|
1416
1469
|
await handle.check();
|
|
1417
1470
|
break;
|
|
1418
1471
|
}
|
|
1419
1472
|
case "uncheck": {
|
|
1420
1473
|
if (debugMode) console.log(`[DEBUG] Unchecking:`, action.target);
|
|
1474
|
+
await checkErrorIf(page, action.target, action.errorIf);
|
|
1421
1475
|
const handle = resolveLocator(page, action.target);
|
|
1422
1476
|
await handle.uncheck();
|
|
1423
1477
|
break;
|
|
@@ -1425,6 +1479,7 @@ async function executeActionWithRetry(page, action, index, options) {
|
|
|
1425
1479
|
case "press": {
|
|
1426
1480
|
if (debugMode) console.log(`[DEBUG] Pressing key: ${action.key}`);
|
|
1427
1481
|
if (action.target) {
|
|
1482
|
+
await checkErrorIf(page, action.target, action.errorIf);
|
|
1428
1483
|
const handle = resolveLocator(page, action.target);
|
|
1429
1484
|
await handle.press(action.key);
|
|
1430
1485
|
} else {
|
|
@@ -1434,6 +1489,7 @@ async function executeActionWithRetry(page, action, index, options) {
|
|
|
1434
1489
|
}
|
|
1435
1490
|
case "focus": {
|
|
1436
1491
|
if (debugMode) console.log(`[DEBUG] Focusing:`, action.target);
|
|
1492
|
+
await checkErrorIf(page, action.target, action.errorIf);
|
|
1437
1493
|
const handle = resolveLocator(page, action.target);
|
|
1438
1494
|
await handle.focus();
|
|
1439
1495
|
break;
|
|
@@ -1446,13 +1502,20 @@ async function executeActionWithRetry(page, action, index, options) {
|
|
|
1446
1502
|
console.log(`[DEBUG] Expected text contains: ${interpolated}`);
|
|
1447
1503
|
}
|
|
1448
1504
|
}
|
|
1505
|
+
await checkErrorIf(page, action.target, action.errorIf);
|
|
1449
1506
|
await runAssert(page, action.target, action.value, context);
|
|
1450
1507
|
break;
|
|
1451
1508
|
}
|
|
1452
1509
|
case "wait":
|
|
1510
|
+
if (action.target && action.errorIf) {
|
|
1511
|
+
await checkErrorIf(page, action.target, action.errorIf);
|
|
1512
|
+
}
|
|
1453
1513
|
await runWait(page, action);
|
|
1454
1514
|
break;
|
|
1455
1515
|
case "scroll":
|
|
1516
|
+
if (action.target && action.errorIf) {
|
|
1517
|
+
await checkErrorIf(page, action.target, action.errorIf);
|
|
1518
|
+
}
|
|
1456
1519
|
await runScroll(page, action);
|
|
1457
1520
|
break;
|
|
1458
1521
|
case "screenshot":
|
|
@@ -1547,6 +1610,9 @@ async function executeActionWithRetry(page, action, index, options) {
|
|
|
1547
1610
|
}
|
|
1548
1611
|
case "waitForSelector": {
|
|
1549
1612
|
const wsAction = action;
|
|
1613
|
+
if (wsAction.errorIf) {
|
|
1614
|
+
await checkErrorIf(page, wsAction.target, wsAction.errorIf);
|
|
1615
|
+
}
|
|
1550
1616
|
const handle = resolveLocator(page, wsAction.target);
|
|
1551
1617
|
const timeout = wsAction.timeout ?? 3e4;
|
|
1552
1618
|
if (debugMode) {
|
|
@@ -1690,7 +1756,7 @@ async function executeActionWithRetry(page, action, index, options) {
|
|
|
1690
1756
|
});
|
|
1691
1757
|
}
|
|
1692
1758
|
} else {
|
|
1693
|
-
const { loadWorkflowDefinition, loadTestDefinition: loadTestDefinition2 } = await import('./loader-
|
|
1759
|
+
const { loadWorkflowDefinition, loadTestDefinition: loadTestDefinition2 } = await import('./loader-B46MGIWG.js');
|
|
1694
1760
|
const workflowPath = path2.resolve(process.cwd(), branchToExecute.workflow);
|
|
1695
1761
|
const workflowDir = path2.dirname(workflowPath);
|
|
1696
1762
|
if (debugMode) {
|
|
@@ -2646,7 +2712,7 @@ async function runTestInWorkflow(test, page, context, options, _workflowDir, wor
|
|
|
2646
2712
|
if (debugMode) {
|
|
2647
2713
|
console.log(` [DEBUG] waitForBranch: loading workflow from ${workflowPath}`);
|
|
2648
2714
|
}
|
|
2649
|
-
const { loadWorkflowDefinition } = await import('./loader-
|
|
2715
|
+
const { loadWorkflowDefinition } = await import('./loader-B46MGIWG.js');
|
|
2650
2716
|
const nestedWorkflow = await loadWorkflowDefinition(workflowPath);
|
|
2651
2717
|
if (branch.variables) {
|
|
2652
2718
|
for (const [key, value] of Object.entries(branch.variables)) {
|
|
@@ -3275,5 +3341,5 @@ Collected ${serverResources.length} server-tracked resources`);
|
|
|
3275
3341
|
}
|
|
3276
3342
|
|
|
3277
3343
|
export { createAIProvider, createTestContext, generateFillerText, generateRandomEmail, generateRandomPhone, generateRandomPhoto, generateRandomUsername, getBrowserLaunchOptions, initFileTracking, interpolateVariables, killServer, mergeFileTrackedResources, runWebTest, runWorkflow, runWorkflowWithContext, setupAppwriteTracking, startTrackingServer, startWebServer };
|
|
3278
|
-
//# sourceMappingURL=chunk-
|
|
3279
|
-
//# sourceMappingURL=chunk-
|
|
3344
|
+
//# sourceMappingURL=chunk-2KTVH32L.js.map
|
|
3345
|
+
//# sourceMappingURL=chunk-2KTVH32L.js.map
|