testeranto 0.84.0 → 0.90.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 (62) hide show
  1. package/README.md +1 -5
  2. package/bin/init-docs.js +24 -0
  3. package/bundle.js +53 -0
  4. package/dist/common/dist/module/src/Init.js +40 -0
  5. package/dist/common/src/Init.js +30 -0
  6. package/dist/common/src/PM/main.js +45 -9
  7. package/dist/common/src/Project.js +80 -0
  8. package/dist/common/src/Puppeteer.js +1 -1
  9. package/dist/common/{run-tests.js → src/build-tests.js} +10 -5
  10. package/dist/common/src/defaultConfig.js +19 -0
  11. package/dist/common/src/esbuildConfigs/inputFilesPlugin.js +27 -15
  12. package/dist/common/src/init-docs.js +43 -0
  13. package/dist/common/src/lib/abstractBase.js +0 -64
  14. package/dist/common/src/lib/core.js +5 -3
  15. package/dist/common/{build-tests.js → src/run-tests.js} +10 -9
  16. package/dist/common/tsconfig.common.tsbuildinfo +1 -1
  17. package/dist/module/src/Init.js +30 -0
  18. package/dist/module/src/PM/main.js +45 -9
  19. package/dist/module/src/Project.js +80 -0
  20. package/dist/module/src/Puppeteer.js +1 -1
  21. package/dist/module/src/build-tests.js +11 -0
  22. package/dist/module/src/defaultConfig.js +17 -0
  23. package/dist/module/src/esbuildConfigs/inputFilesPlugin.js +27 -15
  24. package/dist/module/src/init-docs.js +15 -0
  25. package/dist/module/src/lib/abstractBase.js +0 -64
  26. package/dist/module/src/lib/core.js +5 -3
  27. package/dist/module/src/run-tests.js +11 -0
  28. package/dist/module/tsconfig.module.tsbuildinfo +1 -1
  29. package/dist/prebuild/build-tests.mjs +552 -0
  30. package/dist/prebuild/init-docs.mjs +48 -0
  31. package/dist/prebuild/run-tests.mjs +907 -0
  32. package/dist/types/dist/module/src/Init.d.ts +2 -0
  33. package/dist/types/src/build-tests.d.ts +1 -0
  34. package/dist/types/src/defaultConfig.d.ts +3 -0
  35. package/dist/types/src/init-docs.d.ts +1 -0
  36. package/dist/types/src/run-tests.d.ts +1 -0
  37. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  38. package/package.json +10 -13
  39. package/src/Init.ts +28 -0
  40. package/src/PM/main.ts +58 -10
  41. package/src/Project.ts +102 -0
  42. package/src/Puppeteer.ts +1 -1
  43. package/src/build-tests.ts +12 -0
  44. package/src/defaultConfig.ts +20 -0
  45. package/src/esbuildConfigs/inputFilesPlugin.ts +48 -16
  46. package/src/init-docs.ts +19 -0
  47. package/src/lib/abstractBase.ts +0 -67
  48. package/src/lib/core.ts +3 -3
  49. package/src/run-tests.ts +12 -0
  50. package/tsconfig.json +1 -1
  51. package/build-tests.ts +0 -16
  52. package/dist/common/init-docs.js +0 -8
  53. package/dist/module/build-tests.js +0 -10
  54. package/dist/module/init-docs.js +0 -3
  55. package/dist/module/run-tests.js +0 -6
  56. package/dist/prebuild/Puppeteer.mjs +0 -82033
  57. package/dist/types/build-tests.d.ts +0 -3
  58. package/dist/types/init-docs.d.ts +0 -2
  59. package/dist/types/run-tests.d.ts +0 -2
  60. package/init-docs.ts +0 -5
  61. package/pupBuild.js +0 -18
  62. package/run-tests.ts +0 -9
@@ -0,0 +1,907 @@
1
+ import { createRequire } from 'module';const require = createRequire(import.meta.url);
2
+
3
+ // src/Puppeteer.ts
4
+ import readline from "readline";
5
+ import fs2 from "fs";
6
+ import watch from "recursive-watch";
7
+
8
+ // src/PM/main.ts
9
+ import fs from "fs";
10
+ import path2 from "path";
11
+ import puppeteer from "puppeteer-core";
12
+ import crypto from "crypto";
13
+
14
+ // src/PM/index.ts
15
+ var PM = class {
16
+ };
17
+
18
+ // src/utils.ts
19
+ import path from "path";
20
+ var destinationOfRuntime = (f, r, configs) => {
21
+ return path.normalize(`${configs.buildDir}/${r}/${f}`).split(".").slice(0, -1).join(".");
22
+ };
23
+
24
+ // src/PM/main.ts
25
+ var fileStreams3 = [];
26
+ var fPaths = [];
27
+ var files = {};
28
+ var screenshots = {};
29
+ var PM_Main = class extends PM {
30
+ constructor(configs) {
31
+ super();
32
+ this.shutdownMode = false;
33
+ this.checkForShutdown = () => {
34
+ const anyRunning = Object.values(this.registry).filter((x) => x === false).length > 0;
35
+ if (anyRunning) {
36
+ } else {
37
+ this.browser.disconnect().then(() => {
38
+ console.log("Goodbye");
39
+ process.exit();
40
+ });
41
+ }
42
+ };
43
+ this.register = (src) => {
44
+ this.registry[src] = false;
45
+ };
46
+ this.deregister = (src) => {
47
+ this.registry[src] = true;
48
+ if (this.shutdownMode) {
49
+ this.checkForShutdown();
50
+ }
51
+ };
52
+ this.launchNode = async (src, dest) => {
53
+ console.log("launchNode", src);
54
+ this.register(src);
55
+ const destFolder = dest.replace(".mjs", "");
56
+ let argz = "";
57
+ const testConfig = this.configs.tests.find((t) => {
58
+ return t[0] === src;
59
+ });
60
+ if (!testConfig) {
61
+ console.error("missing test config");
62
+ process.exit(-1);
63
+ }
64
+ const testConfigResource = testConfig[2];
65
+ let portsToUse = [];
66
+ if (testConfigResource.ports === 0) {
67
+ argz = JSON.stringify({
68
+ scheduled: true,
69
+ name: src,
70
+ ports: portsToUse,
71
+ fs: destFolder,
72
+ browserWSEndpoint: this.browser.wsEndpoint()
73
+ });
74
+ } else if (testConfigResource.ports > 0) {
75
+ const openPorts = Object.entries(this.ports).filter(
76
+ ([portnumber, portopen]) => portopen
77
+ );
78
+ if (openPorts.length >= testConfigResource.ports) {
79
+ for (let i = 0; i < testConfigResource.ports; i++) {
80
+ portsToUse.push(openPorts[i][0]);
81
+ this.ports[openPorts[i][0]] = false;
82
+ }
83
+ argz = JSON.stringify({
84
+ scheduled: true,
85
+ name: src,
86
+ // ports: [3333],
87
+ ports: portsToUse,
88
+ fs: destFolder,
89
+ browserWSEndpoint: this.browser.wsEndpoint()
90
+ });
91
+ } else {
92
+ this.queue.push(src);
93
+ return;
94
+ }
95
+ } else {
96
+ console.error("negative port makes no sense", src);
97
+ process.exit(-1);
98
+ }
99
+ const builtfile = dest + ".mjs";
100
+ await Promise.all(
101
+ testConfig[3].map((sidecar) => {
102
+ if (sidecar[1] === "web") {
103
+ return this.launchWebSideCar(
104
+ sidecar[0],
105
+ destinationOfRuntime(sidecar[0], "web", this.configs),
106
+ sidecar
107
+ );
108
+ }
109
+ if (sidecar[1] === "node") {
110
+ return this.launchNodeSideCar(
111
+ sidecar[0],
112
+ destinationOfRuntime(sidecar[0], "node", this.configs),
113
+ sidecar
114
+ );
115
+ }
116
+ })
117
+ );
118
+ this.server[builtfile] = await import(`${builtfile}?cacheBust=${Date.now()}`).then((module) => {
119
+ return module.default.then((defaultModule) => {
120
+ defaultModule.receiveTestResourceConfig(argz).then(async (features) => {
121
+ this.receiveFeatures(features, destFolder);
122
+ }).catch((e) => {
123
+ console.log("catch", e);
124
+ }).finally(() => {
125
+ this.deregister(src);
126
+ });
127
+ });
128
+ });
129
+ for (let i = 0; i <= portsToUse.length; i++) {
130
+ if (portsToUse[i]) {
131
+ this.ports[portsToUse[i]] = "true";
132
+ }
133
+ }
134
+ };
135
+ this.launchWebSideCar = async (src, dest, testConfig) => {
136
+ const d = dest + ".mjs";
137
+ console.log("launchWebSideCar", src, dest, d);
138
+ const destFolder = dest.replace(".mjs", "");
139
+ const webArgz = JSON.stringify({
140
+ name: dest,
141
+ ports: [].toString(),
142
+ fs: destFolder,
143
+ browserWSEndpoint: this.browser.wsEndpoint()
144
+ });
145
+ const fileStreams2 = [];
146
+ const doneFileStream2 = [];
147
+ return new Promise((res, rej) => {
148
+ this.browser.newPage().then((page) => {
149
+ page.exposeFunction(
150
+ "custom-screenshot",
151
+ async (ssOpts, testName) => {
152
+ const p = ssOpts.path;
153
+ const dir = path2.dirname(p);
154
+ fs.mkdirSync(dir, {
155
+ recursive: true
156
+ });
157
+ files[testName].add(ssOpts.path);
158
+ const sPromise = page.screenshot({
159
+ ...ssOpts,
160
+ path: p
161
+ });
162
+ if (!screenshots[testName]) {
163
+ screenshots[testName] = [];
164
+ }
165
+ screenshots[testName].push(sPromise);
166
+ await sPromise;
167
+ return sPromise;
168
+ }
169
+ );
170
+ page.exposeFunction(
171
+ "writeFileSync",
172
+ (fp, contents, testName) => {
173
+ const dir = path2.dirname(fp);
174
+ fs.mkdirSync(dir, {
175
+ recursive: true
176
+ });
177
+ const p = new Promise(async (res2, rej2) => {
178
+ fs.writeFileSync(fp, contents);
179
+ res2(fp);
180
+ });
181
+ doneFileStream2.push(p);
182
+ if (!files[testName]) {
183
+ files[testName] = /* @__PURE__ */ new Set();
184
+ }
185
+ files[testName].add(fp);
186
+ return p;
187
+ }
188
+ );
189
+ page.exposeFunction("existsSync", (fp, contents) => {
190
+ return fs.existsSync(fp);
191
+ });
192
+ page.exposeFunction("mkdirSync", (fp) => {
193
+ if (!fs.existsSync(fp)) {
194
+ return fs.mkdirSync(fp, {
195
+ recursive: true
196
+ });
197
+ }
198
+ return false;
199
+ });
200
+ page.exposeFunction(
201
+ "createWriteStream",
202
+ (fp, testName) => {
203
+ const f = fs.createWriteStream(fp);
204
+ files[testName].add(fp);
205
+ const p = new Promise((res2, rej2) => {
206
+ res2(fp);
207
+ });
208
+ doneFileStream2.push(p);
209
+ f.on("close", async () => {
210
+ await p;
211
+ });
212
+ fileStreams2.push(f);
213
+ return {
214
+ ...JSON.parse(JSON.stringify(f)),
215
+ uid: fileStreams2.length - 1
216
+ };
217
+ }
218
+ );
219
+ page.exposeFunction(
220
+ "write",
221
+ async (uid, contents) => {
222
+ return fileStreams2[uid].write(contents);
223
+ }
224
+ );
225
+ page.exposeFunction("end", async (uid) => {
226
+ return fileStreams2[uid].end();
227
+ });
228
+ page.exposeFunction("customclose", (p, testName) => {
229
+ fs.writeFileSync(
230
+ p + "/manifest.json",
231
+ JSON.stringify(Array.from(files[testName]))
232
+ );
233
+ delete files[testName];
234
+ Promise.all(screenshots[testName] || []).then(() => {
235
+ delete screenshots[testName];
236
+ });
237
+ });
238
+ return page;
239
+ }).then(async (page) => {
240
+ await page.goto(`file://${`${dest}.html`}`, {});
241
+ res(page);
242
+ });
243
+ });
244
+ };
245
+ this.launchNodeSideCar = async (src, dest, testConfig) => {
246
+ const d = dest + ".mjs";
247
+ console.log("launchNodeSideCar", src, dest, d);
248
+ const destFolder = dest.replace(".mjs", "");
249
+ let argz = "";
250
+ const testConfigResource = testConfig[2];
251
+ let portsToUse = [];
252
+ if (testConfigResource.ports === 0) {
253
+ argz = JSON.stringify({
254
+ scheduled: true,
255
+ name: src,
256
+ ports: portsToUse,
257
+ fs: destFolder,
258
+ browserWSEndpoint: this.browser.wsEndpoint()
259
+ });
260
+ } else if (testConfigResource.ports > 0) {
261
+ const openPorts = Object.entries(this.ports).filter(
262
+ ([portnumber, portopen]) => portopen
263
+ );
264
+ if (openPorts.length >= testConfigResource.ports) {
265
+ for (let i = 0; i < testConfigResource.ports; i++) {
266
+ portsToUse.push(openPorts[i][0]);
267
+ this.ports[openPorts[i][0]] = false;
268
+ }
269
+ argz = JSON.stringify({
270
+ scheduled: true,
271
+ name: src,
272
+ // ports: [3333],
273
+ ports: portsToUse,
274
+ fs: ".",
275
+ browserWSEndpoint: this.browser.wsEndpoint()
276
+ });
277
+ } else {
278
+ this.queue.push(src);
279
+ return;
280
+ }
281
+ } else {
282
+ console.error("negative port makes no sense", src);
283
+ process.exit(-1);
284
+ }
285
+ const builtfile = dest + ".mjs";
286
+ this.server[builtfile] = await import(`${builtfile}?cacheBust=${Date.now()}`).then((module) => {
287
+ return module.default.then((defaultModule) => {
288
+ const s = new defaultModule();
289
+ s.receiveTestResourceConfig(argz);
290
+ });
291
+ });
292
+ for (let i = 0; i <= portsToUse.length; i++) {
293
+ if (portsToUse[i]) {
294
+ this.ports[portsToUse[i]] = "true";
295
+ }
296
+ }
297
+ };
298
+ this.launchWeb = (t, dest, sidecars) => {
299
+ console.log("launchWeb", t, dest);
300
+ this.register(t);
301
+ sidecars.map((sidecar) => {
302
+ if (sidecar[1] === "node") {
303
+ return this.launchNodeSideCar(
304
+ sidecar[0],
305
+ destinationOfRuntime(sidecar[0], "node", this.configs),
306
+ sidecar
307
+ );
308
+ }
309
+ });
310
+ const destFolder = dest.replace(".mjs", "");
311
+ const webArgz = JSON.stringify({
312
+ name: dest,
313
+ ports: [].toString(),
314
+ fs: destFolder,
315
+ browserWSEndpoint: this.browser.wsEndpoint()
316
+ });
317
+ const evaluation = `
318
+ console.log("importing ${dest}.mjs");
319
+ import('${dest}.mjs').then(async (x) => {
320
+ console.log("imported", (await x.default));
321
+ try {
322
+ return await (await x.default).receiveTestResourceConfig(${webArgz})
323
+ } catch (e) {
324
+ console.log("fail", e)
325
+ }
326
+ })`;
327
+ const fileStreams2 = [];
328
+ const doneFileStream2 = [];
329
+ const stdoutStream = fs.createWriteStream(`${dest}/stdout.log`);
330
+ const stderrStream = fs.createWriteStream(`${dest}/stderr.log`);
331
+ this.browser.newPage().then((page) => {
332
+ page.exposeFunction(
333
+ "screencast",
334
+ async (ssOpts, testName) => {
335
+ const p = ssOpts.path;
336
+ const dir = path2.dirname(p);
337
+ fs.mkdirSync(dir, {
338
+ recursive: true
339
+ });
340
+ if (!files[testName]) {
341
+ files[testName] = /* @__PURE__ */ new Set();
342
+ }
343
+ files[testName].add(ssOpts.path);
344
+ const sPromise = page.screenshot({
345
+ ...ssOpts,
346
+ path: p
347
+ });
348
+ if (!screenshots[testName]) {
349
+ screenshots[testName] = [];
350
+ }
351
+ screenshots[testName].push(sPromise);
352
+ await sPromise;
353
+ return sPromise;
354
+ }
355
+ );
356
+ page.exposeFunction(
357
+ "customScreenShot",
358
+ async (ssOpts, testName) => {
359
+ const p = ssOpts.path;
360
+ const dir = path2.dirname(p);
361
+ fs.mkdirSync(dir, {
362
+ recursive: true
363
+ });
364
+ if (!files[testName]) {
365
+ files[testName] = /* @__PURE__ */ new Set();
366
+ }
367
+ files[testName].add(ssOpts.path);
368
+ const sPromise = page.screenshot({
369
+ ...ssOpts,
370
+ path: p
371
+ });
372
+ if (!screenshots[testName]) {
373
+ screenshots[testName] = [];
374
+ }
375
+ screenshots[testName].push(sPromise);
376
+ await sPromise;
377
+ return sPromise;
378
+ }
379
+ );
380
+ page.exposeFunction(
381
+ "writeFileSync",
382
+ (fp, contents, testName) => {
383
+ const dir = path2.dirname(fp);
384
+ fs.mkdirSync(dir, {
385
+ recursive: true
386
+ });
387
+ const p = new Promise(async (res, rej) => {
388
+ fs.writeFileSync(fp, contents);
389
+ res(fp);
390
+ });
391
+ doneFileStream2.push(p);
392
+ if (!files[testName]) {
393
+ files[testName] = /* @__PURE__ */ new Set();
394
+ }
395
+ files[testName].add(fp);
396
+ return p;
397
+ }
398
+ );
399
+ page.exposeFunction("existsSync", (fp, contents) => {
400
+ return fs.existsSync(fp);
401
+ });
402
+ page.exposeFunction("mkdirSync", (fp) => {
403
+ if (!fs.existsSync(fp)) {
404
+ return fs.mkdirSync(fp, {
405
+ recursive: true
406
+ });
407
+ }
408
+ return false;
409
+ });
410
+ page.exposeFunction(
411
+ "createWriteStream",
412
+ (fp, testName) => {
413
+ const f = fs.createWriteStream(fp);
414
+ if (!files[testName]) {
415
+ files[testName] = /* @__PURE__ */ new Set();
416
+ }
417
+ files[testName].add(fp);
418
+ const p = new Promise((res, rej) => {
419
+ res(fp);
420
+ });
421
+ doneFileStream2.push(p);
422
+ f.on("close", async () => {
423
+ await p;
424
+ });
425
+ fileStreams2.push(f);
426
+ return {
427
+ ...JSON.parse(JSON.stringify(f)),
428
+ uid: fileStreams2.length - 1
429
+ };
430
+ }
431
+ );
432
+ page.exposeFunction("write", async (uid, contents) => {
433
+ return fileStreams2[uid].write(contents);
434
+ });
435
+ page.exposeFunction("end", async (uid) => {
436
+ return fileStreams2[uid].end();
437
+ });
438
+ page.exposeFunction("customclose", (p, testName) => {
439
+ fs.writeFileSync(
440
+ p + "/manifest.json",
441
+ JSON.stringify(Array.from(files[testName]))
442
+ );
443
+ delete files[testName];
444
+ Promise.all(screenshots[testName] || []).then(() => {
445
+ delete screenshots[testName];
446
+ });
447
+ });
448
+ page.exposeFunction("page", () => {
449
+ return page.mainFrame()._id;
450
+ });
451
+ page.exposeFunction("click", (sel) => {
452
+ return page.click(sel);
453
+ });
454
+ page.exposeFunction("focusOn", (sel) => {
455
+ return page.focus(sel);
456
+ });
457
+ page.exposeFunction(
458
+ "typeInto",
459
+ async (value) => await page.keyboard.type(value)
460
+ );
461
+ page.exposeFunction(
462
+ "getValue",
463
+ (selector) => page.$eval(selector, (input) => input.getAttribute("value"))
464
+ );
465
+ page.exposeFunction(
466
+ "getAttribute",
467
+ async (selector, attribute) => {
468
+ const attributeValue = await page.$eval(selector, (input) => {
469
+ return input.getAttribute(attribute);
470
+ });
471
+ return attributeValue;
472
+ }
473
+ );
474
+ page.exposeFunction("isDisabled", async (selector) => {
475
+ const attributeValue = await page.$eval(
476
+ selector,
477
+ (input) => {
478
+ return input.disabled;
479
+ }
480
+ );
481
+ return attributeValue;
482
+ });
483
+ page.exposeFunction("$", async (selector) => {
484
+ const x = page.$(selector);
485
+ const y = await x;
486
+ return y;
487
+ });
488
+ return page;
489
+ }).then(async (page) => {
490
+ const close = () => {
491
+ console.log("evaluation complete.", dest);
492
+ page.off("pageerror");
493
+ page.close();
494
+ this.deregister(t);
495
+ stderrStream.close();
496
+ stdoutStream.close();
497
+ };
498
+ page.on("pageerror", (err) => {
499
+ console.debug(`Error from ${t}: [${err.name}] `);
500
+ stderrStream.write(err.name);
501
+ if (err.cause) {
502
+ console.debug(`Error from ${t} cause: [${err.cause}] `);
503
+ stderrStream.write(err.cause);
504
+ }
505
+ if (err.stack) {
506
+ console.debug(`Error from stack ${t}: [${err.stack}] `);
507
+ stderrStream.write(err.stack);
508
+ }
509
+ console.debug(`Error from message ${t}: [${err.message}] `);
510
+ stderrStream.write(err.message);
511
+ });
512
+ page.on("console", (log) => {
513
+ stdoutStream.write(log.text());
514
+ stdoutStream.write(JSON.stringify(log.location()));
515
+ stdoutStream.write(JSON.stringify(log.stackTrace()));
516
+ });
517
+ await page.goto(`file://${`${dest}.html`}`, {});
518
+ await page.evaluate(evaluation).then(async (features) => {
519
+ this.receiveFeatures(features, destFolder);
520
+ }).catch((e) => {
521
+ console.log("evaluation failed.", dest);
522
+ console.log(e);
523
+ }).finally(() => {
524
+ close();
525
+ });
526
+ return page;
527
+ });
528
+ };
529
+ this.receiveFeatures = (features, destFolder) => {
530
+ console.log("this.receiveFeatures", features);
531
+ features.reduce(async (mm, featureStringKey) => {
532
+ const accum = await mm;
533
+ const isUrl = isValidUrl(featureStringKey);
534
+ if (isUrl) {
535
+ const u = new URL(featureStringKey);
536
+ if (u.protocol === "file:") {
537
+ const newPath = `${process.cwd()}/docs/features/internal/${path2.relative(
538
+ process.cwd(),
539
+ u.pathname
540
+ )}`;
541
+ await fs.promises.mkdir(path2.dirname(newPath), { recursive: true });
542
+ try {
543
+ await fs.unlinkSync(newPath);
544
+ } catch (error) {
545
+ if (error.code !== "ENOENT") {
546
+ }
547
+ }
548
+ fs.symlink(u.pathname, newPath, (err) => {
549
+ if (err) {
550
+ } else {
551
+ }
552
+ });
553
+ accum.push(newPath);
554
+ } else if (u.protocol === "http:" || u.protocol === "https:") {
555
+ const newPath = `${process.cwd()}/docs/features/external${u.hostname}${u.pathname}`;
556
+ const body = await this.configs.featureIngestor(featureStringKey);
557
+ writeFileAndCreateDir(newPath, body);
558
+ accum.push(newPath);
559
+ }
560
+ } else {
561
+ const newPath = `${process.cwd()}/docs/features/plain/${await sha256(
562
+ featureStringKey
563
+ )}`;
564
+ writeFileAndCreateDir(newPath, featureStringKey);
565
+ accum.push(newPath);
566
+ }
567
+ return accum;
568
+ }, Promise.resolve([])).then((features2) => {
569
+ fs.writeFileSync(
570
+ `${destFolder}/featurePrompt.txt`,
571
+ features2.map((f) => {
572
+ return `/read ${f}`;
573
+ }).join("\n")
574
+ );
575
+ });
576
+ };
577
+ this.server = {};
578
+ this.configs = configs;
579
+ this.ports = {};
580
+ this.registry = {};
581
+ this.configs.ports.forEach((element) => {
582
+ this.ports[element] = "true";
583
+ });
584
+ globalThis["mkdirSync"] = (fp) => {
585
+ if (!fs.existsSync(fp)) {
586
+ return fs.mkdirSync(fp, {
587
+ recursive: true
588
+ });
589
+ }
590
+ return false;
591
+ };
592
+ globalThis["writeFileSync"] = (filepath, contents, testName) => {
593
+ const dir = path2.dirname(filepath.split("/").slice(0, -1).join("/"));
594
+ fs.mkdirSync(dir, {
595
+ recursive: true
596
+ });
597
+ if (!files[testName]) {
598
+ files[testName] = /* @__PURE__ */ new Set();
599
+ }
600
+ files[testName].add(filepath);
601
+ return fs.writeFileSync(filepath, contents);
602
+ };
603
+ globalThis["createWriteStream"] = (filepath, testName) => {
604
+ const f = fs.createWriteStream(filepath);
605
+ fileStreams3.push(f);
606
+ if (!files[testName]) {
607
+ files[testName] = /* @__PURE__ */ new Set();
608
+ }
609
+ files[testName].add(filepath);
610
+ return {
611
+ ...JSON.parse(JSON.stringify(f)),
612
+ uid: fileStreams3.length - 1
613
+ };
614
+ };
615
+ globalThis["write"] = (uid, contents) => {
616
+ fileStreams3[uid].write(contents);
617
+ };
618
+ globalThis["end"] = (uid) => {
619
+ fileStreams3[uid].end();
620
+ };
621
+ globalThis["customScreenShot"] = async (opts, page) => {
622
+ const p = opts.path;
623
+ const dir = path2.dirname(p);
624
+ fs.mkdirSync(dir, {
625
+ recursive: true
626
+ });
627
+ if (!files[opts.path]) {
628
+ files[opts.path] = /* @__PURE__ */ new Set();
629
+ }
630
+ files[opts.path].add(opts.path);
631
+ const sPromise = page.screenshot({
632
+ ...opts,
633
+ path: p
634
+ });
635
+ if (!screenshots[opts.path]) {
636
+ screenshots[opts.path] = [];
637
+ }
638
+ screenshots[opts.path].push(sPromise);
639
+ await sPromise;
640
+ return sPromise;
641
+ };
642
+ globalThis["customclose"] = (p, testName) => {
643
+ if (!files[testName]) {
644
+ files[testName] = /* @__PURE__ */ new Set();
645
+ }
646
+ fs.writeFileSync(
647
+ p + "/manifest.json",
648
+ JSON.stringify(Array.from(files[testName]))
649
+ );
650
+ delete files[testName];
651
+ };
652
+ }
653
+ $(selector) {
654
+ throw new Error("Method not implemented.");
655
+ }
656
+ screencast(opts) {
657
+ throw new Error("Method not implemented.");
658
+ }
659
+ customScreenShot(opts) {
660
+ throw new Error("Method not implemented.");
661
+ }
662
+ end(accessObject) {
663
+ throw new Error("Method not implemented.");
664
+ }
665
+ existsSync(destFolder) {
666
+ return fs.existsSync(destFolder);
667
+ }
668
+ async mkdirSync(fp) {
669
+ if (!fs.existsSync(fp)) {
670
+ return fs.mkdirSync(fp, {
671
+ recursive: true
672
+ });
673
+ }
674
+ return false;
675
+ }
676
+ writeFileSync(fp, contents) {
677
+ fs.writeFileSync(fp, contents);
678
+ }
679
+ createWriteStream(filepath) {
680
+ return fs.createWriteStream(filepath);
681
+ }
682
+ testArtiFactoryfileWriter(tLog, callback) {
683
+ return (fPath, value) => {
684
+ callback(
685
+ new Promise((res, rej) => {
686
+ tLog("testArtiFactory =>", fPath);
687
+ const cleanPath = path2.resolve(fPath);
688
+ fPaths.push(cleanPath.replace(process.cwd(), ``));
689
+ const targetDir = cleanPath.split("/").slice(0, -1).join("/");
690
+ fs.mkdir(targetDir, { recursive: true }, async (error) => {
691
+ if (error) {
692
+ console.error(`\u2757\uFE0FtestArtiFactory failed`, targetDir, error);
693
+ }
694
+ fs.writeFileSync(
695
+ path2.resolve(
696
+ targetDir.split("/").slice(0, -1).join("/"),
697
+ "manifest"
698
+ ),
699
+ fPaths.join(`
700
+ `),
701
+ {
702
+ encoding: "utf-8"
703
+ }
704
+ );
705
+ if (Buffer.isBuffer(value)) {
706
+ fs.writeFileSync(fPath, value, "binary");
707
+ res();
708
+ } else if (`string` === typeof value) {
709
+ fs.writeFileSync(fPath, value.toString(), {
710
+ encoding: "utf-8"
711
+ });
712
+ res();
713
+ } else {
714
+ const pipeStream = value;
715
+ const myFile = fs.createWriteStream(fPath);
716
+ pipeStream.pipe(myFile);
717
+ pipeStream.on("close", () => {
718
+ myFile.close();
719
+ res();
720
+ });
721
+ }
722
+ });
723
+ })
724
+ );
725
+ };
726
+ }
727
+ write(accessObject, contents) {
728
+ throw new Error("Method not implemented.");
729
+ }
730
+ page() {
731
+ throw new Error("Method not implemented.");
732
+ }
733
+ click(selector) {
734
+ throw new Error("Method not implemented.");
735
+ }
736
+ focusOn(selector) {
737
+ throw new Error("Method not implemented.");
738
+ }
739
+ typeInto(value) {
740
+ throw new Error("Method not implemented.");
741
+ }
742
+ getValue(value) {
743
+ throw new Error("Method not implemented.");
744
+ }
745
+ getAttribute(selector, attribute) {
746
+ throw new Error("Method not implemented.");
747
+ }
748
+ isDisabled(selector) {
749
+ throw new Error("Method not implemented.");
750
+ }
751
+ ////////////////////////////////////////////////////////////////////////////////
752
+ async startPuppeteer(options, destfolder) {
753
+ this.browser = await puppeteer.launch(options);
754
+ }
755
+ ////////////////////////////////////////////////////////////////////////////////
756
+ shutDown() {
757
+ console.log("shutting down...");
758
+ this.shutdownMode = true;
759
+ this.checkForShutdown();
760
+ }
761
+ };
762
+ async function writeFileAndCreateDir(filePath, data) {
763
+ const dirPath = path2.dirname(filePath);
764
+ try {
765
+ await fs.promises.mkdir(dirPath, { recursive: true });
766
+ await fs.promises.writeFile(filePath, data);
767
+ } catch (error) {
768
+ console.error(`Error writing file: ${error}`);
769
+ }
770
+ }
771
+ async function sha256(rawData) {
772
+ const data = typeof rawData === "object" ? JSON.stringify(rawData) : String(rawData);
773
+ const msgBuffer = new TextEncoder().encode(data);
774
+ const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer);
775
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
776
+ return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
777
+ }
778
+ function isValidUrl(string) {
779
+ try {
780
+ new URL(string);
781
+ return true;
782
+ } catch (err) {
783
+ return false;
784
+ }
785
+ }
786
+
787
+ // src/Puppeteer.ts
788
+ readline.emitKeypressEvents(process.stdin);
789
+ if (process.stdin.isTTY)
790
+ process.stdin.setRawMode(true);
791
+ var Puppeteer_default = async (partialConfig) => {
792
+ const config = {
793
+ ...partialConfig,
794
+ buildDir: process.cwd() + "/" + partialConfig.outdir
795
+ };
796
+ fs2.writeFileSync(
797
+ `${config.outdir}/testeranto.json`,
798
+ JSON.stringify(
799
+ {
800
+ ...config,
801
+ buildDir: process.cwd() + "/" + config.outdir
802
+ },
803
+ null,
804
+ 2
805
+ )
806
+ );
807
+ const pm = new PM_Main(config);
808
+ await pm.startPuppeteer(
809
+ {
810
+ // timeout: 1,
811
+ waitForInitialPage: false,
812
+ executablePath: (
813
+ // process.env.CHROMIUM_PATH || "/opt/homebrew/bin/chromium",
814
+ "/opt/homebrew/bin/chromium"
815
+ ),
816
+ headless: false,
817
+ dumpio: true,
818
+ // timeout: 0,
819
+ devtools: true,
820
+ args: [
821
+ "--auto-open-devtools-for-tabs",
822
+ `--remote-debugging-port=3234`,
823
+ // "--disable-features=IsolateOrigins,site-per-process",
824
+ "--disable-site-isolation-trials",
825
+ "--allow-insecure-localhost",
826
+ "--allow-file-access-from-files",
827
+ "--allow-running-insecure-content",
828
+ "--disable-dev-shm-usage",
829
+ "--disable-extensions",
830
+ "--disable-gpu",
831
+ "--disable-setuid-sandbox",
832
+ "--disable-site-isolation-trials",
833
+ "--disable-web-security",
834
+ "--no-first-run",
835
+ "--no-sandbox",
836
+ "--no-startup-window",
837
+ // "--no-zygote",
838
+ "--reduce-security-for-testing",
839
+ "--remote-allow-origins=*",
840
+ "--unsafely-treat-insecure-origin-as-secure=*"
841
+ // "--disable-features=IsolateOrigins",
842
+ // "--remote-allow-origins=ws://localhost:3234",
843
+ // "--single-process",
844
+ // "--unsafely-treat-insecure-origin-as-secure",
845
+ // "--unsafely-treat-insecure-origin-as-secure=ws://192.168.0.101:3234",
846
+ // "--disk-cache-dir=/dev/null",
847
+ // "--disk-cache-size=1",
848
+ // "--start-maximized",
849
+ ]
850
+ },
851
+ "."
852
+ );
853
+ console.log(
854
+ "\n Puppeteer is running. Press 'q' to shutdown softly. Press 'x' to shutdown forcefully.\n"
855
+ );
856
+ process.stdin.on("keypress", (str, key) => {
857
+ if (key.name === "q") {
858
+ pm.shutDown();
859
+ }
860
+ if (key.name === "x") {
861
+ process.exit(-1);
862
+ }
863
+ });
864
+ config.tests.forEach(([test, runtime, tr, sidecars]) => {
865
+ if (runtime === "node") {
866
+ pm.launchNode(test, destinationOfRuntime(test, "node", config));
867
+ } else if (runtime === "web") {
868
+ pm.launchWeb(test, destinationOfRuntime(test, "web", config), sidecars);
869
+ } else {
870
+ console.error("runtime makes no sense", runtime);
871
+ }
872
+ });
873
+ if (config.devMode) {
874
+ console.log("ready and watching for changes...", config.buildDir);
875
+ watch(config.buildDir, (eventType, changedFile) => {
876
+ if (changedFile) {
877
+ config.tests.forEach(([test, runtime, tr, sidecars]) => {
878
+ if (eventType === "change" || eventType === "rename") {
879
+ if (changedFile === test.replace("./", "node/").split(".").slice(0, -1).concat("mjs").join(".")) {
880
+ pm.launchNode(test, destinationOfRuntime(test, "node", config));
881
+ }
882
+ if (changedFile === test.replace("./", "web/").split(".").slice(0, -1).concat("mjs").join(".")) {
883
+ pm.launchWeb(
884
+ test,
885
+ destinationOfRuntime(test, "web", config),
886
+ sidecars
887
+ );
888
+ }
889
+ }
890
+ });
891
+ }
892
+ });
893
+ } else {
894
+ pm.shutDown();
895
+ }
896
+ };
897
+
898
+ // src/run-tests.ts
899
+ import process2 from "process";
900
+ if (!process2.argv[2]) {
901
+ console.log("You didn't pass a config file");
902
+ process2.exit(-1);
903
+ } else {
904
+ import(process2.cwd() + "/" + process2.argv[2]).then((module) => {
905
+ Puppeteer_default(module.default);
906
+ });
907
+ }