pw-automation-framework 2.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.
Files changed (111) hide show
  1. package/README.md +93 -0
  2. package/bin/lexxit-automation-framework.js +427 -0
  3. package/dist/app.d.ts +2 -0
  4. package/dist/app.js +26 -0
  5. package/dist/app.js.map +1 -0
  6. package/dist/controllers/controller.d.ts +57 -0
  7. package/dist/controllers/controller.js +263 -0
  8. package/dist/controllers/controller.js.map +1 -0
  9. package/dist/core/BrowserManager.d.ts +46 -0
  10. package/dist/core/BrowserManager.js +377 -0
  11. package/dist/core/BrowserManager.js.map +1 -0
  12. package/dist/core/PlaywrightEngine.d.ts +16 -0
  13. package/dist/core/PlaywrightEngine.js +246 -0
  14. package/dist/core/PlaywrightEngine.js.map +1 -0
  15. package/dist/core/ScreenshotManager.d.ts +10 -0
  16. package/dist/core/ScreenshotManager.js +28 -0
  17. package/dist/core/ScreenshotManager.js.map +1 -0
  18. package/dist/core/TestData.d.ts +12 -0
  19. package/dist/core/TestData.js +29 -0
  20. package/dist/core/TestData.js.map +1 -0
  21. package/dist/core/TestExecutor.d.ts +16 -0
  22. package/dist/core/TestExecutor.js +355 -0
  23. package/dist/core/TestExecutor.js.map +1 -0
  24. package/dist/core/handlers/AllHandlers.d.ts +116 -0
  25. package/dist/core/handlers/AllHandlers.js +648 -0
  26. package/dist/core/handlers/AllHandlers.js.map +1 -0
  27. package/dist/core/handlers/BaseHandler.d.ts +16 -0
  28. package/dist/core/handlers/BaseHandler.js +27 -0
  29. package/dist/core/handlers/BaseHandler.js.map +1 -0
  30. package/dist/core/handlers/ClickHandler.d.ts +34 -0
  31. package/dist/core/handlers/ClickHandler.js +359 -0
  32. package/dist/core/handlers/ClickHandler.js.map +1 -0
  33. package/dist/core/handlers/CustomCodeHandler.d.ts +35 -0
  34. package/dist/core/handlers/CustomCodeHandler.js +102 -0
  35. package/dist/core/handlers/CustomCodeHandler.js.map +1 -0
  36. package/dist/core/handlers/DropdownHandler.d.ts +43 -0
  37. package/dist/core/handlers/DropdownHandler.js +304 -0
  38. package/dist/core/handlers/DropdownHandler.js.map +1 -0
  39. package/dist/core/handlers/InputHandler.d.ts +24 -0
  40. package/dist/core/handlers/InputHandler.js +197 -0
  41. package/dist/core/handlers/InputHandler.js.map +1 -0
  42. package/dist/core/registry/ActionRegistry.d.ts +8 -0
  43. package/dist/core/registry/ActionRegistry.js +35 -0
  44. package/dist/core/registry/ActionRegistry.js.map +1 -0
  45. package/dist/installer/frameworkLauncher.d.ts +31 -0
  46. package/dist/installer/frameworkLauncher.js +198 -0
  47. package/dist/installer/frameworkLauncher.js.map +1 -0
  48. package/dist/queue/ExecutionQueue.d.ts +52 -0
  49. package/dist/queue/ExecutionQueue.js +175 -0
  50. package/dist/queue/ExecutionQueue.js.map +1 -0
  51. package/dist/routes/api.routes.d.ts +2 -0
  52. package/dist/routes/api.routes.js +16 -0
  53. package/dist/routes/api.routes.js.map +1 -0
  54. package/dist/server.d.ts +1 -0
  55. package/dist/server.js +30 -0
  56. package/dist/server.js.map +1 -0
  57. package/dist/types/types.d.ts +135 -0
  58. package/dist/types/types.js +4 -0
  59. package/dist/types/types.js.map +1 -0
  60. package/dist/utils/elementHighlight.d.ts +35 -0
  61. package/dist/utils/elementHighlight.js +136 -0
  62. package/dist/utils/elementHighlight.js.map +1 -0
  63. package/dist/utils/locatorHelper.d.ts +7 -0
  64. package/dist/utils/locatorHelper.js +53 -0
  65. package/dist/utils/locatorHelper.js.map +1 -0
  66. package/dist/utils/logger.d.ts +12 -0
  67. package/dist/utils/logger.js +35 -0
  68. package/dist/utils/logger.js.map +1 -0
  69. package/dist/utils/response.d.ts +4 -0
  70. package/dist/utils/response.js +25 -0
  71. package/dist/utils/response.js.map +1 -0
  72. package/dist/utils/responseFormatter.d.ts +78 -0
  73. package/dist/utils/responseFormatter.js +123 -0
  74. package/dist/utils/responseFormatter.js.map +1 -0
  75. package/dist/utils/sseManager.d.ts +32 -0
  76. package/dist/utils/sseManager.js +122 -0
  77. package/dist/utils/sseManager.js.map +1 -0
  78. package/lexxit-automation-framework-2.0.0.tgz +0 -0
  79. package/npmignore +5 -0
  80. package/package.json +36 -0
  81. package/scripts/postinstall.js +52 -0
  82. package/src/app.ts +27 -0
  83. package/src/controllers/controller.ts +282 -0
  84. package/src/core/BrowserManager.ts +398 -0
  85. package/src/core/PlaywrightEngine.ts +371 -0
  86. package/src/core/ScreenshotManager.ts +25 -0
  87. package/src/core/TestData.ts +25 -0
  88. package/src/core/TestExecutor.ts +436 -0
  89. package/src/core/handlers/AllHandlers.ts +626 -0
  90. package/src/core/handlers/BaseHandler.ts +41 -0
  91. package/src/core/handlers/ClickHandler.ts +482 -0
  92. package/src/core/handlers/CustomCodeHandler.ts +123 -0
  93. package/src/core/handlers/DropdownHandler.ts +438 -0
  94. package/src/core/handlers/InputHandler.ts +192 -0
  95. package/src/core/registry/ActionRegistry.ts +31 -0
  96. package/src/installer/frameworkLauncher.ts +242 -0
  97. package/src/installer/install.sh +107 -0
  98. package/src/public/dashboard.html +540 -0
  99. package/src/public/queue-monitor.html +190 -0
  100. package/src/queue/ExecutionQueue.ts +200 -0
  101. package/src/routes/api.routes.ts +16 -0
  102. package/src/server.ts +29 -0
  103. package/src/types/types.ts +169 -0
  104. package/src/utils/elementHighlight.ts +174 -0
  105. package/src/utils/locatorHelper.ts +49 -0
  106. package/src/utils/logger.ts +40 -0
  107. package/src/utils/response.ts +27 -0
  108. package/src/utils/responseFormatter.ts +167 -0
  109. package/src/utils/sseManager.ts +127 -0
  110. package/tsconfig.json +18 -0
  111. package/videos/fb1b94b6-6639-4c9a-82bb-63572606f403/page@5bd5c6c8b62baa700e9810cdd64f5c49.webm +0 -0
@@ -0,0 +1,377 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BrowserManager = void 0;
4
+ const playwright_1 = require("playwright");
5
+ const response_1 = require("../utils/response");
6
+ const ScreenshotManager_1 = require("./ScreenshotManager");
7
+ const logger_1 = require("../utils/logger");
8
+ class BrowserManager {
9
+ constructor(tConfig) {
10
+ this.headless = tConfig.headless ?? false;
11
+ this.timeout = tConfig.timeout ?? 30000;
12
+ this.slowMo = tConfig.slowMo ?? 0;
13
+ this.recordVideo = tConfig.record_video ?? false;
14
+ this.videoDir = `videos/${tConfig.executionId}`;
15
+ // this.videoDir = require("path").join(process.cwd(), "videos", tConfig.executionId);
16
+ this.shots = new ScreenshotManager_1.ScreenshotManager(tConfig.screenshot_mode);
17
+ this.log = logger_1.Logger.create("BrowserManager", tConfig.executionId);
18
+ }
19
+ // ─── Open ──────────────────────────────────────────────────────────────────
20
+ async openBrowser(type = "chromium") {
21
+ try {
22
+ const launcher = this.getLauncher(type);
23
+ this.browser = await launcher.launch({
24
+ headless: this.headless,
25
+ slowMo: this.slowMo,
26
+ args: ["--no-sandbox",
27
+ "--disable-dev-shm-usage",
28
+ "--disable-blink-features=AutomationControlled",
29
+ "--start-maximized"
30
+ ],
31
+ });
32
+ const ctxOpts = {
33
+ viewport: { width: 1280, height: 720 },
34
+ // Avoid waiting for networkidle by default — use domcontentloaded instead
35
+ // Individual nav calls can override this
36
+ };
37
+ if (this.recordVideo) {
38
+ ctxOpts.recordVideo = { dir: this.videoDir, size: { width: 1280, height: 720 } };
39
+ }
40
+ this.context = await this.browser.newContext(ctxOpts);
41
+ // ✅ FIX: Use domcontentloaded globally — networkidle was the dropdown delay root cause
42
+ // Each navigation still passes waitUntil but falls back faster
43
+ this.context.setDefaultTimeout(this.timeout);
44
+ this.context.setDefaultNavigationTimeout(this.timeout);
45
+ this.page = await this.context.newPage();
46
+ this.log.info(`${type} browser launched successfully`);
47
+ const sc = await this.shots.onPass(this.page);
48
+ return (0, response_1.pass)(`Browser opened: ${type}`, sc);
49
+ }
50
+ catch (error) {
51
+ this.log.error(`openBrowser failed`, { error: error.message });
52
+ return (0, response_1.fail)("Failed to open browser", error.message);
53
+ }
54
+ }
55
+ getLauncher(type) {
56
+ const map = {
57
+ chromium: playwright_1.chromium, chrome: playwright_1.chromium, edge: playwright_1.chromium,
58
+ firefox: playwright_1.firefox,
59
+ webkit: playwright_1.webkit, safari: playwright_1.webkit,
60
+ };
61
+ const l = map[type.toLowerCase()];
62
+ if (!l)
63
+ throw new Error(`Unsupported browser: "${type}". Use: chromium|chrome|firefox|webkit|safari|edge`);
64
+ return l;
65
+ }
66
+ // ─── Close ─────────────────────────────────────────────────────────────────
67
+ async closeBrowser() {
68
+ try {
69
+ if (this.page && !this.page.isClosed())
70
+ await this.page.close().catch(() => { });
71
+ if (this.context)
72
+ await this.context.close().catch(() => { });
73
+ if (this.browser)
74
+ await this.browser.close().catch(() => { });
75
+ if (this.recordVideo)
76
+ this.log.info(`Video saved to: ${this.videoDir}`);
77
+ return (0, response_1.pass)("Browser closed successfully");
78
+ }
79
+ catch (error) {
80
+ return (0, response_1.fail)("Failed to close browser", error.message);
81
+ }
82
+ }
83
+ // ─── Navigation ────────────────────────────────────────────────────────────
84
+ // ✅ ROOT CAUSE FIX: switched from "networkidle" to "domcontentloaded"
85
+ // networkidle waits for ALL network requests to stop (can be 5-30s on SPAs)
86
+ // domcontentloaded fires as soon as HTML is parsed — much faster
87
+ async navigateToURL(url) {
88
+ try {
89
+ await this.getPage().goto(url, {
90
+ waitUntil: "domcontentloaded", // ✅ was networkidle — that caused dropdown delay
91
+ timeout: this.timeout,
92
+ });
93
+ const sc = await this.shots.onPass(this.page);
94
+ return (0, response_1.pass)(`Navigated to ${url}`, sc);
95
+ }
96
+ catch (error) {
97
+ const sc = await this.shots.onFail(this.page);
98
+ return (0, response_1.fail)(`Failed to navigate to: ${url}`, error.message, sc);
99
+ }
100
+ }
101
+ async navigateBack() {
102
+ try {
103
+ await this.getPage().goBack({ waitUntil: "domcontentloaded" });
104
+ const sc = await this.shots.onPass(this.page);
105
+ return (0, response_1.pass)("Navigated back", sc);
106
+ }
107
+ catch (error) {
108
+ const sc = await this.shots.onFail(this.page);
109
+ return (0, response_1.fail)("Failed to navigate back", error.message, sc);
110
+ }
111
+ }
112
+ async navigateForward() {
113
+ try {
114
+ await this.getPage().goForward({ waitUntil: "domcontentloaded" });
115
+ const sc = await this.shots.onPass(this.page);
116
+ return (0, response_1.pass)("Navigated forward", sc);
117
+ }
118
+ catch (error) {
119
+ const sc = await this.shots.onFail(this.page);
120
+ return (0, response_1.fail)("Failed to navigate forward", error.message, sc);
121
+ }
122
+ }
123
+ async refreshPage() {
124
+ try {
125
+ await this.getPage().reload({ waitUntil: "domcontentloaded" });
126
+ const sc = await this.shots.onPass(this.page);
127
+ return (0, response_1.pass)("Page refreshed", sc);
128
+ }
129
+ catch (error) {
130
+ const sc = await this.shots.onFail(this.page);
131
+ return (0, response_1.fail)("Failed to refresh page", error.message, sc);
132
+ }
133
+ }
134
+ // ─── Window / Viewport ─────────────────────────────────────────────────────
135
+ async maximizeWindow() {
136
+ try {
137
+ await this.getPage().setViewportSize({ width: 1920, height: 1080 });
138
+ return (0, response_1.pass)("Window maximized to 1920×1080");
139
+ }
140
+ catch (error) {
141
+ return (0, response_1.fail)("Failed to maximize window", error.message);
142
+ }
143
+ }
144
+ async setWindowSize(width, height) {
145
+ try {
146
+ await this.getPage().setViewportSize({ width: parseInt(width, 10), height: parseInt(height, 10) });
147
+ return (0, response_1.pass)(`Window set to ${width}×${height}`);
148
+ }
149
+ catch (error) {
150
+ return (0, response_1.fail)("Failed to set window size", error.message);
151
+ }
152
+ }
153
+ // ─── Tabs ──────────────────────────────────────────────────────────────────
154
+ async switchToTab(indexStr) {
155
+ try {
156
+ const pages = this.context.pages();
157
+ const index = parseInt(indexStr, 10);
158
+ if (index >= pages.length)
159
+ return (0, response_1.fail)(`Tab index ${index} out of range (${pages.length} tabs)`);
160
+ this.page = pages[index];
161
+ await this.page.bringToFront();
162
+ const sc = await this.shots.onPass(this.page);
163
+ return (0, response_1.pass)(`Switched to tab ${index}`, sc);
164
+ }
165
+ catch (error) {
166
+ return (0, response_1.fail)("Failed to switch tab", error.message);
167
+ }
168
+ }
169
+ async openNewTab(url) {
170
+ try {
171
+ this.page = await this.context.newPage();
172
+ if (url)
173
+ await this.page.goto(url, { waitUntil: "domcontentloaded" });
174
+ const sc = await this.shots.onPass(this.page);
175
+ return (0, response_1.pass)(`Opened new tab${url ? ": " + url : ""}`, sc);
176
+ }
177
+ catch (error) {
178
+ return (0, response_1.fail)("Failed to open new tab", error.message);
179
+ }
180
+ }
181
+ async closeCurrentTab() {
182
+ try {
183
+ await this.getPage().close();
184
+ const pages = this.context.pages();
185
+ if (pages.length > 0)
186
+ this.page = pages[pages.length - 1];
187
+ return (0, response_1.pass)("Current tab closed");
188
+ }
189
+ catch (error) {
190
+ return (0, response_1.fail)("Failed to close tab", error.message);
191
+ }
192
+ }
193
+ async waitForNewTab(triggerAction) {
194
+ try {
195
+ const [newPage] = await Promise.all([
196
+ this.context.waitForEvent("page"),
197
+ triggerAction(),
198
+ ]);
199
+ await newPage.waitForLoadState("domcontentloaded");
200
+ this.page = newPage;
201
+ const sc = await this.shots.onPass(this.page);
202
+ return (0, response_1.pass)("New tab opened and switched to", sc);
203
+ }
204
+ catch (error) {
205
+ return (0, response_1.fail)("Failed waiting for new tab", error.message);
206
+ }
207
+ }
208
+ // ─── Title / URL ───────────────────────────────────────────────────────────
209
+ async getTitle(storeKey) {
210
+ try {
211
+ const title = await this.getPage().title();
212
+ const sc = await this.shots.onPass(this.page);
213
+ return (0, response_1.pass)(`Page title: "${title}"`, sc, { title });
214
+ }
215
+ catch (error) {
216
+ const sc = await this.shots.onFail(this.page);
217
+ return (0, response_1.fail)("Failed to get title", error.message, sc);
218
+ }
219
+ }
220
+ async verifyTitle(expected) {
221
+ try {
222
+ const title = await this.getPage().title();
223
+ const ok = title === expected;
224
+ const msg = ok ? `Title matches: "${expected}"` : `Title mismatch. Expected: "${expected}", Actual: "${title}"`;
225
+ const sc = ok ? await this.shots.onPass(this.page) : await this.shots.onFail(this.page);
226
+ return ok ? (0, response_1.pass)(msg, sc) : (0, response_1.fail)(msg, undefined, sc);
227
+ }
228
+ catch (error) {
229
+ const sc = await this.shots.onFail(this.page);
230
+ return (0, response_1.fail)("Failed to verify title", error.message, sc);
231
+ }
232
+ }
233
+ async verifyPartialTitle(partial) {
234
+ try {
235
+ const title = await this.getPage().title();
236
+ const ok = title.includes(partial);
237
+ const msg = ok ? `Title contains: "${partial}"` : `Title does not contain "${partial}". Actual: "${title}"`;
238
+ const sc = ok ? await this.shots.onPass(this.page) : await this.shots.onFail(this.page);
239
+ return ok ? (0, response_1.pass)(msg, sc) : (0, response_1.fail)(msg, undefined, sc);
240
+ }
241
+ catch (error) {
242
+ const sc = await this.shots.onFail(this.page);
243
+ return (0, response_1.fail)("Failed to verify partial title", error.message, sc);
244
+ }
245
+ }
246
+ async getCurrentURL() {
247
+ const url = this.getPage().url();
248
+ return (0, response_1.pass)(`Current URL: "${url}"`, undefined, { url });
249
+ }
250
+ async getPageSource() {
251
+ try {
252
+ const pageSource = this.getPage().content();
253
+ return (0, response_1.pass)("Page source captured", undefined, { pagesource: pageSource });
254
+ }
255
+ catch (error) {
256
+ return (0, response_1.fail)(`Failed to get page source — ${error.message}`);
257
+ }
258
+ }
259
+ // ─── Dialogs ───────────────────────────────────────────────────────────────
260
+ async acceptAlert(promptText) {
261
+ try {
262
+ this.getPage().once("dialog", (d) => d.accept(promptText));
263
+ return (0, response_1.pass)("Dialog handler set: will accept next dialog");
264
+ }
265
+ catch (error) {
266
+ return (0, response_1.fail)("Failed to set accept handler", error.message);
267
+ }
268
+ }
269
+ async dismissAlert() {
270
+ try {
271
+ this.getPage().once("dialog", (d) => d.dismiss());
272
+ return (0, response_1.pass)("Dialog handler set: will dismiss next dialog");
273
+ }
274
+ catch (error) {
275
+ return (0, response_1.fail)("Failed to set dismiss handler", error.message);
276
+ }
277
+ }
278
+ async getAlertText(storeKey) {
279
+ return new Promise((resolve) => {
280
+ const timer = setTimeout(() => resolve((0, response_1.fail)("No dialog appeared within timeout")), this.timeout);
281
+ this.getPage().once("dialog", async (d) => {
282
+ clearTimeout(timer);
283
+ const text = d.message();
284
+ await d.dismiss();
285
+ if (storeKey) { /* testData would need to be injected here if needed */ }
286
+ resolve((0, response_1.pass)(`Alert text: "${text}"`, undefined, { text }));
287
+ });
288
+ });
289
+ }
290
+ // ─── Frames ────────────────────────────────────────────────────────────────
291
+ async switchToFrame(nameOrSelector) {
292
+ try {
293
+ const frame = this.getPage().frame({ name: nameOrSelector });
294
+ if (!frame) {
295
+ // try as locator-based frame
296
+ this.getPage().frameLocator(nameOrSelector);
297
+ return (0, response_1.pass)(`FrameLocator set for: "${nameOrSelector}"`);
298
+ }
299
+ return (0, response_1.pass)(`Switched to frame: "${nameOrSelector}"`);
300
+ }
301
+ catch (error) {
302
+ return (0, response_1.fail)("Failed to switch to frame", error.message);
303
+ }
304
+ }
305
+ // ─── JavaScript ────────────────────────────────────────────────────────────
306
+ async executeScript(script) {
307
+ try {
308
+ const result = await this.getPage().evaluate(script);
309
+ const sc = await this.shots.onPass(this.page);
310
+ return (0, response_1.pass)("Script executed", sc, { result });
311
+ }
312
+ catch (error) {
313
+ const sc = await this.shots.onFail(this.page);
314
+ return (0, response_1.fail)("Failed to execute script", error.message, sc);
315
+ }
316
+ }
317
+ async scrollToBottom() {
318
+ try {
319
+ await this.getPage().evaluate("window.scrollTo(0, document.body.scrollHeight)");
320
+ return (0, response_1.pass)("Scrolled to bottom");
321
+ }
322
+ catch (error) {
323
+ return (0, response_1.fail)("Failed to scroll to bottom", error.message);
324
+ }
325
+ }
326
+ async scrollToTop() {
327
+ try {
328
+ await this.getPage().evaluate("window.scrollTo(0, 0)");
329
+ return (0, response_1.pass)("Scrolled to top");
330
+ }
331
+ catch (error) {
332
+ return (0, response_1.fail)("Failed to scroll to top", error.message);
333
+ }
334
+ }
335
+ // ─── Cookies / Storage ─────────────────────────────────────────────────────
336
+ async deleteAllCookies() {
337
+ try {
338
+ await this.context.clearCookies();
339
+ return (0, response_1.pass)("All cookies deleted");
340
+ }
341
+ catch (error) {
342
+ return (0, response_1.fail)("Failed to delete cookies", error.message);
343
+ }
344
+ }
345
+ async clearLocalStorage() {
346
+ try {
347
+ await this.getPage().evaluate("localStorage.clear()");
348
+ return (0, response_1.pass)("LocalStorage cleared");
349
+ }
350
+ catch (error) {
351
+ return (0, response_1.fail)("Failed to clear localStorage", error.message);
352
+ }
353
+ }
354
+ async clearSessionStorage() {
355
+ try {
356
+ await this.getPage().evaluate("sessionStorage.clear()");
357
+ return (0, response_1.pass)("SessionStorage cleared");
358
+ }
359
+ catch (error) {
360
+ return (0, response_1.fail)("Failed to clear sessionStorage", error.message);
361
+ }
362
+ }
363
+ // ─── Screenshot ────────────────────────────────────────────────────────────
364
+ async takeScreenshot() {
365
+ const sc = await this.shots.force(this.page);
366
+ return (0, response_1.pass)("Screenshot captured", sc);
367
+ }
368
+ // ─── Getters ───────────────────────────────────────────────────────────────
369
+ getPage() {
370
+ if (!this.page || this.page.isClosed())
371
+ throw new Error("Browser not initialized. Call openBrowser() first.");
372
+ return this.page;
373
+ }
374
+ hasPage() { return !!this.page && !this.page.isClosed(); }
375
+ }
376
+ exports.BrowserManager = BrowserManager;
377
+ //# sourceMappingURL=BrowserManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserManager.js","sourceRoot":"","sources":["../../src/core/BrowserManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { ActionResponse, ParsedStep, TestCaseConfig } from "../types/types";
2
+ export declare class PlaywrightEngine {
3
+ private browserManager;
4
+ private registry;
5
+ private tConfig;
6
+ private log;
7
+ constructor(tConfig: TestCaseConfig);
8
+ parsedStepScript(script: string | undefined | null): ParsedStep | null;
9
+ execute(script: string | undefined | null, label: string | undefined | null): Promise<ActionResponse | undefined>;
10
+ private registerBrowserActions;
11
+ private registerPageHandlers;
12
+ getPageSource(): Promise<string>;
13
+ getCurrentURL(): Promise<string>;
14
+ forceClose(): Promise<void>;
15
+ getRegisteredActions(): string[];
16
+ }
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+ // import { ActionResponse, ParsedStep, TestCaseConfig } from "../types/types";
3
+ // import { ActionRegistry } from "./registry/ActionRegistry";
4
+ // import { BrowserManager } from "./BrowserManager";
5
+ // import { InputHandler } from "./handlers/InputHandler";
6
+ // import { ClickHandler } from "./handlers/ClickHandler";
7
+ // import { DropdownHandler } from "./handlers/DropdownHandler";
8
+ // import { CustomCodeHandler } from "./handlers/CustomCodeHandler";
9
+ // import { AssertionHandler, WaitHandler, KeyboardHandler, CheckboxHandler, TableHandler } from "./handlers/AllHandlers";
10
+ // import { Logger } from "../utils/logger";
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.PlaywrightEngine = void 0;
13
+ const ActionRegistry_1 = require("./registry/ActionRegistry");
14
+ const BrowserManager_1 = require("./BrowserManager");
15
+ const InputHandler_1 = require("./handlers/InputHandler");
16
+ const ClickHandler_1 = require("./handlers/ClickHandler");
17
+ const DropdownHandler_1 = require("./handlers/DropdownHandler");
18
+ const CustomCodeHandler_1 = require("./handlers/CustomCodeHandler");
19
+ const AllHandlers_1 = require("./handlers/AllHandlers");
20
+ const logger_1 = require("../utils/logger");
21
+ class PlaywrightEngine {
22
+ constructor(tConfig) {
23
+ this.tConfig = tConfig;
24
+ this.browserManager = new BrowserManager_1.BrowserManager(tConfig);
25
+ this.registry = new ActionRegistry_1.ActionRegistry();
26
+ this.log = logger_1.Logger.create("PlaywrightEngine", tConfig.executionId);
27
+ this.registerBrowserActions();
28
+ }
29
+ // ─── Script Parser ─────────────────────────────────────────────────────────
30
+ parsedStepScript(script) {
31
+ // ✅ Guard: must be a non-empty string — no crash on undefined
32
+ if (!script || typeof script !== "string" || !script.trim())
33
+ return null;
34
+ const match = script.match(/tSetup\.(\w+)\(([\s\S]*)\)/i);
35
+ if (!match)
36
+ return null;
37
+ const action = match[1];
38
+ const rawArgs = match[2];
39
+ const args = [];
40
+ // ── Robust tokenizer ────────────────────────────────────────────────────
41
+ // Handles: triple-double-quoted strings """...""" (e.g. runCustomCode blocks)
42
+ // double-quoted strings "..."
43
+ // single-quoted strings '...'
44
+ // tSetup.testData['KEY'] → stored as __testData__:KEY marker
45
+ // and resolved in execute() at runtime
46
+ let i = 0;
47
+ while (i < rawArgs.length) {
48
+ const ch = rawArgs[i];
49
+ // Skip whitespace and commas between arguments
50
+ if (ch === " " || ch === "," || ch === "\n" || ch === "\r" || ch === "\t") {
51
+ i++;
52
+ continue;
53
+ }
54
+ // tSetup.testData['KEY'] or tSetup.testData["KEY"]
55
+ // Captures the variable key and defers resolution to execute()
56
+ if (rawArgs.startsWith("tSetup.testData[", i)) {
57
+ const closeIdx = rawArgs.indexOf("]", i);
58
+ if (closeIdx !== -1) {
59
+ const inner = rawArgs.slice(i + "tSetup.testData[".length, closeIdx).trim();
60
+ const key = inner.replace(/^['"]|['"]$/g, ""); // strip surrounding quotes
61
+ args.push(`__testData__:${key}`);
62
+ i = closeIdx + 1;
63
+ continue;
64
+ }
65
+ }
66
+ // Triple double-quote string: """...""" (used in runCustomCode JS blocks)
67
+ if (ch === '"' && rawArgs[i + 1] === '"' && rawArgs[i + 2] === '"') {
68
+ i += 3;
69
+ let str = "";
70
+ while (i < rawArgs.length) {
71
+ if (rawArgs[i] === '"' && rawArgs[i + 1] === '"' && rawArgs[i + 2] === '"') {
72
+ i += 3;
73
+ break;
74
+ }
75
+ // Unescape \n and \t written as two-character literals inside JSON strings
76
+ if (rawArgs[i] === "\\" && rawArgs[i + 1] === "n") {
77
+ str += "\n";
78
+ i += 2;
79
+ }
80
+ else if (rawArgs[i] === "\\" && rawArgs[i + 1] === "t") {
81
+ str += "\t";
82
+ i += 2;
83
+ }
84
+ else if (rawArgs[i] === "\\" && rawArgs[i + 1] === "\\") {
85
+ str += "\\";
86
+ i += 2;
87
+ }
88
+ else {
89
+ str += rawArgs[i++];
90
+ }
91
+ }
92
+ args.push(str);
93
+ continue;
94
+ }
95
+ // Double-quoted string: "..."
96
+ if (ch === '"') {
97
+ i++;
98
+ let str = "";
99
+ while (i < rawArgs.length && rawArgs[i] !== '"') {
100
+ if (rawArgs[i] === "\\") {
101
+ i++;
102
+ str += rawArgs[i++];
103
+ }
104
+ else {
105
+ str += rawArgs[i++];
106
+ }
107
+ }
108
+ i++; // consume closing "
109
+ args.push(str);
110
+ continue;
111
+ }
112
+ // Single-quoted string: '...'
113
+ if (ch === "'") {
114
+ i++;
115
+ let str = "";
116
+ while (i < rawArgs.length && rawArgs[i] !== "'") {
117
+ if (rawArgs[i] === "\\") {
118
+ i++;
119
+ str += rawArgs[i++];
120
+ }
121
+ else {
122
+ str += rawArgs[i++];
123
+ }
124
+ }
125
+ i++; // consume closing '
126
+ args.push(str.replace(/\\'/g, "'"));
127
+ continue;
128
+ }
129
+ // Any other token (numeric literal, identifier, etc.) — skip
130
+ i++;
131
+ }
132
+ return { action, args };
133
+ }
134
+ async execute(script, label) {
135
+ // ✅ Guard: missing step_script — actionable error instead of crash
136
+ if (!script || typeof script !== "string" || !script.trim()) {
137
+ const msg = "step_script is missing or empty. " +
138
+ "Your steps contain only step_name and value — they are RAW database objects. " +
139
+ "You must call prepareSteps(scriptUid) in your main app BEFORE sending to the framework. " +
140
+ "prepareSteps() resolves obj_uid → locator → step_script for each step.";
141
+ this.log.error(msg);
142
+ return { status: "Fail", comments: msg };
143
+ }
144
+ const parsed = this.parsedStepScript(script);
145
+ if (!parsed) {
146
+ this.log.error(`Cannot parse: "${script}"`);
147
+ return {
148
+ status: "Fail",
149
+ comments: `Invalid script format: "${script}". Expected: tSetup.actionName('arg1', ...)`,
150
+ };
151
+ }
152
+ // Resolve __testData__:KEY markers produced by the parser for
153
+ // tSetup.testData['KEY'] arguments — looks up the live value from the store
154
+ const resolvedArgs = parsed.args.map((arg) => {
155
+ if (typeof arg === "string" && arg.startsWith("__testData__:")) {
156
+ const key = arg.slice("__testData__:".length);
157
+ try {
158
+ return String(this.tConfig.testData.get(key));
159
+ }
160
+ catch {
161
+ this.log.warn(`testData key "${key}" not found — passing empty string`);
162
+ return "";
163
+ }
164
+ }
165
+ return arg;
166
+ });
167
+ this.log.info(`→ ${parsed.action}(${resolvedArgs.join(", ")})`);
168
+ const result = await this.registry.execute(parsed.action, resolvedArgs, label ?? undefined);
169
+ if (!result) {
170
+ return {
171
+ status: "Fail",
172
+ comments: `Unknown action: "${parsed.action}". Call GET /api/actions to list all available actions.`,
173
+ };
174
+ }
175
+ return result;
176
+ }
177
+ registerBrowserActions() {
178
+ const bm = this.browserManager;
179
+ this.registry.register({
180
+ getActions: () => ({
181
+ openbrowser: async (a) => {
182
+ const result = await bm.openBrowser(a[0] || "chromium");
183
+ if (result.status === "Pass")
184
+ this.registerPageHandlers();
185
+ return result;
186
+ },
187
+ closebrowser: () => bm.closeBrowser(),
188
+ navigatetourl: (a) => bm.navigateToURL(a[0]),
189
+ navigateback: () => bm.navigateBack(),
190
+ navigateforward: () => bm.navigateForward(),
191
+ refreshpage: () => bm.refreshPage(),
192
+ gettitle: (a) => bm.getTitle(a[0]),
193
+ verifytitle: (a) => bm.verifyTitle(a[0]),
194
+ verifypartialtitle: (a) => bm.verifyPartialTitle(a[0]),
195
+ getcurrenturl: () => bm.getCurrentURL(),
196
+ maximizewindow: () => bm.maximizeWindow(),
197
+ setwindowsize: (a) => bm.setWindowSize(a[0], a[1]),
198
+ switchtotab: (a) => bm.switchToTab(a[0]),
199
+ opennewtab: (a) => bm.openNewTab(a[0]),
200
+ closecurrenttab: () => bm.closeCurrentTab(),
201
+ acceptalert: (a) => bm.acceptAlert(a[0]),
202
+ dismissalert: () => bm.dismissAlert(),
203
+ getalerttext: (a) => bm.getAlertText(a[0]),
204
+ switchtoframe: (a) => bm.switchToFrame(a[0]),
205
+ executescript: (a) => bm.executeScript(a[0]),
206
+ scrolltobottom: () => bm.scrollToBottom(),
207
+ scrolltotop: () => bm.scrollToTop(),
208
+ deleteallcookies: () => bm.deleteAllCookies(),
209
+ clearlocalstorage: () => bm.clearLocalStorage(),
210
+ clearsessionstorage: () => bm.clearSessionStorage(),
211
+ takescreenshot: () => bm.takeScreenshot(),
212
+ }),
213
+ });
214
+ }
215
+ registerPageHandlers() {
216
+ const page = this.browserManager.getPage();
217
+ const cfg = this.tConfig;
218
+ this.registry.register(new InputHandler_1.InputHandler(cfg, page));
219
+ this.registry.register(new ClickHandler_1.ClickHandler(cfg, page));
220
+ this.registry.register(new DropdownHandler_1.DropdownHandler(cfg, page));
221
+ this.registry.register(new AllHandlers_1.AssertionHandler(cfg, page));
222
+ this.registry.register(new AllHandlers_1.WaitHandler(cfg, page));
223
+ this.registry.register(new AllHandlers_1.KeyboardHandler(cfg, page));
224
+ this.registry.register(new AllHandlers_1.CheckboxHandler(cfg, page));
225
+ this.registry.register(new AllHandlers_1.TableHandler(cfg, page));
226
+ this.registry.register(new CustomCodeHandler_1.CustomCodeHandler(cfg, page));
227
+ this.log.info(`Registered ${this.registry.listActions().length} actions`);
228
+ }
229
+ async getPageSource() {
230
+ const resp = await this.browserManager.getPageSource();
231
+ return resp?.data?.pagesource || "";
232
+ }
233
+ async getCurrentURL() {
234
+ const resp = await this.browserManager.getCurrentURL();
235
+ return resp?.data?.url || "";
236
+ }
237
+ async forceClose() {
238
+ try {
239
+ await this.browserManager.closeBrowser();
240
+ }
241
+ catch { /* ignore */ }
242
+ }
243
+ getRegisteredActions() { return this.registry.listActions(); }
244
+ }
245
+ exports.PlaywrightEngine = PlaywrightEngine;
246
+ //# sourceMappingURL=PlaywrightEngine.js.map