@veolab/discoverylab 1.2.2 → 1.3.0

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 (172) hide show
  1. package/.mcp.json +2 -2
  2. package/README.md +182 -0
  3. package/dist/{chunk-YEZ26ENO.js → chunk-3QRQEDWR.js} +313 -192
  4. package/dist/{chunk-E3N3P2AG.js → chunk-4L76GPRC.js} +1124 -51
  5. package/dist/{chunk-I6YD3QFM.js → chunk-FIL7IWEL.js} +5 -3
  6. package/dist/{chunk-G524UVBK.js → chunk-FNUN7EPB.js} +5 -5
  7. package/dist/chunk-GAKEFJ5T.js +481 -0
  8. package/dist/chunk-LB3RNE3O.js +109 -0
  9. package/dist/chunk-N6JJ2RGV.js +2680 -0
  10. package/dist/{chunk-7HZEDTS7.js → chunk-VRM42PML.js} +3471 -848
  11. package/dist/{chunk-TJ3H23LL.js → chunk-VVIOB362.js} +3 -1
  12. package/dist/{chunk-W3WJGYR6.js → chunk-XFVDP332.js} +8 -2
  13. package/dist/cli.js +397 -9
  14. package/dist/{db-ADBEBNH6.js → db-6WLEVKUV.js} +3 -1
  15. package/dist/esvp-GSISVXLC.js +52 -0
  16. package/dist/esvp-mobile-GC7MAGMI.js +20 -0
  17. package/dist/index.d.ts +123 -1
  18. package/dist/index.html +11689 -8690
  19. package/dist/index.js +67 -12
  20. package/dist/{ocr-UTWC7537.js → ocr-QDYNCSPE.js} +1 -1
  21. package/dist/{playwright-R7Y5HREH.js → playwright-VZ7PXDC5.js} +2 -2
  22. package/dist/runtime/esvp-host-runtime/darwin-arm64/esvp-host-runtime +0 -0
  23. package/dist/runtime/esvp-host-runtime/manifest.json +10 -0
  24. package/dist/server-FO3UVUZU.js +22 -0
  25. package/dist/{setup-B5YPNUE4.js → setup-2SQC5UHJ.js} +2 -2
  26. package/dist/{tools-YS4QHOTQ.js → tools-OCRMOQ4U.js} +61 -6
  27. package/package.json +36 -5
  28. package/dist/chunk-22OCFYHG.js +0 -6283
  29. package/dist/chunk-24VARQVO.js +0 -7818
  30. package/dist/chunk-2OGZX6C4.js +0 -588
  31. package/dist/chunk-2WCNIFRO.js +0 -6191
  32. package/dist/chunk-43U6UYV7.js +0 -590
  33. package/dist/chunk-4H2E3K2G.js +0 -7638
  34. package/dist/chunk-4KLG6DDE.js +0 -334
  35. package/dist/chunk-4MS6YW2B.js +0 -6490
  36. package/dist/chunk-4NNTRJOI.js +0 -7791
  37. package/dist/chunk-5F76VWME.js +0 -6397
  38. package/dist/chunk-5NEFN42O.js +0 -7791
  39. package/dist/chunk-63MEQ6UH.js +0 -7673
  40. package/dist/chunk-6H3NXFX3.js +0 -6861
  41. package/dist/chunk-7DOG2W4O.js +0 -6428
  42. package/dist/chunk-7IDQLLBW.js +0 -311
  43. package/dist/chunk-7NP64TGJ.js +0 -6822
  44. package/dist/chunk-AATLY4KT.js +0 -6505
  45. package/dist/chunk-C7QUR7XX.js +0 -6397
  46. package/dist/chunk-CGKCE6MC.js +0 -6279
  47. package/dist/chunk-D25V6IWE.js +0 -6487
  48. package/dist/chunk-EQOZSXAT.js +0 -6822
  49. package/dist/chunk-FPHD7HSQ.js +0 -6812
  50. package/dist/chunk-GGJJUCFK.js +0 -7160
  51. package/dist/chunk-GLHOY3NN.js +0 -7805
  52. package/dist/chunk-GML5MKQA.js +0 -6398
  53. package/dist/chunk-GOL6FUJL.js +0 -6045
  54. package/dist/chunk-GSWHWEYC.js +0 -1346
  55. package/dist/chunk-HDKEQOF5.js +0 -7788
  56. package/dist/chunk-HZGSWVVS.js +0 -7111
  57. package/dist/chunk-IGZ5TICZ.js +0 -334
  58. package/dist/chunk-IRKQG33A.js +0 -7054
  59. package/dist/chunk-JFTBF4JR.js +0 -6040
  60. package/dist/chunk-JVLVBPUJ.js +0 -6180
  61. package/dist/chunk-JY3KC67R.js +0 -6504
  62. package/dist/chunk-KUFBCBNJ.js +0 -6815
  63. package/dist/chunk-KV7KDJ43.js +0 -7639
  64. package/dist/chunk-L4SA5F5W.js +0 -6397
  65. package/dist/chunk-L5IJZV5F.js +0 -6822
  66. package/dist/chunk-MFFPQLU4.js +0 -7102
  67. package/dist/chunk-MJS2YKNR.js +0 -6397
  68. package/dist/chunk-MN6LCZHZ.js +0 -1320
  69. package/dist/chunk-NBAUZ7X2.js +0 -1336
  70. package/dist/chunk-NDBW6ELQ.js +0 -7638
  71. package/dist/chunk-O2HBSDI2.js +0 -6175
  72. package/dist/chunk-OFFIUYMG.js +0 -6341
  73. package/dist/chunk-OVCQGF2J.js +0 -1321
  74. package/dist/chunk-P4S7ZY6G.js +0 -7638
  75. package/dist/chunk-PBHUHSC3.js +0 -6002
  76. package/dist/chunk-PC4LR4ZI.js +0 -6359
  77. package/dist/chunk-PMTGGZ7R.js +0 -6397
  78. package/dist/chunk-PTXSB3UV.js +0 -497
  79. package/dist/chunk-PYUCY3U6.js +0 -1340
  80. package/dist/chunk-QJXXHOV7.js +0 -205
  81. package/dist/chunk-RDZDSOAL.js +0 -7750
  82. package/dist/chunk-RLW2OI2L.js +0 -6383
  83. package/dist/chunk-RUGHHO4K.js +0 -6395
  84. package/dist/chunk-SIOQVM2E.js +0 -6819
  85. package/dist/chunk-SR67SRIT.js +0 -1336
  86. package/dist/chunk-SSRXIO2V.js +0 -6822
  87. package/dist/chunk-SWSEKFON.js +0 -6487
  88. package/dist/chunk-TAODYZ52.js +0 -1393
  89. package/dist/chunk-TBG76CYG.js +0 -6395
  90. package/dist/chunk-V3CBINLD.js +0 -6812
  91. package/dist/chunk-VPYSLEGM.js +0 -6710
  92. package/dist/chunk-VY3BLXBW.js +0 -329
  93. package/dist/chunk-WTFOGVJQ.js +0 -6365
  94. package/dist/chunk-X64SFUT5.js +0 -6099
  95. package/dist/chunk-XIBF5LBD.js +0 -6395
  96. package/dist/chunk-XUKWS2CE.js +0 -7805
  97. package/dist/chunk-XZZKFF5V.js +0 -7787
  98. package/dist/chunk-Y5VDMSYC.js +0 -6701
  99. package/dist/chunk-YUBL36H4.js +0 -6605
  100. package/dist/chunk-YWVXFVSW.js +0 -6456
  101. package/dist/chunk-ZJFWMSZF.js +0 -7883
  102. package/dist/chunk-ZXZACOLD.js +0 -6822
  103. package/dist/db-IWIL65EX.js +0 -33
  104. package/dist/gridCompositor-ENKLFPWR.js +0 -409
  105. package/dist/playwright-A3OGSDRG.js +0 -38
  106. package/dist/playwright-ATDC4NYW.js +0 -38
  107. package/dist/playwright-E6EUFIJG.js +0 -38
  108. package/dist/server-2DXLKLFM.js +0 -13
  109. package/dist/server-2ICEWJVK.js +0 -13
  110. package/dist/server-2MQV3FNY.js +0 -13
  111. package/dist/server-2NGD7GE3.js +0 -13
  112. package/dist/server-2VKO76UK.js +0 -14
  113. package/dist/server-3BK2VFU7.js +0 -13
  114. package/dist/server-3FBHBA7L.js +0 -15
  115. package/dist/server-4LDOB3NX.js +0 -13
  116. package/dist/server-4YI44KDR.js +0 -13
  117. package/dist/server-64XMXA5P.js +0 -13
  118. package/dist/server-6IPHVUYT.js +0 -14
  119. package/dist/server-73ORHMJN.js +0 -13
  120. package/dist/server-73P7M3QB.js +0 -14
  121. package/dist/server-BPVRW5LJ.js +0 -14
  122. package/dist/server-BW4RKZIX.js +0 -13
  123. package/dist/server-CFS5SM5K.js +0 -13
  124. package/dist/server-DX7VYHHM.js +0 -13
  125. package/dist/server-F3YPX6ET.js +0 -13
  126. package/dist/server-FUXTR33I.js +0 -13
  127. package/dist/server-G2SY3DOS.js +0 -13
  128. package/dist/server-G32U7VOQ.js +0 -13
  129. package/dist/server-HKRIY7FP.js +0 -14
  130. package/dist/server-HON66OES.js +0 -15
  131. package/dist/server-IOOZK4NP.js +0 -14
  132. package/dist/server-IZEO7OJJ.js +0 -14
  133. package/dist/server-J52LMTBT.js +0 -13
  134. package/dist/server-JG7UKFGK.js +0 -14
  135. package/dist/server-JSCHEBOD.js +0 -13
  136. package/dist/server-K6KC4ZOM.js +0 -13
  137. package/dist/server-KJVRGWFE.js +0 -13
  138. package/dist/server-LCPB2L4U.js +0 -13
  139. package/dist/server-M7LDYKAJ.js +0 -13
  140. package/dist/server-MKVK6ZQQ.js +0 -13
  141. package/dist/server-MU52LCXT.js +0 -13
  142. package/dist/server-NM5CKDUU.js +0 -13
  143. package/dist/server-NPZN3FWO.js +0 -14
  144. package/dist/server-O5FIAHSY.js +0 -14
  145. package/dist/server-OESJUEYC.js +0 -13
  146. package/dist/server-ONSKQO4W.js +0 -13
  147. package/dist/server-P27BZXBL.js +0 -14
  148. package/dist/server-Q4FBWQUA.js +0 -13
  149. package/dist/server-RNQ7VUAL.js +0 -13
  150. package/dist/server-S6B5WUBT.js +0 -14
  151. package/dist/server-SRYNSGSP.js +0 -14
  152. package/dist/server-SUN3W2YK.js +0 -13
  153. package/dist/server-UA62LHZB.js +0 -13
  154. package/dist/server-UJB44EW5.js +0 -13
  155. package/dist/server-X3TLP6DX.js +0 -14
  156. package/dist/server-YT2UGEZK.js +0 -13
  157. package/dist/server-ZBPQ33V6.js +0 -14
  158. package/dist/setup-27CQAX6K.js +0 -17
  159. package/dist/setup-AQX4JQVR.js +0 -17
  160. package/dist/setup-EQTU7FI6.js +0 -17
  161. package/dist/tools-2KPB37GK.js +0 -178
  162. package/dist/tools-3H6IOWXV.js +0 -178
  163. package/dist/tools-3KYHPDCJ.js +0 -178
  164. package/dist/tools-75BAPCUM.js +0 -177
  165. package/dist/tools-BUVCUCRL.js +0 -178
  166. package/dist/tools-HDNODRS6.js +0 -178
  167. package/dist/tools-HP5MNY3D.js +0 -177
  168. package/dist/tools-L6PKKQPY.js +0 -179
  169. package/dist/tools-N5N2IO7V.js +0 -178
  170. package/dist/tools-NFJEZ2FF.js +0 -177
  171. package/dist/tools-OPULIER6.js +0 -178
  172. package/dist/tools-TLCKABUW.js +0 -178
@@ -1,497 +0,0 @@
1
- import {
2
- PROJECTS_DIR
3
- } from "./chunk-VY3BLXBW.js";
4
-
5
- // src/core/testing/playwright.ts
6
- import { exec, spawn } from "child_process";
7
- import { promisify } from "util";
8
- import * as fs from "fs";
9
- import * as path from "path";
10
- import { createRequire } from "module";
11
- var execAsync = promisify(exec);
12
- var requireFromHere = createRequire(import.meta.url);
13
- function resolveInstalledPlaywrightVersion() {
14
- try {
15
- const pkgPath = requireFromHere.resolve("playwright/package.json");
16
- const raw = fs.readFileSync(pkgPath, "utf-8");
17
- const pkg = JSON.parse(raw);
18
- return typeof pkg.version === "string" && pkg.version.trim() ? pkg.version.trim() : "installed";
19
- } catch {
20
- return null;
21
- }
22
- }
23
- async function isPlaywrightInstalled() {
24
- return !!resolveInstalledPlaywrightVersion();
25
- }
26
- async function getPlaywrightVersion() {
27
- return resolveInstalledPlaywrightVersion();
28
- }
29
- async function installPlaywrightBrowsers() {
30
- try {
31
- await execAsync("npx playwright install");
32
- return { success: true };
33
- } catch (error) {
34
- return {
35
- success: false,
36
- error: error instanceof Error ? error.message : String(error)
37
- };
38
- }
39
- }
40
- var BrowserDevices = {
41
- "Desktop Chrome": {
42
- name: "Desktop Chrome",
43
- viewport: { width: 1280, height: 720 },
44
- userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
45
- deviceScaleFactor: 1,
46
- isMobile: false,
47
- hasTouch: false
48
- },
49
- "Desktop Safari": {
50
- name: "Desktop Safari",
51
- viewport: { width: 1280, height: 720 },
52
- userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15",
53
- deviceScaleFactor: 1,
54
- isMobile: false,
55
- hasTouch: false
56
- },
57
- "iPhone 15 Pro": {
58
- name: "iPhone 15 Pro",
59
- viewport: { width: 393, height: 852 },
60
- userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
61
- deviceScaleFactor: 3,
62
- isMobile: true,
63
- hasTouch: true
64
- },
65
- "iPhone 14": {
66
- name: "iPhone 14",
67
- viewport: { width: 390, height: 844 },
68
- userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1",
69
- deviceScaleFactor: 3,
70
- isMobile: true,
71
- hasTouch: true
72
- },
73
- "Pixel 8": {
74
- name: "Pixel 8",
75
- viewport: { width: 412, height: 915 },
76
- userAgent: "Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36",
77
- deviceScaleFactor: 2.625,
78
- isMobile: true,
79
- hasTouch: true
80
- },
81
- "iPad Pro 12.9": {
82
- name: "iPad Pro 12.9",
83
- viewport: { width: 1024, height: 1366 },
84
- userAgent: "Mozilla/5.0 (iPad; CPU OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
85
- deviceScaleFactor: 2,
86
- isMobile: true,
87
- hasTouch: true
88
- }
89
- };
90
- function listBrowserDevices() {
91
- return Object.values(BrowserDevices);
92
- }
93
- function getBrowserDevice(name) {
94
- return BrowserDevices[name] || null;
95
- }
96
- function generatePlaywrightScript(script) {
97
- const { name, baseURL, viewport, actions } = script;
98
- const lines = [
99
- "import { test, expect } from '@playwright/test';",
100
- ""
101
- ];
102
- lines.push(`test('${name || "Generated Test"}', async ({ page }) => {`);
103
- if (viewport) {
104
- lines.push(` await page.setViewportSize({ width: ${viewport.width}, height: ${viewport.height} });`);
105
- }
106
- if (baseURL) {
107
- lines.push(` await page.goto('${baseURL}');`);
108
- }
109
- for (const action of actions) {
110
- const code = generateActionCode(action);
111
- if (code) {
112
- lines.push(` ${code}`);
113
- }
114
- }
115
- lines.push("});");
116
- lines.push("");
117
- return lines.join("\n");
118
- }
119
- function generateActionCode(action) {
120
- const { type, selector, value, url, key, options } = action;
121
- switch (type) {
122
- case "goto":
123
- return `await page.goto('${url || ""}');`;
124
- case "click":
125
- if (!selector) return null;
126
- return `await page.click('${selector}');`;
127
- case "fill":
128
- if (!selector) return null;
129
- return `await page.fill('${selector}', '${value || ""}');`;
130
- case "type":
131
- if (!selector) return null;
132
- return `await page.type('${selector}', '${value || ""}');`;
133
- case "press":
134
- if (!selector) return null;
135
- return `await page.press('${selector}', '${key || "Enter"}');`;
136
- case "check":
137
- if (!selector) return null;
138
- return `await page.check('${selector}');`;
139
- case "uncheck":
140
- if (!selector) return null;
141
- return `await page.uncheck('${selector}');`;
142
- case "selectOption":
143
- if (!selector) return null;
144
- return `await page.selectOption('${selector}', '${value || ""}');`;
145
- case "hover":
146
- if (!selector) return null;
147
- return `await page.hover('${selector}');`;
148
- case "focus":
149
- if (!selector) return null;
150
- return `await page.focus('${selector}');`;
151
- case "screenshot":
152
- return `await page.screenshot({ path: '${value || "screenshot.png"}' });`;
153
- case "wait":
154
- return `await page.waitForTimeout(${value || 1e3});`;
155
- case "waitForSelector":
156
- if (!selector) return null;
157
- return `await page.waitForSelector('${selector}');`;
158
- case "waitForURL":
159
- return `await page.waitForURL('${url || ""}');`;
160
- case "expectVisible":
161
- if (!selector) return null;
162
- return `await expect(page.locator('${selector}')).toBeVisible();`;
163
- case "expectHidden":
164
- if (!selector) return null;
165
- return `await expect(page.locator('${selector}')).toBeHidden();`;
166
- case "expectText":
167
- if (!selector) return null;
168
- return `await expect(page.locator('${selector}')).toHaveText('${value || ""}');`;
169
- case "expectURL":
170
- return `await expect(page).toHaveURL('${url || ""}');`;
171
- case "expectTitle":
172
- return `await expect(page).toHaveTitle('${value || ""}');`;
173
- case "scroll":
174
- if (selector) {
175
- return `await page.locator('${selector}').scrollIntoViewIfNeeded();`;
176
- }
177
- return `await page.evaluate(() => window.scrollBy(0, ${value || 500}));`;
178
- case "evaluate":
179
- return `await page.evaluate(() => { ${value || ""} });`;
180
- default:
181
- return null;
182
- }
183
- }
184
- var PlaywrightActions = {
185
- // Navigation
186
- goto: (url) => ({ type: "goto", url }),
187
- goBack: () => ({ type: "evaluate", value: "history.back()" }),
188
- goForward: () => ({ type: "evaluate", value: "history.forward()" }),
189
- reload: () => ({ type: "evaluate", value: "location.reload()" }),
190
- // Interactions
191
- click: (selector) => ({ type: "click", selector }),
192
- fill: (selector, value) => ({ type: "fill", selector, value }),
193
- type: (selector, value) => ({ type: "type", selector, value }),
194
- press: (selector, key) => ({ type: "press", selector, key }),
195
- check: (selector) => ({ type: "check", selector }),
196
- uncheck: (selector) => ({ type: "uncheck", selector }),
197
- selectOption: (selector, value) => ({ type: "selectOption", selector, value }),
198
- hover: (selector) => ({ type: "hover", selector }),
199
- focus: (selector) => ({ type: "focus", selector }),
200
- // Waiting
201
- wait: (ms) => ({ type: "wait", value: String(ms) }),
202
- waitForSelector: (selector) => ({ type: "waitForSelector", selector }),
203
- waitForURL: (url) => ({ type: "waitForURL", url }),
204
- // Screenshots
205
- screenshot: (path2) => ({ type: "screenshot", value: path2 }),
206
- // Scrolling
207
- scroll: (pixels) => ({ type: "scroll", value: String(pixels || 500) }),
208
- scrollToElement: (selector) => ({ type: "scroll", selector }),
209
- // Assertions
210
- expectVisible: (selector) => ({ type: "expectVisible", selector }),
211
- expectHidden: (selector) => ({ type: "expectHidden", selector }),
212
- expectText: (selector, text) => ({ type: "expectText", selector, value: text }),
213
- expectURL: (url) => ({ type: "expectURL", url }),
214
- expectTitle: (title) => ({ type: "expectTitle", value: title }),
215
- // Custom
216
- evaluate: (code) => ({ type: "evaluate", value: code })
217
- };
218
- async function runPlaywrightTest(options) {
219
- const installed = await isPlaywrightInstalled();
220
- if (!installed) {
221
- return {
222
- success: false,
223
- error: "Playwright is not installed. Install with: npm install -D @playwright/test && npx playwright install"
224
- };
225
- }
226
- const {
227
- testPath,
228
- testPattern,
229
- config = {},
230
- outputDir = path.join(PROJECTS_DIR, "playwright-output", Date.now().toString()),
231
- project,
232
- workers = 1,
233
- retries = 0,
234
- reporter = "json"
235
- } = options;
236
- await fs.promises.mkdir(outputDir, { recursive: true });
237
- const startTime = Date.now();
238
- const args = ["playwright", "test"];
239
- if (testPath) {
240
- args.push(testPath);
241
- }
242
- if (testPattern) {
243
- args.push("-g", testPattern);
244
- }
245
- if (project) {
246
- args.push("--project", project);
247
- }
248
- args.push("--workers", workers.toString());
249
- if (retries > 0) {
250
- args.push("--retries", retries.toString());
251
- }
252
- args.push("--reporter", reporter);
253
- args.push("--output", outputDir);
254
- if (config.browser) {
255
- args.push("--browser", config.browser);
256
- }
257
- if (config.headless === false) {
258
- args.push("--headed");
259
- }
260
- try {
261
- const { stdout, stderr } = await execAsync(`npx ${args.join(" ")}`, {
262
- timeout: config.timeout || 3e5,
263
- cwd: process.cwd()
264
- });
265
- const duration = Date.now() - startTime;
266
- let passed = 0;
267
- let failed = 0;
268
- let skipped = 0;
269
- const passedMatch = stdout.match(/(\d+) passed/);
270
- const failedMatch = stdout.match(/(\d+) failed/);
271
- const skippedMatch = stdout.match(/(\d+) skipped/);
272
- if (passedMatch) passed = parseInt(passedMatch[1], 10);
273
- if (failedMatch) failed = parseInt(failedMatch[1], 10);
274
- if (skippedMatch) skipped = parseInt(skippedMatch[1], 10);
275
- const videos = [];
276
- const screenshots = [];
277
- const traces = [];
278
- if (fs.existsSync(outputDir)) {
279
- const collectArtifacts = async (dir) => {
280
- const files = await fs.promises.readdir(dir, { withFileTypes: true });
281
- for (const file of files) {
282
- const filePath = path.join(dir, file.name);
283
- if (file.isDirectory()) {
284
- await collectArtifacts(filePath);
285
- } else if (file.name.endsWith(".webm") || file.name.endsWith(".mp4")) {
286
- videos.push(filePath);
287
- } else if (file.name.endsWith(".png")) {
288
- screenshots.push(filePath);
289
- } else if (file.name.endsWith(".zip") && file.name.includes("trace")) {
290
- traces.push(filePath);
291
- }
292
- }
293
- };
294
- await collectArtifacts(outputDir);
295
- }
296
- return {
297
- success: failed === 0,
298
- duration,
299
- passed,
300
- failed,
301
- skipped,
302
- output: stdout + stderr,
303
- reportPath: path.join(outputDir, "report.json"),
304
- videos,
305
- screenshots,
306
- traces
307
- };
308
- } catch (error) {
309
- const duration = Date.now() - startTime;
310
- const message = error instanceof Error ? error.message : String(error);
311
- let passed = 0;
312
- let failed = 0;
313
- let skipped = 0;
314
- const passedMatch = message.match(/(\d+) passed/);
315
- const failedMatch = message.match(/(\d+) failed/);
316
- const skippedMatch = message.match(/(\d+) skipped/);
317
- if (passedMatch) passed = parseInt(passedMatch[1], 10);
318
- if (failedMatch) failed = parseInt(failedMatch[1], 10);
319
- if (skippedMatch) skipped = parseInt(skippedMatch[1], 10);
320
- return {
321
- success: false,
322
- error: message,
323
- duration,
324
- passed,
325
- failed,
326
- skipped,
327
- output: message
328
- };
329
- }
330
- }
331
- async function runPlaywrightScript(script, options = {}) {
332
- const outputDir = options.outputDir || path.join(PROJECTS_DIR, "playwright-output", Date.now().toString());
333
- await fs.promises.mkdir(outputDir, { recursive: true });
334
- const scriptContent = generatePlaywrightScript(script);
335
- const scriptPath = path.join(outputDir, "test.spec.ts");
336
- await fs.promises.writeFile(scriptPath, scriptContent);
337
- const configContent = `
338
- import { defineConfig } from '@playwright/test';
339
-
340
- export default defineConfig({
341
- testDir: '.',
342
- timeout: ${options.config?.timeout || 3e4},
343
- use: {
344
- headless: ${options.config?.headless !== false},
345
- video: '${options.config?.video || "off"}',
346
- screenshot: '${options.config?.screenshot || "off"}',
347
- trace: '${options.config?.trace || "off"}',
348
- ${script.baseURL ? `baseURL: '${script.baseURL}',` : ""}
349
- ${script.viewport ? `viewport: { width: ${script.viewport.width}, height: ${script.viewport.height} },` : ""}
350
- },
351
- reporter: [['json', { outputFile: 'report.json' }]],
352
- outputDir: './results',
353
- });
354
- `;
355
- const configPath = path.join(outputDir, "playwright.config.ts");
356
- await fs.promises.writeFile(configPath, configContent);
357
- return runPlaywrightTest({
358
- ...options,
359
- testPath: scriptPath,
360
- outputDir
361
- });
362
- }
363
- async function savePlaywrightScript(script, outputPath) {
364
- const content = generatePlaywrightScript(script);
365
- const filePath = outputPath || path.join(
366
- PROJECTS_DIR,
367
- "scripts",
368
- `${script.name?.replace(/\s+/g, "_") || "test"}_${Date.now()}.spec.ts`
369
- );
370
- await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
371
- await fs.promises.writeFile(filePath, content);
372
- return filePath;
373
- }
374
- async function startPlaywrightCodegen(url, options = {}) {
375
- const installed = await isPlaywrightInstalled();
376
- if (!installed) {
377
- return {
378
- success: false,
379
- error: "Playwright is not installed"
380
- };
381
- }
382
- try {
383
- const args = ["playwright", "codegen"];
384
- if (options.browser) {
385
- args.push("--browser", options.browser);
386
- }
387
- if (options.device) {
388
- args.push("--device", `"${options.device}"`);
389
- }
390
- if (options.outputPath) {
391
- args.push("-o", options.outputPath);
392
- }
393
- if (url) {
394
- args.push(url);
395
- }
396
- spawn("npx", args, {
397
- detached: true,
398
- stdio: "ignore",
399
- shell: true
400
- }).unref();
401
- return { success: true };
402
- } catch (error) {
403
- return {
404
- success: false,
405
- error: error instanceof Error ? error.message : String(error)
406
- };
407
- }
408
- }
409
- async function showPlaywrightReport(reportDir) {
410
- const installed = await isPlaywrightInstalled();
411
- if (!installed) {
412
- return {
413
- success: false,
414
- error: "Playwright is not installed"
415
- };
416
- }
417
- try {
418
- const args = ["playwright", "show-report"];
419
- if (reportDir) {
420
- args.push(reportDir);
421
- }
422
- spawn("npx", args, {
423
- detached: true,
424
- stdio: "ignore",
425
- shell: true
426
- }).unref();
427
- return { success: true };
428
- } catch (error) {
429
- return {
430
- success: false,
431
- error: error instanceof Error ? error.message : String(error)
432
- };
433
- }
434
- }
435
- function createLoginScript(baseURL, usernameSelector, passwordSelector, submitSelector, successURL) {
436
- return {
437
- name: "Login Test",
438
- baseURL,
439
- actions: [
440
- PlaywrightActions.goto(baseURL),
441
- PlaywrightActions.fill(usernameSelector, "${USERNAME}"),
442
- PlaywrightActions.fill(passwordSelector, "${PASSWORD}"),
443
- PlaywrightActions.click(submitSelector),
444
- PlaywrightActions.waitForURL(successURL),
445
- PlaywrightActions.expectURL(successURL),
446
- PlaywrightActions.screenshot("login-success.png")
447
- ]
448
- };
449
- }
450
- function createNavigationScript(baseURL, links) {
451
- const actions = [PlaywrightActions.goto(baseURL)];
452
- for (const link of links) {
453
- actions.push(PlaywrightActions.click(link.selector));
454
- actions.push(PlaywrightActions.waitForURL(link.expectedURL));
455
- actions.push(PlaywrightActions.screenshot(`${link.name}.png`));
456
- actions.push(PlaywrightActions.goBack());
457
- }
458
- return {
459
- name: "Navigation Test",
460
- baseURL,
461
- actions
462
- };
463
- }
464
- function createFormSubmissionScript(baseURL, formFields, submitSelector, successIndicator) {
465
- const actions = [PlaywrightActions.goto(baseURL)];
466
- for (const field of formFields) {
467
- actions.push(PlaywrightActions.fill(field.selector, field.value));
468
- }
469
- actions.push(PlaywrightActions.click(submitSelector));
470
- actions.push(PlaywrightActions.waitForSelector(successIndicator));
471
- actions.push(PlaywrightActions.expectVisible(successIndicator));
472
- actions.push(PlaywrightActions.screenshot("form-success.png"));
473
- return {
474
- name: "Form Submission Test",
475
- baseURL,
476
- actions
477
- };
478
- }
479
-
480
- export {
481
- isPlaywrightInstalled,
482
- getPlaywrightVersion,
483
- installPlaywrightBrowsers,
484
- BrowserDevices,
485
- listBrowserDevices,
486
- getBrowserDevice,
487
- generatePlaywrightScript,
488
- PlaywrightActions,
489
- runPlaywrightTest,
490
- runPlaywrightScript,
491
- savePlaywrightScript,
492
- startPlaywrightCodegen,
493
- showPlaywrightReport,
494
- createLoginScript,
495
- createNavigationScript,
496
- createFormSubmissionScript
497
- };