testchimp-runner-core 0.0.74 → 0.0.76

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.
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+ /**
3
+ * Utilities for extracting and transforming initialization code from test scripts
4
+ * Handles AST parsing and transformation of variable declarations
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ var __importDefault = (this && this.__importDefault) || function (mod) {
40
+ return (mod && mod.__esModule) ? mod : { "default": mod };
41
+ };
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.InitializationCodeUtils = void 0;
44
+ const parser_1 = require("@babel/parser");
45
+ const traverse_1 = __importDefault(require("@babel/traverse"));
46
+ const t = __importStar(require("@babel/types"));
47
+ const generator_1 = __importDefault(require("@babel/generator"));
48
+ class InitializationCodeUtils {
49
+ /**
50
+ * Extract initialization code from test script using AST parsing
51
+ * This includes variable declarations like: const signInPage = new SignInPage(page);
52
+ * Returns the code that should be executed before steps
53
+ */
54
+ static extractInitializationCode(script, logger) {
55
+ try {
56
+ // Parse the script with Babel
57
+ const ast = (0, parser_1.parse)(script, {
58
+ sourceType: 'module',
59
+ plugins: ['typescript', 'classProperties', 'decorators-legacy'],
60
+ allowImportExportEverywhere: true
61
+ });
62
+ let testBody = null;
63
+ let testBodyStart = 0;
64
+ let testBodyEnd = 0;
65
+ // Find the test function call
66
+ (0, traverse_1.default)(ast, {
67
+ CallExpression(path) {
68
+ if (testBody)
69
+ return; // Already found
70
+ const callee = path.node.callee;
71
+ if (!t.isIdentifier(callee) || callee.name !== 'test') {
72
+ return;
73
+ }
74
+ if (path.node.arguments.length < 2) {
75
+ return;
76
+ }
77
+ const testCallback = path.node.arguments[1];
78
+ if (!(t.isFunctionExpression(testCallback) ||
79
+ t.isArrowFunctionExpression(testCallback))) {
80
+ return;
81
+ }
82
+ if (!t.isBlockStatement(testCallback.body)) {
83
+ return;
84
+ }
85
+ testBody = testCallback.body;
86
+ testBodyStart = testBody.start ?? 0;
87
+ testBodyEnd = testBody.end ?? script.length;
88
+ }
89
+ });
90
+ if (!testBody) {
91
+ return null;
92
+ }
93
+ // Extract initialization statements (variable declarations before first step)
94
+ const initStatements = [];
95
+ let foundFirstStep = false;
96
+ // TypeScript type narrowing issue - use explicit type assertion
97
+ const bodyStatements = testBody.body;
98
+ for (const statement of bodyStatements) {
99
+ // Stop at step comments or await expressions that are not part of variable declarations
100
+ if (t.isExpressionStatement(statement)) {
101
+ const expr = statement.expression;
102
+ // Check if this is an await expression that's not part of initialization
103
+ if (t.isAwaitExpression(expr)) {
104
+ // This is likely a step, not initialization
105
+ foundFirstStep = true;
106
+ break;
107
+ }
108
+ }
109
+ // Check for step comments - any comment that is NOT a @Screen annotation
110
+ // @Screen annotations are for screen state tracking, not step descriptions
111
+ // All other comments are treated as intent/step comments
112
+ if (statement.leadingComments) {
113
+ for (const comment of statement.leadingComments) {
114
+ const commentText = comment.value.trim();
115
+ // If comment contains @Screen, it's a screen state annotation, not a step
116
+ // All other comments indicate a step
117
+ if (!commentText.includes('@Screen')) {
118
+ foundFirstStep = true;
119
+ break;
120
+ }
121
+ }
122
+ if (foundFirstStep)
123
+ break;
124
+ }
125
+ // Collect variable declarations (initialization code)
126
+ if (t.isVariableDeclaration(statement)) {
127
+ initStatements.push(statement);
128
+ }
129
+ else if (!t.isEmptyStatement(statement) && !t.isExpressionStatement(statement)) {
130
+ // Other statements that aren't steps (e.g., other declarations)
131
+ initStatements.push(statement);
132
+ }
133
+ }
134
+ if (initStatements.length === 0) {
135
+ return null;
136
+ }
137
+ // Extract the code for these statements from the original script
138
+ const firstStatement = initStatements[0];
139
+ const lastStatement = initStatements[initStatements.length - 1];
140
+ const codeStart = firstStatement.start ?? testBodyStart;
141
+ const codeEnd = lastStatement.end ?? testBodyEnd;
142
+ // Extract the code snippet
143
+ let initCode = script.slice(codeStart, codeEnd).trim();
144
+ // Remove trailing blank lines using string methods instead of regex
145
+ while (initCode.endsWith('\n') || initCode.endsWith('\r')) {
146
+ initCode = initCode.slice(0, -1).trimEnd();
147
+ }
148
+ return initCode || null;
149
+ }
150
+ catch (error) {
151
+ if (logger) {
152
+ logger(`Error parsing script with AST: ${error.message}`, 'warn');
153
+ }
154
+ return null;
155
+ }
156
+ }
157
+ /**
158
+ * Extract variable names from initialization code using AST
159
+ */
160
+ static extractVariableNames(initializationCode, logger) {
161
+ const variableNames = [];
162
+ try {
163
+ const ast = (0, parser_1.parse)(initializationCode, {
164
+ sourceType: 'module',
165
+ plugins: ['typescript', 'classProperties'],
166
+ allowImportExportEverywhere: true
167
+ });
168
+ (0, traverse_1.default)(ast, {
169
+ VariableDeclarator(path) {
170
+ if (t.isIdentifier(path.node.id)) {
171
+ variableNames.push(path.node.id.name);
172
+ }
173
+ }
174
+ });
175
+ }
176
+ catch (parseError) {
177
+ if (logger) {
178
+ logger(`Warning: Failed to parse initialization code for variable extraction: ${parseError.message}`, 'warn');
179
+ }
180
+ // Fallback: try to extract from code string (less reliable)
181
+ // Handle const, let, var declarations (including destructuring)
182
+ const lines = initializationCode.split('\n');
183
+ for (const line of lines) {
184
+ // Match: const/let/var identifier = ...
185
+ const simpleMatch = line.match(/(?:const|let|var)\s+(\w+)\s*=/);
186
+ if (simpleMatch) {
187
+ variableNames.push(simpleMatch[1]);
188
+ }
189
+ else {
190
+ // Match destructuring: const { a, b } = ... or const [a, b] = ...
191
+ const destructureMatch = line.match(/(?:const|let|var)\s*[\[\{]([^}\]]+)[\]\}]\s*=/);
192
+ if (destructureMatch) {
193
+ // Extract variable names from destructuring pattern
194
+ const names = destructureMatch[1].split(',').map(n => {
195
+ const trimmed = n.trim();
196
+ // Handle aliases: { a: b } -> extract 'b'
197
+ const aliasMatch = trimmed.match(/:\s*(\w+)/);
198
+ return aliasMatch ? aliasMatch[1] : trimmed.split(':')[0].trim();
199
+ }).filter(n => n.length > 0);
200
+ variableNames.push(...names);
201
+ }
202
+ }
203
+ }
204
+ }
205
+ return variableNames;
206
+ }
207
+ /**
208
+ * Transform initialization code to assign variables directly to context
209
+ * Converts: const signInPage = new SignInPage(page);
210
+ * To: signInPage = new SignInPage(page);
211
+ * This ensures variables are accessible in the vm context
212
+ */
213
+ static transformInitializationCode(initializationCode, logger) {
214
+ const variableNames = [];
215
+ try {
216
+ // Parse as a program (not module) since this is just a code snippet
217
+ const ast = (0, parser_1.parse)(initializationCode, {
218
+ sourceType: 'script',
219
+ plugins: ['typescript', 'classProperties'],
220
+ allowImportExportEverywhere: true
221
+ });
222
+ // Extract variable names first
223
+ (0, traverse_1.default)(ast, {
224
+ VariableDeclarator(path) {
225
+ if (t.isIdentifier(path.node.id)) {
226
+ variableNames.push(path.node.id.name);
227
+ }
228
+ }
229
+ });
230
+ // Transform const/let declarations to direct assignments on the context
231
+ // In vm context, assignments without declaration create properties on the context object
232
+ (0, traverse_1.default)(ast, {
233
+ VariableDeclaration(path) {
234
+ const declarations = path.node.declarations;
235
+ const newStatements = [];
236
+ for (const decl of declarations) {
237
+ if (t.isIdentifier(decl.id)) {
238
+ const varName = decl.id.name;
239
+ // Create: varName = <init expression> (no const/let/var)
240
+ // In vm context, this creates a property on the context object
241
+ const assignment = t.expressionStatement(t.assignmentExpression('=', t.identifier(varName), decl.init || t.identifier('undefined')));
242
+ newStatements.push(assignment);
243
+ }
244
+ }
245
+ // Replace the variable declaration with assignment statements
246
+ if (newStatements.length > 0) {
247
+ path.replaceWithMultiple(newStatements);
248
+ }
249
+ }
250
+ });
251
+ // Generate code from transformed AST
252
+ const output = (0, generator_1.default)(ast, {}, initializationCode);
253
+ const transformedCode = output.code;
254
+ if (logger) {
255
+ logger(`Transformed initialization code: ${transformedCode.substring(0, 200)}...`);
256
+ logger(`Full transformed initialization code:\n${transformedCode}`);
257
+ }
258
+ return { transformedCode, variableNames };
259
+ }
260
+ catch (transformError) {
261
+ if (logger) {
262
+ logger(`Warning: Failed to transform initialization code with AST: ${transformError.message}. Using original code.`, 'warn');
263
+ logger(`Transform error stack: ${transformError.stack}`, 'warn');
264
+ }
265
+ // Fallback: extract variable names from original code
266
+ const fallbackNames = this.extractVariableNames(initializationCode, logger);
267
+ return { transformedCode: initializationCode, variableNames: fallbackNames };
268
+ }
269
+ }
270
+ }
271
+ exports.InitializationCodeUtils = InitializationCodeUtils;
272
+ //# sourceMappingURL=initialization-code-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"initialization-code-utils.js","sourceRoot":"","sources":["../../src/utils/initialization-code-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Utilities for generating scripts from steps
3
+ */
4
+ import { ScriptStep } from '../types';
5
+ export declare class ScriptGeneratorUtils {
6
+ /**
7
+ * Generate updated script from steps
8
+ */
9
+ static generateUpdatedScript(steps: (ScriptStep & {
10
+ success?: boolean;
11
+ error?: string;
12
+ })[], repairAdvice?: string, originalScript?: string): string;
13
+ }
14
+ //# sourceMappingURL=script-generator-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script-generator-utils.d.ts","sourceRoot":"","sources":["../../src/utils/script-generator-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAItC,qBAAa,oBAAoB;IAC/B;;OAEG;IACH,MAAM,CAAC,qBAAqB,CAC1B,KAAK,EAAE,CAAC,UAAU,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,EAC7D,YAAY,CAAC,EAAE,MAAM,EACrB,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM;CA+CV"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ /**
3
+ * Utilities for generating scripts from steps
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ScriptGeneratorUtils = void 0;
7
+ const ai_command_utils_1 = require("./ai-command-utils");
8
+ const script_utils_1 = require("../script-utils");
9
+ class ScriptGeneratorUtils {
10
+ /**
11
+ * Generate updated script from steps
12
+ */
13
+ static generateUpdatedScript(steps, repairAdvice, originalScript) {
14
+ // Extract test name and hashtags from original script if provided
15
+ let testName = 'repairedTest';
16
+ let hashtags = [];
17
+ if (originalScript) {
18
+ const testNameMatch = originalScript.match(/test\(['"]([^'"]+)['"]/);
19
+ if (testNameMatch) {
20
+ testName = testNameMatch[1];
21
+ }
22
+ // Extract hashtags from TestChimp comment
23
+ const hashtagMatch = originalScript.match(/#\w+(?:\s+#\w+)*/);
24
+ if (hashtagMatch) {
25
+ hashtags = hashtagMatch[0].split(/\s+/).filter(tag => tag.startsWith('#'));
26
+ }
27
+ }
28
+ const scriptLines = [
29
+ "import { test, expect } from '@playwright/test';"
30
+ ];
31
+ const needsAiImport = steps.some(step => (0, ai_command_utils_1.containsAiCommand)(step.code));
32
+ if (needsAiImport) {
33
+ scriptLines.push("import { ai } from 'ai-wright';");
34
+ }
35
+ scriptLines.push('');
36
+ scriptLines.push(`test('${testName}', async ({ page, browser, context }) => {`);
37
+ steps.forEach((step, index) => {
38
+ // Only add step if it has code to execute
39
+ if (step.code && step.code.trim().length > 0) {
40
+ scriptLines.push(` // ${step.description}`);
41
+ const codeLines = step.code.split('\n');
42
+ codeLines.forEach(line => {
43
+ scriptLines.push(` ${line}`);
44
+ });
45
+ }
46
+ });
47
+ scriptLines.push('});');
48
+ const script = scriptLines.join('\n');
49
+ // Add TestChimp comment with hashtags and repair advice
50
+ return (0, script_utils_1.addTestChimpComment)(script, repairAdvice, hashtags);
51
+ }
52
+ }
53
+ exports.ScriptGeneratorUtils = ScriptGeneratorUtils;
54
+ //# sourceMappingURL=script-generator-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script-generator-utils.js","sourceRoot":"","sources":["../../src/utils/script-generator-utils.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAGH,yDAAuD;AACvD,kDAAsD;AAEtD,MAAa,oBAAoB;IAC/B;;OAEG;IACH,MAAM,CAAC,qBAAqB,CAC1B,KAA6D,EAC7D,YAAqB,EACrB,cAAuB;QAEvB,kEAAkE;QAClE,IAAI,QAAQ,GAAG,cAAc,CAAC;QAC9B,IAAI,QAAQ,GAAa,EAAE,CAAC;QAE5B,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,aAAa,GAAG,cAAc,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YACrE,IAAI,aAAa,EAAE,CAAC;gBAClB,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;YAC9B,CAAC;YAED,0CAA0C;YAC1C,MAAM,YAAY,GAAG,cAAc,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;YAC9D,IAAI,YAAY,EAAE,CAAC;gBACjB,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC;QAED,MAAM,WAAW,GAAG;YAClB,kDAAkD;SACnD,CAAC;QAEF,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAA,oCAAiB,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACvE,IAAI,aAAa,EAAE,CAAC;YAClB,WAAW,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QACtD,CAAC;QAED,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrB,WAAW,CAAC,IAAI,CAAC,SAAS,QAAQ,4CAA4C,CAAC,CAAC;QAEhF,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YAC5B,0CAA0C;YAC1C,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7C,WAAW,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACxC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;oBACvB,WAAW,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;gBAChC,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEtC,wDAAwD;QACxD,OAAO,IAAA,kCAAmB,EAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;IAC7D,CAAC;CACF;AAvDD,oDAuDC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Utilities for parsing scripts into steps
3
+ */
4
+ import { ScriptStep } from '../types';
5
+ export declare class ScriptParserUtils {
6
+ /**
7
+ * Parse script into steps using fallback method (code-based parsing)
8
+ * Used when LLM parsing fails
9
+ */
10
+ static parseScriptIntoStepsFallback(script: string): (ScriptStep & {
11
+ success?: boolean;
12
+ error?: string;
13
+ })[];
14
+ /**
15
+ * Validate step code has executable content (preserves comments)
16
+ * Uses AST parsing to determine if code contains executable statements
17
+ */
18
+ static cleanStepCode(code: string): string;
19
+ }
20
+ //# sourceMappingURL=script-parser-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script-parser-utils.d.ts","sourceRoot":"","sources":["../../src/utils/script-parser-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAItC,qBAAa,iBAAiB;IAC5B;;;OAGG;IACH,MAAM,CAAC,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,UAAU,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE;IA2E3G;;;OAGG;IACH,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CA0C3C"}
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ /**
3
+ * Utilities for parsing scripts into steps
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ScriptParserUtils = void 0;
7
+ const parser_1 = require("@babel/parser");
8
+ class ScriptParserUtils {
9
+ /**
10
+ * Parse script into steps using fallback method (code-based parsing)
11
+ * Used when LLM parsing fails
12
+ */
13
+ static parseScriptIntoStepsFallback(script) {
14
+ const lines = script.split('\n');
15
+ const steps = [];
16
+ let currentStep = null;
17
+ let currentCode = [];
18
+ for (const line of lines) {
19
+ const trimmedLine = line.trim();
20
+ // Check for any comment (except @Screen annotations which are for screen state tracking)
21
+ // Any comment that is not a @Screen annotation is treated as an intent/step comment
22
+ if (trimmedLine.startsWith('//')) {
23
+ const commentText = trimmedLine.substring(2).trim();
24
+ // Skip @Screen annotations - these are for screen state, not step descriptions
25
+ if (commentText.includes('@Screen')) {
26
+ // This is a screen state annotation, not a step - continue to current step
27
+ if (currentStep) {
28
+ currentCode.push(line);
29
+ }
30
+ continue;
31
+ }
32
+ // Any other comment is a step comment
33
+ // Save previous step if exists and has code
34
+ if (currentStep) {
35
+ const code = currentCode.join('\n').trim();
36
+ const cleanedCode = ScriptParserUtils.cleanStepCode(code);
37
+ if (cleanedCode) {
38
+ currentStep.code = cleanedCode;
39
+ steps.push(currentStep);
40
+ }
41
+ }
42
+ // Start new step - use comment text as description
43
+ // Remove status markers like [FAILED], [SKIPPED], etc.
44
+ // Use simple string methods instead of regex
45
+ let description = commentText.trim();
46
+ // Remove trailing status markers: [FAILED], [SKIPPED], etc.
47
+ if (description.endsWith(']')) {
48
+ const lastBracket = description.lastIndexOf('[');
49
+ if (lastBracket > 0 && lastBracket < description.length - 1) {
50
+ // Check if it's a status marker (simple heuristic: brackets near the end)
51
+ const beforeBracket = description.substring(0, lastBracket).trim();
52
+ const afterBracket = description.substring(lastBracket + 1, description.length - 1);
53
+ // If the bracket content looks like a status (all caps or common status words)
54
+ if (afterBracket && (afterBracket === afterBracket.toUpperCase() ||
55
+ ['FAILED', 'SKIPPED', 'PASSED', 'PENDING'].includes(afterBracket))) {
56
+ description = beforeBracket;
57
+ }
58
+ }
59
+ }
60
+ currentStep = { description, code: '' };
61
+ currentCode = [];
62
+ }
63
+ else if (trimmedLine && !trimmedLine.startsWith('import') && !trimmedLine.startsWith('test(') && !trimmedLine.startsWith('});')) {
64
+ // Add code line to current step
65
+ // Exclude import statements and test function boundaries
66
+ if (currentStep) {
67
+ currentCode.push(line);
68
+ }
69
+ }
70
+ }
71
+ // Add the last step if it has code
72
+ if (currentStep) {
73
+ const code = currentCode.join('\n').trim();
74
+ const cleanedCode = ScriptParserUtils.cleanStepCode(code);
75
+ if (cleanedCode) {
76
+ currentStep.code = cleanedCode;
77
+ steps.push(currentStep);
78
+ }
79
+ }
80
+ return steps;
81
+ }
82
+ /**
83
+ * Validate step code has executable content (preserves comments)
84
+ * Uses AST parsing to determine if code contains executable statements
85
+ */
86
+ static cleanStepCode(code) {
87
+ if (!code || code.trim().length === 0) {
88
+ return '';
89
+ }
90
+ // Use AST parsing to check if code has executable statements
91
+ try {
92
+ const ast = (0, parser_1.parse)(code, {
93
+ sourceType: 'script',
94
+ plugins: ['typescript', 'classProperties'],
95
+ allowReturnOutsideFunction: true,
96
+ allowAwaitOutsideFunction: true,
97
+ allowImportExportEverywhere: true,
98
+ errorRecovery: true
99
+ });
100
+ // Check if AST has any executable statements
101
+ // Empty program or only comments/whitespace would have no statements
102
+ if (!ast.program || !ast.program.body || ast.program.body.length === 0) {
103
+ return '';
104
+ }
105
+ // Check if any statement is executable (not just empty statements or directives)
106
+ const hasExecutableStatements = ast.program.body.some((stmt) => {
107
+ // Skip empty statements and directives
108
+ // For ExpressionStatement, only count if it has an expression
109
+ return stmt.type !== 'EmptyStatement' &&
110
+ stmt.type !== 'Directive' &&
111
+ (stmt.type !== 'ExpressionStatement' || (stmt.type === 'ExpressionStatement' && stmt.expression));
112
+ });
113
+ if (!hasExecutableStatements) {
114
+ return '';
115
+ }
116
+ return code; // Return the original code without removing comments
117
+ }
118
+ catch (parseError) {
119
+ // If parsing fails, assume code is invalid/empty
120
+ // This is safer than trying to execute potentially malformed code
121
+ return '';
122
+ }
123
+ }
124
+ }
125
+ exports.ScriptParserUtils = ScriptParserUtils;
126
+ //# sourceMappingURL=script-parser-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"script-parser-utils.js","sourceRoot":"","sources":["../../src/utils/script-parser-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Utilities for step execution tracking
3
+ */
4
+ export declare class StepExecutionUtils {
5
+ /**
6
+ * Split raw step code into syntactically complete statements.
7
+ * Uses Function compilation to detect when a statement is complete so that
8
+ * multi-line await blocks (e.g., ai.verify) are preserved.
9
+ */
10
+ static splitIntoExecutableStatements(stepCode: string): string[];
11
+ /**
12
+ * Safely serialize error information, filtering out non-serializable values
13
+ */
14
+ static safeSerializeError(error: any): string;
15
+ }
16
+ //# sourceMappingURL=step-execution-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-execution-utils.d.ts","sourceRoot":"","sources":["../../src/utils/step-execution-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,kBAAkB;IAC7B;;;;OAIG;IACH,MAAM,CAAC,6BAA6B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAgDhE;;OAEG;IACH,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM;CAkC9C"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ /**
3
+ * Utilities for step execution tracking
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.StepExecutionUtils = void 0;
7
+ class StepExecutionUtils {
8
+ /**
9
+ * Split raw step code into syntactically complete statements.
10
+ * Uses Function compilation to detect when a statement is complete so that
11
+ * multi-line await blocks (e.g., ai.verify) are preserved.
12
+ */
13
+ static splitIntoExecutableStatements(stepCode) {
14
+ const statements = [];
15
+ const lines = stepCode.split('\n');
16
+ let buffer = [];
17
+ const flushBuffer = () => {
18
+ if (buffer.length === 0) {
19
+ return;
20
+ }
21
+ const statement = buffer.join('\n').trim();
22
+ if (statement.length > 0) {
23
+ statements.push(statement);
24
+ }
25
+ buffer = [];
26
+ };
27
+ const isIncomplete = (code) => {
28
+ const trimmed = code.trim();
29
+ if (trimmed.length === 0) {
30
+ return false;
31
+ }
32
+ try {
33
+ new Function('page', 'expect', 'test', 'ai', `return async () => {\n${code}\n};`);
34
+ return false;
35
+ }
36
+ catch (error) {
37
+ if (error instanceof SyntaxError) {
38
+ return true;
39
+ }
40
+ return false;
41
+ }
42
+ };
43
+ for (const rawLine of lines) {
44
+ if (buffer.length === 0 && rawLine.trim().length === 0) {
45
+ continue;
46
+ }
47
+ buffer.push(rawLine);
48
+ const candidate = buffer.join('\n');
49
+ if (!isIncomplete(candidate)) {
50
+ flushBuffer();
51
+ }
52
+ }
53
+ flushBuffer();
54
+ return statements;
55
+ }
56
+ /**
57
+ * Safely serialize error information, filtering out non-serializable values
58
+ */
59
+ static safeSerializeError(error) {
60
+ try {
61
+ if (error instanceof Error) {
62
+ return error.message;
63
+ }
64
+ if (typeof error === 'string') {
65
+ return error;
66
+ }
67
+ if (typeof error === 'object' && error !== null) {
68
+ // Try to extract meaningful information without serializing the entire object
69
+ const safeError = {};
70
+ // Copy safe properties
71
+ if (error.message)
72
+ safeError.message = error.message;
73
+ if (error.name)
74
+ safeError.name = error.name;
75
+ if (error.code)
76
+ safeError.code = error.code;
77
+ if (error.status)
78
+ safeError.status = error.status;
79
+ // Try to get stack trace safely
80
+ if (error.stack && typeof error.stack === 'string') {
81
+ safeError.stack = error.stack;
82
+ }
83
+ return JSON.stringify(safeError);
84
+ }
85
+ return String(error);
86
+ }
87
+ catch (serializationError) {
88
+ // If even safe serialization fails, return a basic string representation
89
+ return `Error: ${String(error)}`;
90
+ }
91
+ }
92
+ }
93
+ exports.StepExecutionUtils = StepExecutionUtils;
94
+ //# sourceMappingURL=step-execution-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-execution-utils.js","sourceRoot":"","sources":["../../src/utils/step-execution-utils.ts"],"names":[],"mappings":"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"}