intellitester 0.2.22 → 0.2.25
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-BDSLT5FJ.js +512 -0
- package/dist/chunk-BDSLT5FJ.js.map +1 -0
- package/dist/chunk-OLQKQ3TR.cjs +538 -0
- package/dist/chunk-OLQKQ3TR.cjs.map +1 -0
- package/dist/{chunk-GCF2Q77Q.cjs → chunk-SZFPANKM.cjs} +325 -545
- package/dist/chunk-SZFPANKM.cjs.map +1 -0
- package/dist/{chunk-EQJZ2E5H.js → chunk-YKAAZZCH.js} +324 -523
- package/dist/chunk-YKAAZZCH.js.map +1 -0
- package/dist/cli/index.cjs +37 -36
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +3 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +67 -66
- package/dist/index.d.cts +1084 -214
- package/dist/index.d.ts +1084 -214
- package/dist/index.js +2 -1
- package/dist/loader-DIGNOK6I.js +3 -0
- package/dist/loader-DIGNOK6I.js.map +1 -0
- package/dist/loader-JBFPNQO3.cjs +60 -0
- package/dist/loader-JBFPNQO3.cjs.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-EQJZ2E5H.js.map +0 -1
- package/dist/chunk-GCF2Q77Q.cjs.map +0 -1
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import { parse } from 'yaml';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
5
|
+
// src/core/loader.ts
|
|
6
|
+
var nonEmptyString = z.string().trim().min(1, "Value cannot be empty");
|
|
7
|
+
var LocatorSchema = z.object({
|
|
8
|
+
description: z.string().trim().optional().describe("AI-friendly description of the element to find"),
|
|
9
|
+
testId: z.string().trim().optional().describe("data-testid attribute value"),
|
|
10
|
+
text: z.string().trim().optional().describe("Visible text content"),
|
|
11
|
+
css: z.string().trim().optional().describe("CSS selector"),
|
|
12
|
+
xpath: z.string().trim().optional().describe("XPath selector"),
|
|
13
|
+
role: z.string().trim().optional().describe("ARIA role"),
|
|
14
|
+
name: z.string().trim().optional().describe("Accessible name")
|
|
15
|
+
}).describe("Defines how to locate an element on the page. At least one selector must be provided.").refine(
|
|
16
|
+
(locator) => Boolean(
|
|
17
|
+
locator.description || locator.testId || locator.text || locator.css || locator.xpath || locator.role || locator.name
|
|
18
|
+
),
|
|
19
|
+
{ message: "Locator requires at least one selector or description" }
|
|
20
|
+
);
|
|
21
|
+
var navigateActionSchema = z.object({
|
|
22
|
+
type: z.literal("navigate"),
|
|
23
|
+
value: nonEmptyString.describe("URL or path to navigate to")
|
|
24
|
+
}).describe("Navigate to a URL");
|
|
25
|
+
var tapActionSchema = z.object({
|
|
26
|
+
type: z.literal("tap"),
|
|
27
|
+
target: LocatorSchema
|
|
28
|
+
}).describe("Click or tap on an element");
|
|
29
|
+
var inputActionSchema = z.object({
|
|
30
|
+
type: z.literal("input"),
|
|
31
|
+
target: LocatorSchema,
|
|
32
|
+
value: z.string().describe("Text to input (can reference variables with ${VAR_NAME})")
|
|
33
|
+
}).describe("Input text into a field");
|
|
34
|
+
var clearActionSchema = z.object({
|
|
35
|
+
type: z.literal("clear"),
|
|
36
|
+
target: LocatorSchema
|
|
37
|
+
}).describe("Clear the contents of an input field");
|
|
38
|
+
var hoverActionSchema = z.object({
|
|
39
|
+
type: z.literal("hover"),
|
|
40
|
+
target: LocatorSchema
|
|
41
|
+
}).describe("Hover over an element");
|
|
42
|
+
var selectActionSchema = z.object({
|
|
43
|
+
type: z.literal("select"),
|
|
44
|
+
target: LocatorSchema,
|
|
45
|
+
value: z.string().describe("Option value, label, or index to select")
|
|
46
|
+
}).describe("Select an option from a dropdown");
|
|
47
|
+
var checkActionSchema = z.object({
|
|
48
|
+
type: z.literal("check"),
|
|
49
|
+
target: LocatorSchema
|
|
50
|
+
}).describe("Check a checkbox");
|
|
51
|
+
var uncheckActionSchema = z.object({
|
|
52
|
+
type: z.literal("uncheck"),
|
|
53
|
+
target: LocatorSchema
|
|
54
|
+
}).describe("Uncheck a checkbox");
|
|
55
|
+
var pressActionSchema = z.object({
|
|
56
|
+
type: z.literal("press"),
|
|
57
|
+
key: nonEmptyString.describe("Key to press (e.g., Enter, Tab, Escape, ArrowDown)"),
|
|
58
|
+
target: LocatorSchema.optional().describe("Element to focus before pressing key")
|
|
59
|
+
}).describe("Press a keyboard key");
|
|
60
|
+
var focusActionSchema = z.object({
|
|
61
|
+
type: z.literal("focus"),
|
|
62
|
+
target: LocatorSchema
|
|
63
|
+
}).describe("Focus an element");
|
|
64
|
+
var assertActionSchema = z.object({
|
|
65
|
+
type: z.literal("assert"),
|
|
66
|
+
target: LocatorSchema,
|
|
67
|
+
value: z.string().optional().describe("Expected text content")
|
|
68
|
+
}).describe("Assert that an element exists or contains expected text");
|
|
69
|
+
var waitActionSchema = z.object({
|
|
70
|
+
type: z.literal("wait"),
|
|
71
|
+
target: LocatorSchema.optional().describe("Element to wait for"),
|
|
72
|
+
timeout: z.number().int().positive().optional().describe("Time to wait in milliseconds")
|
|
73
|
+
}).describe("Wait for an element or timeout").refine((action) => action.target || action.timeout, {
|
|
74
|
+
message: "wait requires a target or timeout"
|
|
75
|
+
});
|
|
76
|
+
var scrollActionSchema = z.object({
|
|
77
|
+
type: z.literal("scroll"),
|
|
78
|
+
target: LocatorSchema.optional().describe("Element to scroll"),
|
|
79
|
+
direction: z.enum(["up", "down"]).optional().describe("Direction to scroll"),
|
|
80
|
+
amount: z.number().int().positive().optional().describe("Amount to scroll in pixels")
|
|
81
|
+
}).describe("Scroll the page or an element");
|
|
82
|
+
var screenshotActionSchema = z.object({
|
|
83
|
+
type: z.literal("screenshot"),
|
|
84
|
+
name: z.string().optional().describe("Name for the screenshot file"),
|
|
85
|
+
waitBefore: z.number().int().nonnegative().optional().describe("Milliseconds to wait before capturing for visual stability (default: 500)")
|
|
86
|
+
}).describe("Take a screenshot");
|
|
87
|
+
var setVarActionSchema = z.object({
|
|
88
|
+
type: z.literal("setVar"),
|
|
89
|
+
name: nonEmptyString.describe("Variable name to set"),
|
|
90
|
+
value: z.string().optional().describe("Static value to set"),
|
|
91
|
+
from: z.enum(["response", "element", "email"]).optional().describe("Extract value from a source"),
|
|
92
|
+
path: z.string().optional().describe("JSON path or selector for extraction"),
|
|
93
|
+
pattern: z.string().optional().describe("Regular expression pattern for extraction")
|
|
94
|
+
}).describe("Set a variable for use in later steps");
|
|
95
|
+
var emailWaitForActionSchema = z.object({
|
|
96
|
+
type: z.literal("email.waitFor"),
|
|
97
|
+
mailbox: nonEmptyString.describe("Email address or mailbox to check"),
|
|
98
|
+
timeout: z.number().int().positive().optional().describe("How long to wait for email in milliseconds"),
|
|
99
|
+
subjectContains: z.string().optional().describe("Filter by email subject")
|
|
100
|
+
}).describe("Wait for an email to arrive");
|
|
101
|
+
var emailExtractCodeActionSchema = z.object({
|
|
102
|
+
type: z.literal("email.extractCode"),
|
|
103
|
+
saveTo: nonEmptyString.describe("Variable name to save the extracted code"),
|
|
104
|
+
pattern: z.string().optional().describe("Regular expression to extract code")
|
|
105
|
+
}).describe("Extract a verification code from email");
|
|
106
|
+
var emailExtractLinkActionSchema = z.object({
|
|
107
|
+
type: z.literal("email.extractLink"),
|
|
108
|
+
saveTo: nonEmptyString.describe("Variable name to save the extracted link"),
|
|
109
|
+
pattern: z.string().optional().describe("Regular expression to match specific links")
|
|
110
|
+
}).describe("Extract a link from email");
|
|
111
|
+
var emailClearActionSchema = z.object({
|
|
112
|
+
type: z.literal("email.clear"),
|
|
113
|
+
mailbox: nonEmptyString.describe("Email address or mailbox to clear")
|
|
114
|
+
}).describe("Clear emails from a mailbox");
|
|
115
|
+
var appwriteVerifyEmailActionSchema = z.object({
|
|
116
|
+
type: z.literal("appwrite.verifyEmail")
|
|
117
|
+
}).describe("Verify email using Appwrite");
|
|
118
|
+
var debugActionSchema = z.object({
|
|
119
|
+
type: z.literal("debug")
|
|
120
|
+
}).describe("Pause execution and open Playwright Inspector for debugging");
|
|
121
|
+
var waitForSelectorActionSchema = z.object({
|
|
122
|
+
type: z.literal("waitForSelector"),
|
|
123
|
+
target: LocatorSchema,
|
|
124
|
+
state: z.enum(["enabled", "disabled", "visible", "hidden", "attached", "detached"]).describe("Element state to wait for"),
|
|
125
|
+
timeout: z.number().int().positive().optional().describe("Time to wait in milliseconds")
|
|
126
|
+
}).describe("Wait for an element to reach a specific state");
|
|
127
|
+
var failActionSchema = z.object({
|
|
128
|
+
type: z.literal("fail"),
|
|
129
|
+
message: nonEmptyString.describe("Error message to display when test fails")
|
|
130
|
+
}).describe("Explicitly fail the test with a custom message");
|
|
131
|
+
var BaseActionSchema = z.discriminatedUnion("type", [
|
|
132
|
+
navigateActionSchema,
|
|
133
|
+
tapActionSchema,
|
|
134
|
+
inputActionSchema,
|
|
135
|
+
clearActionSchema,
|
|
136
|
+
hoverActionSchema,
|
|
137
|
+
selectActionSchema,
|
|
138
|
+
checkActionSchema,
|
|
139
|
+
uncheckActionSchema,
|
|
140
|
+
pressActionSchema,
|
|
141
|
+
focusActionSchema,
|
|
142
|
+
assertActionSchema,
|
|
143
|
+
waitActionSchema,
|
|
144
|
+
scrollActionSchema,
|
|
145
|
+
screenshotActionSchema,
|
|
146
|
+
setVarActionSchema,
|
|
147
|
+
emailWaitForActionSchema,
|
|
148
|
+
emailExtractCodeActionSchema,
|
|
149
|
+
emailExtractLinkActionSchema,
|
|
150
|
+
emailClearActionSchema,
|
|
151
|
+
appwriteVerifyEmailActionSchema,
|
|
152
|
+
debugActionSchema,
|
|
153
|
+
waitForSelectorActionSchema,
|
|
154
|
+
failActionSchema
|
|
155
|
+
]);
|
|
156
|
+
var conditionalActionSchema = z.object({
|
|
157
|
+
type: z.literal("conditional"),
|
|
158
|
+
condition: z.object({
|
|
159
|
+
type: z.enum(["exists", "notExists", "visible", "hidden"]),
|
|
160
|
+
target: LocatorSchema
|
|
161
|
+
}).describe("Condition to check"),
|
|
162
|
+
then: z.array(BaseActionSchema).describe("Steps to execute if condition is true"),
|
|
163
|
+
else: z.array(BaseActionSchema).optional().describe("Steps to execute if condition is false")
|
|
164
|
+
}).describe("Execute steps conditionally based on element state");
|
|
165
|
+
var branchSchema = z.union([
|
|
166
|
+
z.array(BaseActionSchema),
|
|
167
|
+
// Inline actions
|
|
168
|
+
z.object({
|
|
169
|
+
workflow: z.string().trim().min(1).describe("Path to workflow file relative to current file"),
|
|
170
|
+
variables: z.record(z.string(), z.string()).optional().describe("Variables to pass to the workflow")
|
|
171
|
+
})
|
|
172
|
+
]).describe("Actions to execute - either inline steps or a workflow file reference");
|
|
173
|
+
var waitForBranchActionSchema = z.object({
|
|
174
|
+
type: z.literal("waitForBranch"),
|
|
175
|
+
target: LocatorSchema.describe("Element to wait for"),
|
|
176
|
+
timeout: z.number().int().positive().optional().describe("Maximum time to wait for element in milliseconds (default: 30000)"),
|
|
177
|
+
state: z.enum(["visible", "attached", "enabled"]).optional().describe("Element state to wait for (default: visible)"),
|
|
178
|
+
onAppear: branchSchema.describe("Actions to execute when element appears within timeout"),
|
|
179
|
+
onTimeout: branchSchema.optional().describe("Actions to execute if timeout occurs (silent continue if omitted)"),
|
|
180
|
+
pollInterval: z.number().int().positive().optional().describe("How often to check for element in milliseconds (default: 100)")
|
|
181
|
+
}).describe("Wait for an element and branch based on whether it appears or times out");
|
|
182
|
+
var ActionSchema = z.union([BaseActionSchema, conditionalActionSchema, waitForBranchActionSchema]);
|
|
183
|
+
var defaultsSchema = z.object({
|
|
184
|
+
timeout: z.number().int().positive().optional().describe("Default timeout in milliseconds for all actions"),
|
|
185
|
+
screenshots: z.enum(["on-failure", "always", "never"]).optional().describe("When to capture screenshots during test execution")
|
|
186
|
+
}).describe("Default settings that apply to all tests unless overridden");
|
|
187
|
+
var webConfigSchema = z.object({
|
|
188
|
+
baseUrl: nonEmptyString.url().optional().describe("Base URL for the web application"),
|
|
189
|
+
browser: z.string().trim().optional().describe("Browser to use for testing"),
|
|
190
|
+
headless: z.boolean().optional().describe("Run browser in headless mode"),
|
|
191
|
+
timeout: z.number().int().positive().optional().describe("Timeout in milliseconds for web actions")
|
|
192
|
+
}).describe("Web platform configuration");
|
|
193
|
+
var androidConfigSchema = z.object({
|
|
194
|
+
appId: z.string().trim().optional().describe("Android application ID"),
|
|
195
|
+
device: z.string().trim().optional().describe("Device name or ID to run tests on")
|
|
196
|
+
}).describe("Android platform configuration");
|
|
197
|
+
var iosConfigSchema = z.object({
|
|
198
|
+
bundleId: z.string().trim().optional().describe("iOS bundle identifier"),
|
|
199
|
+
simulator: z.string().trim().optional().describe("Simulator name to run tests on")
|
|
200
|
+
}).describe("iOS platform configuration");
|
|
201
|
+
var emailConfigSchema = z.object({
|
|
202
|
+
provider: z.literal("inbucket").describe("Email testing provider"),
|
|
203
|
+
endpoint: nonEmptyString.url().optional().describe("Email service endpoint URL")
|
|
204
|
+
}).describe("Email testing configuration");
|
|
205
|
+
var appwriteConfigSchema = z.object({
|
|
206
|
+
endpoint: nonEmptyString.url().describe("Appwrite API endpoint"),
|
|
207
|
+
projectId: nonEmptyString.describe("Appwrite project ID"),
|
|
208
|
+
apiKey: nonEmptyString.describe("Appwrite API key with appropriate permissions"),
|
|
209
|
+
cleanup: z.boolean().optional().describe("Enable automatic cleanup of created resources"),
|
|
210
|
+
cleanupOnFailure: z.boolean().optional().describe("Clean up resources even when test fails")
|
|
211
|
+
}).describe("Appwrite backend configuration");
|
|
212
|
+
var healingSchema = z.object({
|
|
213
|
+
enabled: z.boolean().optional().describe("Enable self-healing capabilities"),
|
|
214
|
+
strategies: z.array(z.string().trim()).optional().describe("Healing strategies to use")
|
|
215
|
+
}).describe("Self-healing test configuration");
|
|
216
|
+
var webServerSchema = z.object({
|
|
217
|
+
command: nonEmptyString.optional().describe("Command to start the web server"),
|
|
218
|
+
auto: z.boolean().optional().describe("Automatically detect and run the dev server from package.json"),
|
|
219
|
+
static: z.string().optional().describe("Serve a static directory instead of running a command"),
|
|
220
|
+
url: nonEmptyString.url().describe("URL to wait for before starting tests"),
|
|
221
|
+
port: z.number().int().positive().optional().describe("Port number for the web server"),
|
|
222
|
+
reuseExistingServer: z.boolean().default(true).describe("Use existing server if already running at the specified URL"),
|
|
223
|
+
timeout: z.number().int().positive().default(3e4).describe("Timeout in milliseconds to wait for server to become available"),
|
|
224
|
+
cwd: z.string().optional().describe("Working directory for the server command")
|
|
225
|
+
}).describe("Configuration for starting a web server before running tests").refine((config) => config.command || config.auto || config.static, {
|
|
226
|
+
message: "WebServerConfig requires command, auto: true, or static directory"
|
|
227
|
+
});
|
|
228
|
+
var aiSourceSchema = z.object({
|
|
229
|
+
pagesDir: z.string().optional().describe("Directory containing page components"),
|
|
230
|
+
componentsDir: z.string().optional().describe("Directory containing reusable components"),
|
|
231
|
+
extensions: z.array(z.string()).default([".vue", ".astro", ".tsx", ".jsx", ".svelte"]).describe("File extensions to include in source code analysis")
|
|
232
|
+
}).optional().describe("Source code directories for AI to analyze when generating tests");
|
|
233
|
+
var aiConfigSchema = z.object({
|
|
234
|
+
provider: z.enum(["anthropic", "openai", "ollama"]).describe("AI provider to use for test generation"),
|
|
235
|
+
model: nonEmptyString.describe("Model name to use"),
|
|
236
|
+
apiKey: z.string().trim().optional().describe("API key for the AI provider"),
|
|
237
|
+
baseUrl: z.string().trim().url().optional().describe("Base URL for the AI API (required for Ollama)"),
|
|
238
|
+
temperature: z.number().min(0).max(2).default(0.2).describe("Temperature for AI generation (0 = deterministic, 2 = very creative)"),
|
|
239
|
+
maxTokens: z.number().int().positive().default(4096).describe("Maximum tokens for AI responses"),
|
|
240
|
+
source: aiSourceSchema
|
|
241
|
+
}).describe("AI configuration for test generation and healing");
|
|
242
|
+
var cleanupDiscoverSchema = z.object({
|
|
243
|
+
enabled: z.boolean().default(true).describe("Enable auto-discovery of cleanup handlers in specified paths"),
|
|
244
|
+
paths: z.array(z.string()).default(["./tests/cleanup"]).describe("Directories to search for cleanup handler files"),
|
|
245
|
+
pattern: z.string().default("**/*.ts").describe("Glob pattern to match handler files")
|
|
246
|
+
}).optional().describe("Auto-discovery configuration for cleanup handlers");
|
|
247
|
+
var cleanupConfigSchema = z.object({
|
|
248
|
+
provider: z.string().optional().describe("Primary cleanup provider to use"),
|
|
249
|
+
parallel: z.boolean().default(false).describe("Execute cleanup operations in parallel"),
|
|
250
|
+
retries: z.number().min(1).max(10).default(3).describe("Number of retry attempts for failed cleanup operations"),
|
|
251
|
+
types: z.record(z.string(), z.string()).optional().describe("Map resource types to cleanup handler methods"),
|
|
252
|
+
handlers: z.array(z.string()).optional().describe("Explicit paths to custom cleanup handler files"),
|
|
253
|
+
discover: cleanupDiscoverSchema
|
|
254
|
+
}).passthrough().describe("Comprehensive resource cleanup configuration");
|
|
255
|
+
var platformsSchema = z.object({
|
|
256
|
+
web: webConfigSchema.optional(),
|
|
257
|
+
android: androidConfigSchema.optional(),
|
|
258
|
+
ios: iosConfigSchema.optional()
|
|
259
|
+
}).describe("Platform-specific configurations");
|
|
260
|
+
var previewConfigSchema = z.object({
|
|
261
|
+
build: z.object({
|
|
262
|
+
command: z.string().optional().describe("Command to build the project")
|
|
263
|
+
}).optional().describe("Build configuration"),
|
|
264
|
+
preview: z.object({
|
|
265
|
+
command: z.string().optional().describe("Command to start the preview server after build")
|
|
266
|
+
}).optional().describe("Preview server configuration"),
|
|
267
|
+
url: z.string().url().optional().describe("URL to wait for before starting tests"),
|
|
268
|
+
timeout: z.number().int().positive().optional().describe("Timeout in milliseconds to wait for preview server")
|
|
269
|
+
}).describe("Configuration for the --preview flag (build and serve production build)");
|
|
270
|
+
var TestConfigSchema = z.object({
|
|
271
|
+
defaults: defaultsSchema.optional(),
|
|
272
|
+
web: webConfigSchema.optional(),
|
|
273
|
+
android: androidConfigSchema.optional(),
|
|
274
|
+
ios: iosConfigSchema.optional(),
|
|
275
|
+
email: emailConfigSchema.optional(),
|
|
276
|
+
appwrite: appwriteConfigSchema.optional()
|
|
277
|
+
}).describe("Test-specific configuration that overrides global settings");
|
|
278
|
+
var TestDefinitionSchema = z.object({
|
|
279
|
+
name: nonEmptyString.describe("The name of the test"),
|
|
280
|
+
platform: z.enum(["web", "android", "ios"]).describe("The platform to run the test on"),
|
|
281
|
+
variables: z.record(z.string(), z.string()).optional().describe("Variables that can be referenced in test steps using ${VARIABLE_NAME} syntax"),
|
|
282
|
+
config: TestConfigSchema.optional(),
|
|
283
|
+
steps: z.array(ActionSchema).min(1).describe("The sequence of actions to execute in this test")
|
|
284
|
+
}).describe("Schema for IntelliTester test definition files");
|
|
285
|
+
var IntellitesterConfigSchema = z.object({
|
|
286
|
+
defaults: defaultsSchema.optional(),
|
|
287
|
+
ai: aiConfigSchema.optional(),
|
|
288
|
+
platforms: platformsSchema.optional(),
|
|
289
|
+
healing: healingSchema.optional(),
|
|
290
|
+
email: emailConfigSchema.optional(),
|
|
291
|
+
appwrite: appwriteConfigSchema.optional(),
|
|
292
|
+
cleanup: cleanupConfigSchema.optional(),
|
|
293
|
+
webServer: webServerSchema.optional(),
|
|
294
|
+
preview: previewConfigSchema.optional(),
|
|
295
|
+
secrets: z.record(z.string(), z.string().trim()).optional().describe("Secret values that can be referenced in tests")
|
|
296
|
+
}).describe("Global configuration file for IntelliTester");
|
|
297
|
+
var nonEmptyString2 = z.string().trim().min(1, "Value cannot be empty");
|
|
298
|
+
var testReferenceSchema = z.object({
|
|
299
|
+
file: nonEmptyString2.describe("Path to the test file relative to the workflow file"),
|
|
300
|
+
id: nonEmptyString2.optional().describe("Optional ID for referencing this test in variables or dependencies"),
|
|
301
|
+
variables: z.record(z.string(), z.string()).optional().describe("Variables to inject or override for this specific test")
|
|
302
|
+
}).describe("Reference to a test file");
|
|
303
|
+
var workflowWebConfigSchema = z.object({
|
|
304
|
+
baseUrl: nonEmptyString2.url().optional().describe("Base URL for all tests in this workflow"),
|
|
305
|
+
browser: z.enum(["chromium", "firefox", "webkit"]).optional().describe("Browser to use for all web tests"),
|
|
306
|
+
headless: z.boolean().optional().describe("Run browser in headless mode")
|
|
307
|
+
}).describe("Web platform configuration for the workflow");
|
|
308
|
+
var workflowAppwriteConfigSchema = z.object({
|
|
309
|
+
endpoint: nonEmptyString2.url().describe("Appwrite API endpoint"),
|
|
310
|
+
projectId: nonEmptyString2.describe("Appwrite project ID"),
|
|
311
|
+
apiKey: nonEmptyString2.describe("Appwrite API key"),
|
|
312
|
+
cleanup: z.boolean().default(true).describe("Enable automatic cleanup of created resources"),
|
|
313
|
+
cleanupOnFailure: z.boolean().default(true).describe("Clean up resources even when tests fail")
|
|
314
|
+
}).describe("Appwrite backend configuration for the workflow");
|
|
315
|
+
var workflowCleanupDiscoverSchema = z.object({
|
|
316
|
+
enabled: z.boolean().default(true).describe("Enable auto-discovery of cleanup handlers"),
|
|
317
|
+
paths: z.array(z.string()).default(["./tests/cleanup"]).describe("Directories to search for cleanup handlers"),
|
|
318
|
+
pattern: z.string().default("**/*.ts").describe("Glob pattern for handler files")
|
|
319
|
+
}).optional().describe("Auto-discovery configuration for cleanup handlers");
|
|
320
|
+
var workflowCleanupConfigSchema = z.object({
|
|
321
|
+
provider: z.string().optional().describe("Cleanup provider to use"),
|
|
322
|
+
parallel: z.boolean().default(false).describe("Run cleanup tasks in parallel"),
|
|
323
|
+
retries: z.number().min(1).max(10).default(3).describe("Number of retry attempts for failed cleanup operations"),
|
|
324
|
+
types: z.record(z.string(), z.string()).optional().describe("Map resource types to cleanup handler methods"),
|
|
325
|
+
handlers: z.array(z.string()).optional().describe("Explicit paths to custom cleanup handler files"),
|
|
326
|
+
discover: workflowCleanupDiscoverSchema
|
|
327
|
+
}).passthrough().describe("Resource cleanup configuration");
|
|
328
|
+
var workflowWebServerSchema = z.object({
|
|
329
|
+
command: nonEmptyString2.optional().describe("Command to start the web server"),
|
|
330
|
+
auto: z.boolean().optional().describe("Auto-detect server start command from package.json"),
|
|
331
|
+
url: nonEmptyString2.url().describe("URL to wait for before starting tests"),
|
|
332
|
+
reuseExistingServer: z.boolean().default(true).describe("Use existing server if already running at the URL"),
|
|
333
|
+
timeout: z.number().int().positive().default(3e4).describe("Timeout in milliseconds to wait for server to start")
|
|
334
|
+
}).describe("Configuration for starting a web server before tests");
|
|
335
|
+
var workflowConfigSchema = z.object({
|
|
336
|
+
web: workflowWebConfigSchema.optional(),
|
|
337
|
+
appwrite: workflowAppwriteConfigSchema.optional(),
|
|
338
|
+
cleanup: workflowCleanupConfigSchema.optional(),
|
|
339
|
+
webServer: workflowWebServerSchema.optional()
|
|
340
|
+
}).describe("Workflow-level configuration that applies to all tests");
|
|
341
|
+
var WorkflowDefinitionSchema = z.object({
|
|
342
|
+
name: nonEmptyString2.describe("The name of the workflow"),
|
|
343
|
+
platform: z.enum(["web", "android", "ios"]).default("web").describe("The platform to run the workflow on"),
|
|
344
|
+
variables: z.record(z.string(), z.string()).optional().describe("Workflow-level variables available to all tests"),
|
|
345
|
+
config: workflowConfigSchema.optional(),
|
|
346
|
+
continueOnFailure: z.boolean().default(false).describe("Continue running subsequent tests even if a test fails"),
|
|
347
|
+
tests: z.array(testReferenceSchema).min(1, "Workflow must contain at least one test").describe("List of test files to execute in this workflow")
|
|
348
|
+
}).describe("Schema for IntelliTester workflow files that orchestrate multiple tests");
|
|
349
|
+
var nonEmptyString3 = z.string().trim().min(1, "Value cannot be empty");
|
|
350
|
+
var workflowReferenceSchema = z.object({
|
|
351
|
+
file: nonEmptyString3.describe("Path to the workflow file"),
|
|
352
|
+
id: nonEmptyString3.optional().describe("Optional ID for referencing this workflow in dependencies"),
|
|
353
|
+
depends_on: z.array(nonEmptyString3).optional().describe("IDs of workflows that must complete before this one"),
|
|
354
|
+
on_failure: z.enum(["skip", "fail", "ignore"]).optional().describe("How to handle failure of this workflow"),
|
|
355
|
+
variables: z.record(z.string(), z.string()).optional().describe("Variables to inject or override for this workflow")
|
|
356
|
+
}).describe("Reference to a workflow file");
|
|
357
|
+
var pipelineWebConfigSchema = z.object({
|
|
358
|
+
baseUrl: nonEmptyString3.url().optional().describe("Base URL for all workflows in this pipeline"),
|
|
359
|
+
browser: z.enum(["chromium", "firefox", "webkit"]).optional().describe("Browser to use for all web tests"),
|
|
360
|
+
headless: z.boolean().optional().describe("Run browser in headless mode")
|
|
361
|
+
}).describe("Web platform configuration for the pipeline");
|
|
362
|
+
var pipelineAppwriteConfigSchema = z.object({
|
|
363
|
+
endpoint: nonEmptyString3.url().describe("Appwrite API endpoint"),
|
|
364
|
+
projectId: nonEmptyString3.describe("Appwrite project ID"),
|
|
365
|
+
apiKey: nonEmptyString3.describe("Appwrite API key"),
|
|
366
|
+
cleanup: z.boolean().default(true).describe("Enable automatic cleanup of created resources"),
|
|
367
|
+
cleanupOnFailure: z.boolean().default(true).describe("Clean up resources even when workflows fail")
|
|
368
|
+
}).describe("Appwrite backend configuration for the pipeline");
|
|
369
|
+
var pipelineCleanupDiscoverSchema = z.object({
|
|
370
|
+
enabled: z.boolean().default(true).describe("Enable auto-discovery of cleanup handlers"),
|
|
371
|
+
paths: z.array(z.string()).default(["./tests/cleanup"]).describe("Directories to search for cleanup handlers"),
|
|
372
|
+
pattern: z.string().default("**/*.ts").describe("Glob pattern for handler files")
|
|
373
|
+
}).optional().describe("Auto-discovery configuration for cleanup handlers");
|
|
374
|
+
var pipelineCleanupConfigSchema = z.object({
|
|
375
|
+
provider: z.string().optional().describe("Cleanup provider to use"),
|
|
376
|
+
parallel: z.boolean().default(false).describe("Run cleanup tasks in parallel"),
|
|
377
|
+
retries: z.number().min(1).max(10).default(3).describe("Number of retry attempts for failed cleanup operations"),
|
|
378
|
+
types: z.record(z.string(), z.string()).optional().describe("Map resource types to cleanup handler methods"),
|
|
379
|
+
handlers: z.array(z.string()).optional().describe("Explicit paths to custom cleanup handler files"),
|
|
380
|
+
discover: pipelineCleanupDiscoverSchema,
|
|
381
|
+
on_failure: z.boolean().default(true).describe("Run cleanup even if pipeline fails")
|
|
382
|
+
}).passthrough().describe("Resource cleanup configuration");
|
|
383
|
+
var pipelineWebServerSchema = z.object({
|
|
384
|
+
command: nonEmptyString3.optional().describe("Command to start the web server"),
|
|
385
|
+
auto: z.boolean().optional().describe("Auto-detect server start command from package.json"),
|
|
386
|
+
url: nonEmptyString3.url().describe("URL to wait for before starting workflows"),
|
|
387
|
+
reuseExistingServer: z.boolean().default(true).describe("Use existing server if already running at the URL"),
|
|
388
|
+
timeout: z.number().int().positive().default(3e4).describe("Timeout in milliseconds to wait for server to start")
|
|
389
|
+
}).describe("Configuration for starting a web server before workflows");
|
|
390
|
+
var pipelineConfigSchema = z.object({
|
|
391
|
+
web: pipelineWebConfigSchema.optional(),
|
|
392
|
+
appwrite: pipelineAppwriteConfigSchema.optional(),
|
|
393
|
+
cleanup: pipelineCleanupConfigSchema.optional(),
|
|
394
|
+
webServer: pipelineWebServerSchema.optional()
|
|
395
|
+
}).describe("Pipeline-level configuration that applies to all workflows");
|
|
396
|
+
var PipelineDefinitionSchema = z.object({
|
|
397
|
+
name: nonEmptyString3.describe("The name of the pipeline"),
|
|
398
|
+
platform: z.enum(["web", "android", "ios"]).default("web").describe("The platform to run the pipeline on"),
|
|
399
|
+
config: pipelineConfigSchema.optional(),
|
|
400
|
+
on_failure: z.enum(["skip", "fail", "ignore"]).default("skip").describe("Default failure handling for workflows"),
|
|
401
|
+
cleanup_on_failure: z.boolean().default(true).describe("Run cleanup even when pipeline fails"),
|
|
402
|
+
workflows: z.array(workflowReferenceSchema).min(1, "Pipeline must contain at least one workflow").describe("List of workflow files to execute in this pipeline")
|
|
403
|
+
}).describe("Schema for IntelliTester pipeline files that orchestrate multiple workflows");
|
|
404
|
+
|
|
405
|
+
// src/core/loader.ts
|
|
406
|
+
var formatIssues = (issues) => issues.map((issue) => {
|
|
407
|
+
const path = issue.path.join(".") || "<root>";
|
|
408
|
+
return `${path}: ${issue.message}`;
|
|
409
|
+
}).join("; ");
|
|
410
|
+
var interpolateEnvVars = (obj) => {
|
|
411
|
+
if (typeof obj === "string") {
|
|
412
|
+
return obj.replace(/\$\{([^}]+)\}/g, (_, varName) => {
|
|
413
|
+
const value = process.env[varName];
|
|
414
|
+
if (value === void 0) {
|
|
415
|
+
throw new Error(`Environment variable ${varName} is not defined`);
|
|
416
|
+
}
|
|
417
|
+
return value;
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
if (Array.isArray(obj)) {
|
|
421
|
+
return obj.map(interpolateEnvVars);
|
|
422
|
+
}
|
|
423
|
+
if (obj !== null && typeof obj === "object") {
|
|
424
|
+
const result = {};
|
|
425
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
426
|
+
result[key] = interpolateEnvVars(value);
|
|
427
|
+
}
|
|
428
|
+
return result;
|
|
429
|
+
}
|
|
430
|
+
return obj;
|
|
431
|
+
};
|
|
432
|
+
var parseWithSchema = (content, schema, subject) => {
|
|
433
|
+
let parsed;
|
|
434
|
+
try {
|
|
435
|
+
parsed = parse(content);
|
|
436
|
+
} catch (error) {
|
|
437
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
438
|
+
throw new Error(`Invalid YAML for ${subject}: ${message}`);
|
|
439
|
+
}
|
|
440
|
+
const interpolated = interpolateEnvVars(parsed);
|
|
441
|
+
const result = schema.safeParse(interpolated);
|
|
442
|
+
if (!result.success) {
|
|
443
|
+
throw new Error(`Invalid ${subject}: ${formatIssues(result.error.issues)}`);
|
|
444
|
+
}
|
|
445
|
+
return result.data;
|
|
446
|
+
};
|
|
447
|
+
var parseTestDefinition = (content) => parseWithSchema(content, TestDefinitionSchema, "test definition");
|
|
448
|
+
var loadTestDefinition = async (filePath) => {
|
|
449
|
+
const fileContent = await fs.readFile(filePath, "utf8");
|
|
450
|
+
return parseTestDefinition(fileContent);
|
|
451
|
+
};
|
|
452
|
+
var parseIntellitesterConfig = (content) => parseWithSchema(content, IntellitesterConfigSchema, "config");
|
|
453
|
+
var loadIntellitesterConfig = async (filePath) => {
|
|
454
|
+
const fileContent = await fs.readFile(filePath, "utf8");
|
|
455
|
+
return parseIntellitesterConfig(fileContent);
|
|
456
|
+
};
|
|
457
|
+
var parseWorkflowDefinition = (content) => parseWithSchema(content, WorkflowDefinitionSchema, "workflow definition");
|
|
458
|
+
var loadWorkflowDefinition = async (filePath) => {
|
|
459
|
+
const fileContent = await fs.readFile(filePath, "utf8");
|
|
460
|
+
return parseWorkflowDefinition(fileContent);
|
|
461
|
+
};
|
|
462
|
+
var isWorkflowFile = (filePath) => {
|
|
463
|
+
return filePath.endsWith(".workflow.yaml") || filePath.endsWith(".workflow.yml");
|
|
464
|
+
};
|
|
465
|
+
var isPipelineFile = (filePath) => {
|
|
466
|
+
return filePath.endsWith(".pipeline.yaml") || filePath.endsWith(".pipeline.yml");
|
|
467
|
+
};
|
|
468
|
+
var parsePipelineDefinition = (content) => parseWithSchema(content, PipelineDefinitionSchema, "pipeline definition");
|
|
469
|
+
var loadPipelineDefinition = async (filePath) => {
|
|
470
|
+
const fileContent = await fs.readFile(filePath, "utf8");
|
|
471
|
+
return parsePipelineDefinition(fileContent);
|
|
472
|
+
};
|
|
473
|
+
var collectMissingEnvVars = (obj) => {
|
|
474
|
+
const missing = [];
|
|
475
|
+
const collect = (value) => {
|
|
476
|
+
if (typeof value === "string") {
|
|
477
|
+
const matches = value.matchAll(/\$\{([^}]+)\}/g);
|
|
478
|
+
for (const match of matches) {
|
|
479
|
+
const varName = match[1];
|
|
480
|
+
if (process.env[varName] === void 0 && !missing.includes(varName)) {
|
|
481
|
+
missing.push(varName);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
} else if (Array.isArray(value)) {
|
|
485
|
+
value.forEach(collect);
|
|
486
|
+
} else if (value !== null && typeof value === "object") {
|
|
487
|
+
Object.values(value).forEach(collect);
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
collect(obj);
|
|
491
|
+
return missing;
|
|
492
|
+
};
|
|
493
|
+
var isWorkflowContent = (content) => {
|
|
494
|
+
try {
|
|
495
|
+
const parsed = parse(content);
|
|
496
|
+
return parsed && Array.isArray(parsed.tests) && !parsed.steps && !parsed.workflows;
|
|
497
|
+
} catch {
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
var isPipelineContent = (content) => {
|
|
502
|
+
try {
|
|
503
|
+
const parsed = parse(content);
|
|
504
|
+
return parsed && Array.isArray(parsed.workflows) && !parsed.steps;
|
|
505
|
+
} catch {
|
|
506
|
+
return false;
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
export { ActionSchema, IntellitesterConfigSchema, LocatorSchema, TestConfigSchema, TestDefinitionSchema, cleanupConfigSchema, cleanupDiscoverSchema, collectMissingEnvVars, isPipelineContent, isPipelineFile, isWorkflowContent, isWorkflowFile, loadIntellitesterConfig, loadPipelineDefinition, loadTestDefinition, loadWorkflowDefinition, parseIntellitesterConfig, parsePipelineDefinition, parseTestDefinition, parseWorkflowDefinition, previewConfigSchema };
|
|
511
|
+
//# sourceMappingURL=chunk-BDSLT5FJ.js.map
|
|
512
|
+
//# sourceMappingURL=chunk-BDSLT5FJ.js.map
|