lexxit-automation-framework 2.0.20 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +246 -57
- package/dist-obf/actions/baseHandler.js +1 -0
- package/dist-obf/actions/browserManager.js +1 -0
- package/dist-obf/actions/checkboxHandler.js +1 -0
- package/dist-obf/actions/clickHandler.js +1 -0
- package/dist-obf/actions/customcodehandler.js +1 -0
- package/dist-obf/actions/dropdownHandler.js +1 -0
- package/dist-obf/actions/radiobuttonHandler.js +1 -0
- package/dist-obf/actions/textHandler.js +1 -0
- package/dist-obf/api/server.js +1 -0
- package/dist-obf/config.js +1 -0
- package/dist-obf/executor/functionMap.js +1 -0
- package/dist-obf/executor/mapping.js +1 -0
- package/dist-obf/executor/scriptExecutor.js +1 -0
- package/dist-obf/executor/stepExecutor.js +1 -0
- package/dist-obf/runner/testRunner.js +1 -0
- package/dist-obf/sse/sseManager.js +1 -0
- package/dist-obf/store/executionStore.js +1 -0
- package/dist-obf/store/testDataStore.js +1 -0
- package/dist-obf/types/types.js +1 -1
- package/dist-obf/utils/healingService.js +1 -0
- package/dist-obf/utils/locatorService.js +1 -0
- package/dist-obf/utils/logger.js +1 -1
- package/dist-obf/utils/metadataService.js +1 -0
- package/dist-obf/utils/waitConditions.js +1 -0
- package/dist-obf/validator/validator.js +1 -0
- package/npmignore +8 -0
- package/package.json +32 -1
- package/public/dashboard.html +591 -0
- package/src/actions/baseHandler.ts +351 -0
- package/src/actions/browserManager.ts +432 -0
- package/src/actions/checkboxHandler.ts +276 -0
- package/src/actions/clickHandler.ts +513 -0
- package/src/actions/customcodehandler.ts +251 -0
- package/src/actions/dropdownHandler.ts +501 -0
- package/src/actions/radiobuttonHandler.ts +286 -0
- package/src/actions/textHandler.ts +498 -0
- package/src/api/server.ts +210 -0
- package/src/config.ts +7 -0
- package/src/executor/functionMap.ts +153 -0
- package/src/executor/mapping.ts +70 -0
- package/src/executor/scriptExecutor.ts +162 -0
- package/src/executor/stepExecutor.ts +289 -0
- package/src/runner/testRunner.ts +78 -0
- package/src/sse/sseManager.ts +130 -0
- package/src/store/executionStore.ts +152 -0
- package/src/store/testDataStore.ts +46 -0
- package/src/types/types.ts +159 -0
- package/src/utils/healingService.ts +210 -0
- package/src/utils/locatorService.ts +73 -0
- package/src/utils/logger.ts +27 -0
- package/src/utils/metadataService.ts +137 -0
- package/src/utils/waitConditions.ts +141 -0
- package/src/validator/validator.ts +140 -0
- package/tsconfig.json +16 -0
- package/bin/lexxit-automation-framework.js +0 -224
- package/dist-obf/app.js +0 -1
- package/dist-obf/controllers/controller.js +0 -1
- package/dist-obf/core/BrowserManager.js +0 -1
- package/dist-obf/core/PlaywrightEngine.js +0 -1
- package/dist-obf/core/ScreenshotManager.js +0 -1
- package/dist-obf/core/TestData.js +0 -1
- package/dist-obf/core/TestExecutor.js +0 -1
- package/dist-obf/core/handlers/AllHandlers.js +0 -1
- package/dist-obf/core/handlers/BaseHandler.js +0 -1
- package/dist-obf/core/handlers/ClickHandler.js +0 -1
- package/dist-obf/core/handlers/CustomCodeHandler.js +0 -1
- package/dist-obf/core/handlers/DropdownHandler.js +0 -1
- package/dist-obf/core/handlers/InputHandler.js +0 -1
- package/dist-obf/core/registry/ActionRegistry.js +0 -1
- package/dist-obf/installer/frameworkLauncher.js +0 -1
- package/dist-obf/public/dashboard.html +0 -591
- package/dist-obf/public/execution.html +0 -510
- package/dist-obf/public/queue-monitor.html +0 -408
- package/dist-obf/queue/ExecutionQueue.js +0 -1
- package/dist-obf/routes/api.routes.js +0 -1
- package/dist-obf/server.js +0 -1
- package/dist-obf/utils/chromefinder.js +0 -1
- package/dist-obf/utils/elementHighlight.js +0 -1
- package/dist-obf/utils/locatorHelper.js +0 -1
- package/dist-obf/utils/response.js +0 -1
- package/dist-obf/utils/responseFormatter.js +0 -1
- package/dist-obf/utils/sseManager.js +0 -1
- package/scripts/postinstall.js +0 -52
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
|
|
2
|
+
// import { Page } from 'playwright';
|
|
3
|
+
// import { StepResult, ScreenshotMode } from '../types/types';
|
|
4
|
+
// import { TestDataStore } from '../store/testDataStore';
|
|
5
|
+
// import { BaseHandler } from './baseHandler';
|
|
6
|
+
|
|
7
|
+
// export class CustomCodeHandler extends BaseHandler {
|
|
8
|
+
// private page: Page;
|
|
9
|
+
// private testData: TestDataStore;
|
|
10
|
+
|
|
11
|
+
// constructor(page: Page,testData: TestDataStore) {
|
|
12
|
+
// super();
|
|
13
|
+
// this.page = page;
|
|
14
|
+
// this.testData = testData;
|
|
15
|
+
// }
|
|
16
|
+
|
|
17
|
+
// // ─── Helpers ───────────────────────────────────────────────────────────────
|
|
18
|
+
|
|
19
|
+
// // private getStartTime(): string {
|
|
20
|
+
// // return new Date().toISOString();
|
|
21
|
+
// // }
|
|
22
|
+
|
|
23
|
+
// // private getDuration(startMs: number): number {
|
|
24
|
+
// // return Date.now() - startMs;
|
|
25
|
+
// // }
|
|
26
|
+
|
|
27
|
+
// // private buildResult(
|
|
28
|
+
// // status: 'PASS' | 'FAIL',
|
|
29
|
+
// // expected_result: string,
|
|
30
|
+
// // comments: string,
|
|
31
|
+
// // startMs: number,
|
|
32
|
+
// // startTime: string,
|
|
33
|
+
// // step_name: string = '',
|
|
34
|
+
// // uid: string | null = null,
|
|
35
|
+
// // obj_uid: string | null = null,
|
|
36
|
+
// // page_uid: string | null = null
|
|
37
|
+
// // ): StepResult {
|
|
38
|
+
// // return {
|
|
39
|
+
// // uid,
|
|
40
|
+
// // obj_uid,
|
|
41
|
+
// // page_uid,
|
|
42
|
+
// // step_name,
|
|
43
|
+
// // step_script: '',
|
|
44
|
+
// // status,
|
|
45
|
+
// // expected_result,
|
|
46
|
+
// // comments,
|
|
47
|
+
// // duration: this.getDuration(startMs),
|
|
48
|
+
// // start_time: startTime
|
|
49
|
+
// // };
|
|
50
|
+
// // }
|
|
51
|
+
|
|
52
|
+
// // private async captureScreenshot(isFailure: boolean): Promise<string | undefined> {
|
|
53
|
+
// // if (this.screenshotMode === 'never') return undefined;
|
|
54
|
+
// // if (this.screenshotMode === 'on_failure' && !isFailure) return undefined;
|
|
55
|
+
// // try {
|
|
56
|
+
// // if (!this.page || this.page.isClosed()) return undefined;
|
|
57
|
+
// // const buf = await this.page.screenshot({ type: 'png', fullPage: false });
|
|
58
|
+
// // return buf.toString('base64');
|
|
59
|
+
// // } catch {
|
|
60
|
+
// // return undefined;
|
|
61
|
+
// // }
|
|
62
|
+
// // }
|
|
63
|
+
|
|
64
|
+
// // ─── runCustomCode ─────────────────────────────────────────────────────────
|
|
65
|
+
// //
|
|
66
|
+
// // step_script format:
|
|
67
|
+
// // tSetup.runCustomCode('<JS code>', '<returnVariable>', '<optional xpath>')
|
|
68
|
+
// //
|
|
69
|
+
// // The returnVariable name is used as the key in TestDataStore.
|
|
70
|
+
// // Later steps can reference it as: testData["returnVariable"]
|
|
71
|
+
// //
|
|
72
|
+
// // Examples:
|
|
73
|
+
// // tSetup.runCustomCode('const RN_randomEmail=...;', 'RN_randomEmail')
|
|
74
|
+
// // tSetup.runCustomCode('const otp=...;', 'otp', '//input[@id="lname"]')
|
|
75
|
+
// // tSetup.runCustomCode('await page.waitForTimeout(2000);')
|
|
76
|
+
|
|
77
|
+
// async runCustomCode(
|
|
78
|
+
// codeStr: string,
|
|
79
|
+
// returnVariable?: string,
|
|
80
|
+
// xpath?: string,
|
|
81
|
+
// step_name: string = 'Run custom code'
|
|
82
|
+
// ): Promise<StepResult> {
|
|
83
|
+
// const startMs = Date.now();
|
|
84
|
+
// const startTime = this.getStartTime();
|
|
85
|
+
// const expected = 'Custom code executed successfully';
|
|
86
|
+
|
|
87
|
+
// if (!codeStr || !codeStr.trim()) {
|
|
88
|
+
// // const sc = await this.captureScreenshot(true);
|
|
89
|
+
// return this.buildResult('FAIL', expected, 'runCustomCode: codeStr (first argument) is required', startMs, startTime, step_name);
|
|
90
|
+
// }
|
|
91
|
+
|
|
92
|
+
// try {
|
|
93
|
+
// const context = {
|
|
94
|
+
// page: this.page,
|
|
95
|
+
// tSetup: this.page,
|
|
96
|
+
// testData: this.testData,
|
|
97
|
+
// };
|
|
98
|
+
|
|
99
|
+
// const wrappedCode = `
|
|
100
|
+
// "use strict";
|
|
101
|
+
// const { page, tSetup, testData } = __ctx__;
|
|
102
|
+
// ${codeStr}
|
|
103
|
+
// return typeof ${returnVariable || '__undefined__'} !== 'undefined'
|
|
104
|
+
// ? ${returnVariable || 'undefined'}
|
|
105
|
+
// : undefined;
|
|
106
|
+
// `;
|
|
107
|
+
|
|
108
|
+
// // eslint-disable-next-line no-new-func
|
|
109
|
+
// const fn = new Function('__ctx__', `return (async (__ctx__) => { ${wrappedCode} })(__ctx__)`);
|
|
110
|
+
// const value = await fn(context);
|
|
111
|
+
|
|
112
|
+
// // ── Capture return value → write to TestDataStore ─────────────────────
|
|
113
|
+
// if (returnVariable && value !== undefined && value !== null) {
|
|
114
|
+
// const strValue = String(value);
|
|
115
|
+
|
|
116
|
+
// // Store so later steps can use testData["returnVariable"]
|
|
117
|
+
// this.testData.set(returnVariable, strValue);
|
|
118
|
+
|
|
119
|
+
// // If xpath provided, also type directly into the field
|
|
120
|
+
// if (xpath && xpath.trim()) {
|
|
121
|
+
// try {
|
|
122
|
+
// const el = this.page.locator(`xpath=${xpath}`);
|
|
123
|
+
// await el.waitFor({ state: 'visible', timeout: 10000 });
|
|
124
|
+
// await el.clear();
|
|
125
|
+
// await el.fill(strValue);
|
|
126
|
+
// } catch (fillErr: any) {
|
|
127
|
+
// // const sc = await this.captureScreenshot(true);
|
|
128
|
+
// return this.buildResult(
|
|
129
|
+
// 'FAIL',
|
|
130
|
+
// expected,
|
|
131
|
+
// `Custom code ran OK (${returnVariable}="${strValue}") but failed to type into [xpath=${xpath}] — ${fillErr.message}`,
|
|
132
|
+
// startMs, startTime, step_name
|
|
133
|
+
// );
|
|
134
|
+
// }
|
|
135
|
+
// }
|
|
136
|
+
|
|
137
|
+
// // const sc = await this.captureScreenshot(false);
|
|
138
|
+
// return this.buildResult(
|
|
139
|
+
// 'PASS',
|
|
140
|
+
// expected,
|
|
141
|
+
// `Custom code executed. ${returnVariable} = ${strValue}`,
|
|
142
|
+
// startMs, startTime, step_name
|
|
143
|
+
// );
|
|
144
|
+
// }
|
|
145
|
+
|
|
146
|
+
// // ── No return variable — side-effects only ────────────────────────────
|
|
147
|
+
// // const sc = await this.captureScreenshot(false);
|
|
148
|
+
// return this.buildResult('PASS', expected, expected, startMs, startTime, step_name);
|
|
149
|
+
|
|
150
|
+
// } catch (error: any) {
|
|
151
|
+
// // const sc = await this.captureScreenshot(true);
|
|
152
|
+
// const snippet = String(codeStr).slice(0, 200);
|
|
153
|
+
// return this.buildResult(
|
|
154
|
+
// 'FAIL',
|
|
155
|
+
// expected,
|
|
156
|
+
// `Exception during custom code execution — ${error.message} | code: ${snippet}`,
|
|
157
|
+
// startMs, startTime, step_name
|
|
158
|
+
// );
|
|
159
|
+
// }
|
|
160
|
+
// }
|
|
161
|
+
// }
|
|
162
|
+
import { Page } from 'playwright';
|
|
163
|
+
import { StepResult } from '../types/types';
|
|
164
|
+
import { TestDataStore } from '../store/testDataStore';
|
|
165
|
+
import { BaseHandler } from './baseHandler';
|
|
166
|
+
|
|
167
|
+
export class CustomCodeHandler extends BaseHandler {
|
|
168
|
+
protected page: Page;
|
|
169
|
+
private testData: TestDataStore;
|
|
170
|
+
|
|
171
|
+
constructor(page: Page, testData: TestDataStore) {
|
|
172
|
+
super();
|
|
173
|
+
this.page = page;
|
|
174
|
+
this.testData = testData;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async runCustomCode(
|
|
178
|
+
codeStr: string,
|
|
179
|
+
returnVariable?: string,
|
|
180
|
+
xpath?: string,
|
|
181
|
+
step_name: string = 'Run custom code'
|
|
182
|
+
): Promise<StepResult> {
|
|
183
|
+
const startMs = Date.now();
|
|
184
|
+
const startTime = this.getStartTime();
|
|
185
|
+
const expected = 'Custom code executed successfully';
|
|
186
|
+
|
|
187
|
+
if (!codeStr || !codeStr.trim()) {
|
|
188
|
+
return this.buildResult('FAIL', expected, 'runCustomCode: codeStr (first argument) is required', startMs, startTime, step_name);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
try {
|
|
192
|
+
const context = {
|
|
193
|
+
page: this.page,
|
|
194
|
+
tSetup: this.page,
|
|
195
|
+
testData: this.testData,
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const wrappedCode = `
|
|
199
|
+
"use strict";
|
|
200
|
+
const { page, tSetup, testData } = __ctx__;
|
|
201
|
+
${codeStr}
|
|
202
|
+
return typeof ${returnVariable || '__undefined__'} !== 'undefined'
|
|
203
|
+
? ${returnVariable || 'undefined'}
|
|
204
|
+
: undefined;
|
|
205
|
+
`;
|
|
206
|
+
|
|
207
|
+
const fn = new Function('__ctx__', `return (async (__ctx__) => { ${wrappedCode} })(__ctx__)`);
|
|
208
|
+
const value = await fn(context);
|
|
209
|
+
|
|
210
|
+
if (returnVariable && value !== undefined && value !== null) {
|
|
211
|
+
const strValue = String(value);
|
|
212
|
+
|
|
213
|
+
this.testData.set(returnVariable, strValue);
|
|
214
|
+
|
|
215
|
+
if (xpath && xpath.trim()) {
|
|
216
|
+
try {
|
|
217
|
+
const el = this.page.locator(`xpath=${xpath}`);
|
|
218
|
+
await el.waitFor({ state: 'visible', timeout: 10000 });
|
|
219
|
+
await el.clear();
|
|
220
|
+
await el.fill(strValue);
|
|
221
|
+
} catch (fillErr: any) {
|
|
222
|
+
return this.buildResult(
|
|
223
|
+
'FAIL',
|
|
224
|
+
expected,
|
|
225
|
+
`Custom code ran OK (${returnVariable}="${strValue}") but failed to type into [xpath=${xpath}] — ${fillErr.message}`,
|
|
226
|
+
startMs, startTime, step_name
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return this.buildResult(
|
|
232
|
+
'PASS',
|
|
233
|
+
expected,
|
|
234
|
+
`Custom code executed. ${returnVariable} = ${strValue}`,
|
|
235
|
+
startMs, startTime, step_name
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return this.buildResult('PASS', expected, expected, startMs, startTime, step_name);
|
|
240
|
+
|
|
241
|
+
} catch (error: any) {
|
|
242
|
+
const snippet = String(codeStr).slice(0, 200);
|
|
243
|
+
return this.buildResult(
|
|
244
|
+
'FAIL',
|
|
245
|
+
expected,
|
|
246
|
+
`Exception during custom code execution — ${error.message} | code: ${snippet}`,
|
|
247
|
+
startMs, startTime, step_name
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|