testchimp-runner-core 0.0.75 → 0.0.77
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/execution-service.d.ts +0 -15
- package/dist/execution-service.d.ts.map +1 -1
- package/dist/execution-service.js +558 -200
- package/dist/execution-service.js.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/import-utils.d.ts +18 -0
- package/dist/utils/import-utils.d.ts.map +1 -0
- package/dist/utils/import-utils.js +80 -0
- package/dist/utils/import-utils.js.map +1 -0
- package/dist/utils/initialization-code-utils.d.ts +27 -0
- package/dist/utils/initialization-code-utils.d.ts.map +1 -0
- package/dist/utils/initialization-code-utils.js +272 -0
- package/dist/utils/initialization-code-utils.js.map +1 -0
- package/dist/utils/script-generator-utils.d.ts +14 -0
- package/dist/utils/script-generator-utils.d.ts.map +1 -0
- package/dist/utils/script-generator-utils.js +54 -0
- package/dist/utils/script-generator-utils.js.map +1 -0
- package/dist/utils/script-parser-utils.d.ts +20 -0
- package/dist/utils/script-parser-utils.d.ts.map +1 -0
- package/dist/utils/script-parser-utils.js +126 -0
- package/dist/utils/script-parser-utils.js.map +1 -0
- package/dist/utils/step-execution-utils.d.ts +16 -0
- package/dist/utils/step-execution-utils.d.ts.map +1 -0
- package/dist/utils/step-execution-utils.js +94 -0
- package/dist/utils/step-execution-utils.js.map +1 -0
- package/package.json +7 -1
|
@@ -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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"}
|