testeranto 0.113.1 → 0.121.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 +6 -2
- package/bundle.js +1 -1
- package/dist/common/Init.js +55 -61
- package/dist/common/PM/base.js +233 -0
- package/dist/common/PM/main.js +217 -434
- package/dist/common/build.js +113 -92
- package/dist/common/defaultConfig.js +2 -2
- package/dist/common/esbuildConfigs/index.js +1 -1
- package/dist/common/esbuildConfigs/inputFilesPlugin.js +7 -3
- package/dist/common/esbuildConfigs/node.js +5 -3
- package/dist/common/esbuildConfigs/web.js +3 -3
- package/dist/common/init-docs.js +2 -46
- package/dist/common/lib/abstractBase.js +60 -54
- package/dist/common/lib/basebuilder.js +7 -8
- package/dist/common/lib/classBuilder.js +8 -5
- package/dist/common/lib/core.js +6 -18
- package/dist/common/lib/index.js +6 -1
- package/dist/common/run.js +10 -2
- package/dist/common/tsconfig.common.tsbuildinfo +1 -1
- package/dist/common/utils.js +9 -21
- package/dist/module/Init.js +55 -61
- package/dist/module/PM/base.js +226 -0
- package/dist/module/PM/main.js +218 -435
- package/dist/module/Project.js +117 -0
- package/dist/module/TestReport.js +13 -4
- package/dist/module/build.js +113 -92
- package/dist/module/defaultConfig.js +2 -2
- package/dist/module/esbuildConfigs/index.js +1 -1
- package/dist/module/esbuildConfigs/inputFilesPlugin.js +7 -3
- package/dist/module/esbuildConfigs/node.js +5 -3
- package/dist/module/esbuildConfigs/web.js +3 -3
- package/dist/module/init-docs.js +2 -13
- package/dist/module/lib/abstractBase.js +60 -54
- package/dist/module/lib/basebuilder.js +7 -8
- package/dist/module/lib/classBuilder.js +8 -5
- package/dist/module/lib/core.js +6 -18
- package/dist/module/lib/index.js +6 -1
- package/dist/module/run.js +10 -2
- package/dist/module/tsconfig.module.tsbuildinfo +1 -1
- package/dist/module/utils.js +8 -17
- package/dist/prebuild/Project.css +11367 -0
- package/dist/prebuild/Project.js +24640 -0
- package/dist/prebuild/ReportClient.js +1 -1
- package/dist/prebuild/TestReport.js +9 -11
- package/dist/prebuild/build.mjs +142 -81
- package/dist/prebuild/init-docs.mjs +28 -83
- package/dist/prebuild/run.mjs +618 -537
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/Init.d.ts +1 -1
- package/dist/types/PM/base.d.ts +38 -0
- package/dist/types/PM/main.d.ts +20 -44
- package/dist/types/esbuildConfigs/inputFilesPlugin.d.ts +1 -1
- package/dist/types/esbuildConfigs/node.d.ts +1 -1
- package/dist/types/esbuildConfigs/web.d.ts +1 -1
- package/dist/types/lib/abstractBase.d.ts +19 -11
- package/dist/types/lib/basebuilder.d.ts +1 -2
- package/dist/types/lib/index.d.ts +3 -3
- package/dist/types/lib/types.d.ts +2 -5
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/types/utils.d.ts +4 -7
- package/package.json +7 -6
- package/src/Init.ts +60 -68
- package/src/PM/base.ts +301 -0
- package/src/PM/main.ts +276 -567
- package/src/Project.tsx +197 -0
- package/src/ReportClient.tsx +1 -1
- package/src/TestReport.tsx +30 -15
- package/src/build.ts +140 -104
- package/src/defaultConfig.ts +2 -2
- package/src/esbuildConfigs/index.ts +1 -1
- package/src/esbuildConfigs/inputFilesPlugin.ts +7 -6
- package/src/esbuildConfigs/node.ts +5 -3
- package/src/esbuildConfigs/web.ts +4 -3
- package/src/init-docs.ts +2 -15
- package/src/lib/abstractBase.ts +113 -93
- package/src/lib/basebuilder.ts +8 -9
- package/src/lib/classBuilder.ts +11 -10
- package/src/lib/core.ts +15 -27
- package/src/lib/index.ts +13 -6
- package/src/lib/types.ts +3 -8
- package/src/run.ts +21 -5
- package/src/utils.ts +27 -39
- package/tsc.log +12 -23
- package/dist/common/puppeteerConfiger.js +0 -24
- package/dist/module/puppeteerConfiger.js +0 -19
- package/dist/types/puppeteerConfiger.d.ts +0 -4
- package/src/puppeteerConfiger.ts +0 -26
package/src/PM/main.ts
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { Page } from "puppeteer-core/lib/esm/puppeteer";
|
|
4
4
|
import fs, { watch } from "fs";
|
|
5
5
|
import path from "path";
|
|
6
|
-
import puppeteer, {
|
|
7
|
-
Browser,
|
|
8
|
-
ConsoleMessage,
|
|
9
|
-
ScreenRecorder,
|
|
10
|
-
ScreenshotOptions,
|
|
11
|
-
} from "puppeteer-core";
|
|
12
|
-
import { PassThrough } from "stream";
|
|
6
|
+
import puppeteer, { ConsoleMessage, ScreenshotOptions } from "puppeteer-core";
|
|
13
7
|
import ansiC from "ansi-colors";
|
|
14
8
|
import crypto from "node:crypto";
|
|
15
9
|
import { ESLint } from "eslint";
|
|
@@ -19,11 +13,10 @@ import {
|
|
|
19
13
|
IFinalResults,
|
|
20
14
|
IRunnables,
|
|
21
15
|
ITestTypes,
|
|
22
|
-
ITLog,
|
|
23
16
|
} from "../lib/index.js";
|
|
24
|
-
import { ISummary, lintPather, tscPather } from "../utils";
|
|
17
|
+
import { ISummary, lintPather, promptPather, tscPather } from "../utils";
|
|
25
18
|
|
|
26
|
-
import {
|
|
19
|
+
import { PM_Base } from "./base.js";
|
|
27
20
|
|
|
28
21
|
type IOutputs = Record<
|
|
29
22
|
string,
|
|
@@ -38,11 +31,7 @@ const formatter = await eslint.loadFormatter(
|
|
|
38
31
|
);
|
|
39
32
|
const changes: Record<string, string> = {};
|
|
40
33
|
const fileHashes = {};
|
|
41
|
-
const fileStreams3: fs.WriteStream[] = [];
|
|
42
|
-
type IFPaths = string[];
|
|
43
|
-
const fPaths: IFPaths = [];
|
|
44
34
|
const files: Record<string, Set<string>> = {};
|
|
45
|
-
const recorders: Record<string, ScreenRecorder> = {};
|
|
46
35
|
const screenshots: Record<string, Promise<Uint8Array>[]> = {};
|
|
47
36
|
|
|
48
37
|
async function fileHash(filePath, algorithm = "md5") {
|
|
@@ -65,32 +54,6 @@ async function fileHash(filePath, algorithm = "md5") {
|
|
|
65
54
|
});
|
|
66
55
|
}
|
|
67
56
|
|
|
68
|
-
const getRunnables = (
|
|
69
|
-
tests: ITestTypes[],
|
|
70
|
-
payload = {
|
|
71
|
-
nodeEntryPoints: {},
|
|
72
|
-
webEntryPoints: {},
|
|
73
|
-
}
|
|
74
|
-
): IRunnables => {
|
|
75
|
-
return tests.reduce((pt, cv, cndx, cry) => {
|
|
76
|
-
if (cv[1] === "node") {
|
|
77
|
-
pt.nodeEntryPoints[cv[0]] = path.resolve(
|
|
78
|
-
`./docs/node/${cv[0].split(".").slice(0, -1).concat("mjs").join(".")}`
|
|
79
|
-
);
|
|
80
|
-
} else if (cv[1] === "web") {
|
|
81
|
-
pt.webEntryPoints[cv[0]] = path.resolve(
|
|
82
|
-
`./docs/web/${cv[0].split(".").slice(0, -1).concat("mjs").join(".")}`
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (cv[3].length) {
|
|
87
|
-
getRunnables(cv[3], payload);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return pt;
|
|
91
|
-
}, payload as IRunnables);
|
|
92
|
-
};
|
|
93
|
-
|
|
94
57
|
const statusMessagePretty = (failures: number, test: string) => {
|
|
95
58
|
if (failures === 0) {
|
|
96
59
|
console.log(ansiC.green(ansiC.inverse(`> ${test} completed successfully`)));
|
|
@@ -129,27 +92,20 @@ function isValidUrl(string) {
|
|
|
129
92
|
}
|
|
130
93
|
}
|
|
131
94
|
|
|
132
|
-
export class PM_Main extends
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
shutdownMode = false;
|
|
136
|
-
configs: IBuiltConfig;
|
|
95
|
+
export class PM_Main extends PM_Base {
|
|
96
|
+
name: string;
|
|
137
97
|
ports: Record<number, boolean>;
|
|
138
98
|
queue: any[];
|
|
139
|
-
|
|
140
|
-
mode: "DEV" | "PROD";
|
|
141
|
-
|
|
99
|
+
mode: "once" | "dev";
|
|
142
100
|
bigBoard: ISummary = {};
|
|
143
101
|
webMetafileWatcher: fs.FSWatcher;
|
|
144
102
|
nodeMetafileWatcher: fs.FSWatcher;
|
|
145
103
|
|
|
146
|
-
constructor(configs: IBuiltConfig) {
|
|
147
|
-
super();
|
|
148
|
-
|
|
149
|
-
this.mode = configs.devMode ? "DEV" : "PROD";
|
|
104
|
+
constructor(configs: IBuiltConfig, name: string, mode: "once" | "dev") {
|
|
105
|
+
super(configs);
|
|
150
106
|
|
|
151
|
-
this.
|
|
152
|
-
this.
|
|
107
|
+
this.name = name;
|
|
108
|
+
this.mode = mode;
|
|
153
109
|
this.ports = {};
|
|
154
110
|
|
|
155
111
|
this.configs.tests.forEach(([t]) => {
|
|
@@ -164,378 +120,56 @@ export class PM_Main extends PM {
|
|
|
164
120
|
this.configs.ports.forEach((element) => {
|
|
165
121
|
this.ports[element] = "true"; // set ports as open
|
|
166
122
|
});
|
|
167
|
-
|
|
168
|
-
globalThis["waitForSelector"] = async (pageKey: string, sel: string) => {
|
|
169
|
-
const page = (await this.browser.pages()).find(
|
|
170
|
-
/* @ts-ignore:next-line */
|
|
171
|
-
(p) => p.mainFrame()._id === pageKey
|
|
172
|
-
);
|
|
173
|
-
await page?.waitForSelector(sel);
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
globalThis["screencastStop"] = async (path: string) => {
|
|
177
|
-
return recorders[path].stop();
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
globalThis["closePage"] = async (pageKey) => {
|
|
181
|
-
const page = (await this.browser.pages()).find(
|
|
182
|
-
/* @ts-ignore:next-line */
|
|
183
|
-
(p) => p.mainFrame()._id === pageKey
|
|
184
|
-
);
|
|
185
|
-
/* @ts-ignore:next-line */
|
|
186
|
-
return page.close();
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
globalThis["goto"] = async (pageKey: string, url: string) => {
|
|
190
|
-
const page = (await this.browser.pages()).find(
|
|
191
|
-
/* @ts-ignore:next-line */
|
|
192
|
-
(p) => p.mainFrame()._id === pageKey
|
|
193
|
-
);
|
|
194
|
-
await page?.goto(url);
|
|
195
|
-
return;
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
globalThis["newPage"] = () => {
|
|
199
|
-
return this.browser.newPage();
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
globalThis["pages"] = () => {
|
|
203
|
-
return this.browser.pages();
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
globalThis["mkdirSync"] = (fp: string) => {
|
|
207
|
-
if (!fs.existsSync(fp)) {
|
|
208
|
-
return fs.mkdirSync(fp, {
|
|
209
|
-
recursive: true,
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
return false;
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
globalThis["writeFileSync"] = (
|
|
216
|
-
filepath: string,
|
|
217
|
-
contents: string,
|
|
218
|
-
testName: string
|
|
219
|
-
) => {
|
|
220
|
-
fs.mkdirSync(path.dirname(filepath), {
|
|
221
|
-
recursive: true,
|
|
222
|
-
});
|
|
223
|
-
if (!files[testName]) {
|
|
224
|
-
files[testName] = new Set();
|
|
225
|
-
}
|
|
226
|
-
files[testName].add(filepath);
|
|
227
|
-
return fs.writeFileSync(filepath, contents);
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
globalThis["createWriteStream"] = (filepath: string, testName: string) => {
|
|
231
|
-
const f = fs.createWriteStream(filepath);
|
|
232
|
-
fileStreams3.push(f);
|
|
233
|
-
// files.add(filepath);
|
|
234
|
-
if (!files[testName]) {
|
|
235
|
-
files[testName] = new Set();
|
|
236
|
-
}
|
|
237
|
-
files[testName].add(filepath);
|
|
238
|
-
return {
|
|
239
|
-
...JSON.parse(JSON.stringify(f)),
|
|
240
|
-
uid: fileStreams3.length - 1,
|
|
241
|
-
};
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
globalThis["write"] = (uid: number, contents: string) => {
|
|
245
|
-
fileStreams3[uid].write(contents);
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
globalThis["end"] = (uid: number) => {
|
|
249
|
-
fileStreams3[uid].end();
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
globalThis["customScreenShot"] = async (
|
|
253
|
-
opts: { path: string },
|
|
254
|
-
pageKey: string,
|
|
255
|
-
testName: string
|
|
256
|
-
) => {
|
|
257
|
-
const page = (await this.browser.pages()).find(
|
|
258
|
-
/* @ts-ignore:next-line */
|
|
259
|
-
(p) => p.mainFrame()._id === pageKey
|
|
260
|
-
);
|
|
261
|
-
|
|
262
|
-
const p = opts.path as string;
|
|
263
|
-
const dir = path.dirname(p);
|
|
264
|
-
fs.mkdirSync(dir, {
|
|
265
|
-
recursive: true,
|
|
266
|
-
});
|
|
267
|
-
if (!files[opts.path]) {
|
|
268
|
-
files[opts.path] = new Set();
|
|
269
|
-
}
|
|
270
|
-
files[opts.path].add(opts.path as string);
|
|
271
|
-
|
|
272
|
-
const sPromise = page.screenshot({
|
|
273
|
-
...opts,
|
|
274
|
-
path: p,
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
if (!screenshots[opts.path]) {
|
|
278
|
-
screenshots[opts.path] = [];
|
|
279
|
-
}
|
|
280
|
-
screenshots[opts.path].push(sPromise);
|
|
281
|
-
|
|
282
|
-
await sPromise;
|
|
283
|
-
return sPromise;
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
globalThis["screencast"] = async (
|
|
287
|
-
opts: ScreenshotOptions,
|
|
288
|
-
pageKey: string
|
|
289
|
-
) => {
|
|
290
|
-
const page = (await this.browser.pages()).find(
|
|
291
|
-
/* @ts-ignore:next-line */
|
|
292
|
-
(p) => p.mainFrame()._id === pageKey
|
|
293
|
-
);
|
|
294
|
-
|
|
295
|
-
const p = opts.path as string;
|
|
296
|
-
const dir = path.dirname(p);
|
|
297
|
-
fs.mkdirSync(dir, {
|
|
298
|
-
recursive: true,
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
const recorder = await page?.screencast({
|
|
302
|
-
...opts,
|
|
303
|
-
path: p,
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
recorders[opts.path] = recorder;
|
|
307
|
-
|
|
308
|
-
return opts.path;
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
stop = () => {
|
|
313
|
-
console.log(ansiC.inverse("Testeranto-Run is shutting down gracefully..."));
|
|
314
|
-
this.mode = "PROD";
|
|
315
|
-
this.nodeMetafileWatcher.close();
|
|
316
|
-
this.webMetafileWatcher.close();
|
|
317
|
-
this.checkForShutdown();
|
|
318
|
-
};
|
|
319
|
-
|
|
320
|
-
customclose() {
|
|
321
|
-
throw new Error("Method not implemented.");
|
|
322
|
-
}
|
|
323
|
-
waitForSelector(p: string, s: string): any {
|
|
324
|
-
throw new Error("Method not implemented.");
|
|
325
|
-
}
|
|
326
|
-
closePage(p): any {
|
|
327
|
-
throw new Error("Method not implemented.");
|
|
328
|
-
}
|
|
329
|
-
newPage(): CdpPage {
|
|
330
|
-
throw new Error("Method not implemented.");
|
|
331
|
-
}
|
|
332
|
-
goto(p, url: string): any {
|
|
333
|
-
throw new Error("Method not implemented.");
|
|
334
|
-
}
|
|
335
|
-
$(selector: string): boolean {
|
|
336
|
-
throw new Error("Method not implemented.");
|
|
337
|
-
}
|
|
338
|
-
screencast(opts: object) {
|
|
339
|
-
throw new Error("Method not implemented.");
|
|
340
|
-
}
|
|
341
|
-
customScreenShot(opts: object, cdpPage?: CdpPage) {
|
|
342
|
-
throw new Error("Method not implemented.");
|
|
343
|
-
}
|
|
344
|
-
end(accessObject: { uid: number }): boolean {
|
|
345
|
-
throw new Error("Method not implemented.");
|
|
346
|
-
}
|
|
347
|
-
existsSync(destFolder: string): boolean {
|
|
348
|
-
return fs.existsSync(destFolder);
|
|
349
123
|
}
|
|
350
124
|
|
|
351
|
-
async
|
|
352
|
-
if (!fs.existsSync(
|
|
353
|
-
|
|
354
|
-
recursive: true,
|
|
355
|
-
});
|
|
125
|
+
async start(): Promise<any> {
|
|
126
|
+
if (!fs.existsSync(`testeranto/reports/${this.name}`)) {
|
|
127
|
+
fs.mkdirSync(`testeranto/reports/${this.name}`);
|
|
356
128
|
}
|
|
357
|
-
return false;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
writeFileSync(fp: string, contents: string) {
|
|
361
|
-
fs.writeFileSync(fp, contents);
|
|
362
|
-
}
|
|
363
129
|
|
|
364
|
-
createWriteStream(filepath: string): fs.WriteStream {
|
|
365
|
-
return fs.createWriteStream(filepath);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
testArtiFactoryfileWriter(tLog: ITLog, callback: (Promise) => void) {
|
|
369
|
-
return (fPath, value: string | Buffer | PassThrough) => {
|
|
370
|
-
callback(
|
|
371
|
-
new Promise<void>((res, rej) => {
|
|
372
|
-
tLog("testArtiFactory =>", fPath);
|
|
373
|
-
|
|
374
|
-
const cleanPath = path.resolve(fPath);
|
|
375
|
-
fPaths.push(cleanPath.replace(process.cwd(), ``));
|
|
376
|
-
|
|
377
|
-
const targetDir = cleanPath.split("/").slice(0, -1).join("/");
|
|
378
|
-
|
|
379
|
-
fs.mkdir(targetDir, { recursive: true }, async (error) => {
|
|
380
|
-
if (error) {
|
|
381
|
-
console.error(`❗️testArtiFactory failed`, targetDir, error);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
fs.writeFileSync(
|
|
385
|
-
path.resolve(
|
|
386
|
-
targetDir.split("/").slice(0, -1).join("/"),
|
|
387
|
-
"manifest"
|
|
388
|
-
),
|
|
389
|
-
fPaths.join(`\n`),
|
|
390
|
-
{
|
|
391
|
-
encoding: "utf-8",
|
|
392
|
-
}
|
|
393
|
-
);
|
|
394
|
-
|
|
395
|
-
if (Buffer.isBuffer(value)) {
|
|
396
|
-
fs.writeFileSync(fPath, value, "binary");
|
|
397
|
-
res();
|
|
398
|
-
} else if (`string` === typeof value) {
|
|
399
|
-
fs.writeFileSync(fPath, value.toString(), {
|
|
400
|
-
encoding: "utf-8",
|
|
401
|
-
});
|
|
402
|
-
res();
|
|
403
|
-
} else {
|
|
404
|
-
/* @ts-ignore:next-line */
|
|
405
|
-
const pipeStream: PassThrough = value;
|
|
406
|
-
const myFile = fs.createWriteStream(fPath);
|
|
407
|
-
pipeStream.pipe(myFile);
|
|
408
|
-
pipeStream.on("close", () => {
|
|
409
|
-
myFile.close();
|
|
410
|
-
res();
|
|
411
|
-
});
|
|
412
|
-
}
|
|
413
|
-
});
|
|
414
|
-
})
|
|
415
|
-
);
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
write(accessObject: { uid: number }, contents: string): boolean {
|
|
420
|
-
throw new Error("Method not implemented.");
|
|
421
|
-
}
|
|
422
|
-
page(): string | undefined {
|
|
423
|
-
throw new Error("Method not implemented.");
|
|
424
|
-
}
|
|
425
|
-
click(selector: string): string | undefined {
|
|
426
|
-
throw new Error("Method not implemented.");
|
|
427
|
-
}
|
|
428
|
-
focusOn(selector: string) {
|
|
429
|
-
throw new Error("Method not implemented.");
|
|
430
|
-
}
|
|
431
|
-
typeInto(value: string) {
|
|
432
|
-
throw new Error("Method not implemented.");
|
|
433
|
-
}
|
|
434
|
-
getValue(value: string) {
|
|
435
|
-
throw new Error("Method not implemented.");
|
|
436
|
-
}
|
|
437
|
-
getAttribute(selector: string, attribute: string) {
|
|
438
|
-
throw new Error("Method not implemented.");
|
|
439
|
-
}
|
|
440
|
-
isDisabled(selector: string): Promise<boolean> {
|
|
441
|
-
throw new Error("Method not implemented.");
|
|
442
|
-
}
|
|
443
|
-
screencastStop(s: string) {
|
|
444
|
-
throw new Error("Method not implemented.");
|
|
445
|
-
}
|
|
446
|
-
////////////////////////////////////////////////////////////////////////////////
|
|
447
|
-
|
|
448
|
-
async metafileOutputs(platform: "web" | "node") {
|
|
449
|
-
const metafile = JSON.parse(
|
|
450
|
-
fs.readFileSync(`docs/${platform}/metafile.json`).toString()
|
|
451
|
-
).metafile;
|
|
452
|
-
|
|
453
|
-
if (!metafile) return;
|
|
454
|
-
|
|
455
|
-
const outputs: IOutputs = metafile.outputs;
|
|
456
|
-
|
|
457
|
-
Object.keys(outputs).forEach(async (k) => {
|
|
458
|
-
const addableFiles = Object.keys(outputs[k].inputs).filter((i) => {
|
|
459
|
-
if (!fs.existsSync(i)) return false;
|
|
460
|
-
if (i.startsWith("node_modules")) return false;
|
|
461
|
-
return true;
|
|
462
|
-
});
|
|
463
|
-
|
|
464
|
-
const f = `${k.split(".").slice(0, -1).join(".")}/`;
|
|
465
|
-
if (!fs.existsSync(f)) {
|
|
466
|
-
fs.mkdirSync(f);
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
const entrypoint = outputs[k].entryPoint;
|
|
470
|
-
|
|
471
|
-
if (entrypoint) {
|
|
472
|
-
const changeDigest = await filesHash(addableFiles);
|
|
473
|
-
|
|
474
|
-
if (changeDigest === changes[entrypoint]) {
|
|
475
|
-
// skip
|
|
476
|
-
} else {
|
|
477
|
-
changes[entrypoint] = changeDigest;
|
|
478
|
-
this.tscCheck({
|
|
479
|
-
platform,
|
|
480
|
-
addableFiles,
|
|
481
|
-
entrypoint: "./" + entrypoint,
|
|
482
|
-
});
|
|
483
|
-
this.eslintCheck("./" + entrypoint, platform, addableFiles);
|
|
484
|
-
this.makePrompt("./" + entrypoint, addableFiles, platform);
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
async start(): Promise<any> {
|
|
491
130
|
this.browser = (await puppeteer.launch({
|
|
492
131
|
slowMo: 1,
|
|
493
|
-
// timeout: 1,
|
|
494
132
|
waitForInitialPage: false,
|
|
495
133
|
executablePath:
|
|
496
134
|
// process.env.CHROMIUM_PATH || "/opt/homebrew/bin/chromium",
|
|
497
135
|
"/opt/homebrew/bin/chromium",
|
|
498
136
|
headless: true,
|
|
499
|
-
dumpio:
|
|
500
|
-
|
|
501
|
-
devtools: true,
|
|
137
|
+
dumpio: false,
|
|
138
|
+
devtools: false,
|
|
502
139
|
|
|
503
140
|
args: [
|
|
504
|
-
"--auto-open-devtools-for-tabs",
|
|
505
|
-
`--remote-debugging-port=3234`,
|
|
506
|
-
|
|
507
|
-
// "--disable-features=IsolateOrigins,site-per-process",
|
|
508
|
-
"--disable-site-isolation-trials",
|
|
509
|
-
"--allow-insecure-localhost",
|
|
510
141
|
"--allow-file-access-from-files",
|
|
142
|
+
"--allow-insecure-localhost",
|
|
511
143
|
"--allow-running-insecure-content",
|
|
512
|
-
|
|
144
|
+
"--auto-open-devtools-for-tabs",
|
|
513
145
|
"--disable-dev-shm-usage",
|
|
514
146
|
"--disable-extensions",
|
|
515
147
|
"--disable-gpu",
|
|
516
148
|
"--disable-setuid-sandbox",
|
|
517
149
|
"--disable-site-isolation-trials",
|
|
150
|
+
"--disable-site-isolation-trials",
|
|
518
151
|
"--disable-web-security",
|
|
519
152
|
"--no-first-run",
|
|
520
153
|
"--no-sandbox",
|
|
521
154
|
"--no-startup-window",
|
|
522
|
-
// "--no-zygote",
|
|
523
155
|
"--reduce-security-for-testing",
|
|
524
156
|
"--remote-allow-origins=*",
|
|
157
|
+
`--remote-debugging-port=3234`,
|
|
525
158
|
"--unsafely-treat-insecure-origin-as-secure=*",
|
|
159
|
+
// "--disable-features=IsolateOrigins,site-per-process",
|
|
526
160
|
// "--disable-features=IsolateOrigins",
|
|
161
|
+
// "--disk-cache-dir=/dev/null",
|
|
162
|
+
// "--disk-cache-size=1",
|
|
163
|
+
// "--no-zygote",
|
|
527
164
|
// "--remote-allow-origins=ws://localhost:3234",
|
|
528
165
|
// "--single-process",
|
|
166
|
+
// "--start-maximized",
|
|
529
167
|
// "--unsafely-treat-insecure-origin-as-secure",
|
|
530
168
|
// "--unsafely-treat-insecure-origin-as-secure=ws://192.168.0.101:3234",
|
|
531
|
-
|
|
532
|
-
// "--disk-cache-dir=/dev/null",
|
|
533
|
-
// "--disk-cache-size=1",
|
|
534
|
-
// "--start-maximized",
|
|
535
169
|
],
|
|
536
170
|
})) as any;
|
|
537
171
|
|
|
538
|
-
const { nodeEntryPoints, webEntryPoints } = getRunnables(
|
|
172
|
+
const { nodeEntryPoints, webEntryPoints } = this.getRunnables(
|
|
539
173
|
this.configs.tests
|
|
540
174
|
);
|
|
541
175
|
|
|
@@ -572,17 +206,16 @@ export class PM_Main extends PM {
|
|
|
572
206
|
);
|
|
573
207
|
|
|
574
208
|
this.metafileOutputs("node");
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
);
|
|
209
|
+
const w = `./testeranto/bundles/node/${this.name}/metafile.json`;
|
|
210
|
+
console.log("w", w);
|
|
211
|
+
this.nodeMetafileWatcher = watch(w, async (e, filename) => {
|
|
212
|
+
console.log(ansiC.green(ansiC.inverse(`< ${e} ${filename} (node)`)));
|
|
213
|
+
this.metafileOutputs("node");
|
|
214
|
+
});
|
|
582
215
|
|
|
583
216
|
this.metafileOutputs("web");
|
|
584
217
|
this.webMetafileWatcher = watch(
|
|
585
|
-
|
|
218
|
+
`./testeranto/bundles/web/${this.name}/metafile.json`,
|
|
586
219
|
async (e, filename) => {
|
|
587
220
|
console.log(ansiC.green(ansiC.inverse(`< ${e} ${filename} (web)`)));
|
|
588
221
|
this.metafileOutputs("web");
|
|
@@ -590,6 +223,94 @@ export class PM_Main extends PM {
|
|
|
590
223
|
);
|
|
591
224
|
}
|
|
592
225
|
|
|
226
|
+
stop = () => {
|
|
227
|
+
console.log(ansiC.inverse("Testeranto-Run is shutting down gracefully..."));
|
|
228
|
+
this.mode = "once";
|
|
229
|
+
this.nodeMetafileWatcher.close();
|
|
230
|
+
this.webMetafileWatcher.close();
|
|
231
|
+
this.checkForShutdown();
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
getRunnables = (
|
|
235
|
+
tests: ITestTypes[],
|
|
236
|
+
payload = {
|
|
237
|
+
nodeEntryPoints: {},
|
|
238
|
+
webEntryPoints: {},
|
|
239
|
+
}
|
|
240
|
+
): IRunnables => {
|
|
241
|
+
return tests.reduce((pt, cv, cndx, cry) => {
|
|
242
|
+
if (cv[1] === "node") {
|
|
243
|
+
pt.nodeEntryPoints[cv[0]] = path.resolve(
|
|
244
|
+
`./testeranto/bundles/node/${this.name}/${cv[0]
|
|
245
|
+
.split(".")
|
|
246
|
+
.slice(0, -1)
|
|
247
|
+
.concat("mjs")
|
|
248
|
+
.join(".")}`
|
|
249
|
+
);
|
|
250
|
+
} else if (cv[1] === "web") {
|
|
251
|
+
pt.webEntryPoints[cv[0]] = path.resolve(
|
|
252
|
+
`./testeranto/bundles/web/${this.name}/${cv[0]
|
|
253
|
+
.split(".")
|
|
254
|
+
.slice(0, -1)
|
|
255
|
+
.concat("mjs")
|
|
256
|
+
.join(".")}`
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (cv[3].length) {
|
|
261
|
+
this.getRunnables(cv[3], payload);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return pt;
|
|
265
|
+
}, payload as IRunnables);
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
async metafileOutputs(platform: "web" | "node") {
|
|
269
|
+
const metafile = JSON.parse(
|
|
270
|
+
fs
|
|
271
|
+
.readFileSync(
|
|
272
|
+
`./testeranto/bundles/${platform}/${this.name}/metafile.json`
|
|
273
|
+
)
|
|
274
|
+
.toString()
|
|
275
|
+
).metafile;
|
|
276
|
+
|
|
277
|
+
if (!metafile) return;
|
|
278
|
+
|
|
279
|
+
const outputs: IOutputs = metafile.outputs;
|
|
280
|
+
|
|
281
|
+
Object.keys(outputs).forEach(async (k) => {
|
|
282
|
+
const addableFiles = Object.keys(outputs[k].inputs).filter((i) => {
|
|
283
|
+
if (!fs.existsSync(i)) return false;
|
|
284
|
+
if (i.startsWith("node_modules")) return false;
|
|
285
|
+
return true;
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
const f = `${k.split(".").slice(0, -1).join(".")}/`;
|
|
289
|
+
if (!fs.existsSync(f)) {
|
|
290
|
+
fs.mkdirSync(f);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const entrypoint = outputs[k].entryPoint;
|
|
294
|
+
|
|
295
|
+
if (entrypoint) {
|
|
296
|
+
const changeDigest = await filesHash(addableFiles);
|
|
297
|
+
|
|
298
|
+
if (changeDigest === changes[entrypoint]) {
|
|
299
|
+
// skip
|
|
300
|
+
} else {
|
|
301
|
+
changes[entrypoint] = changeDigest;
|
|
302
|
+
this.tscCheck({
|
|
303
|
+
platform,
|
|
304
|
+
addableFiles,
|
|
305
|
+
entrypoint: "./" + entrypoint,
|
|
306
|
+
});
|
|
307
|
+
this.eslintCheck("./" + entrypoint, platform, addableFiles);
|
|
308
|
+
this.makePrompt("./" + entrypoint, addableFiles, platform);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
593
314
|
tscCheck = async ({
|
|
594
315
|
entrypoint,
|
|
595
316
|
addableFiles,
|
|
@@ -600,14 +321,14 @@ export class PM_Main extends PM {
|
|
|
600
321
|
addableFiles: string[];
|
|
601
322
|
}) => {
|
|
602
323
|
console.log(ansiC.green(ansiC.inverse(`tsc < ${entrypoint}`)));
|
|
603
|
-
this.
|
|
324
|
+
this.typeCheckIsRunning(entrypoint);
|
|
604
325
|
|
|
605
326
|
const program = tsc.createProgramFromConfig({
|
|
606
327
|
basePath: process.cwd(), // always required, used for relative paths
|
|
607
328
|
configFilePath: "tsconfig.json", // config to inherit from (optional)
|
|
608
329
|
compilerOptions: {
|
|
609
330
|
rootDir: "src",
|
|
610
|
-
outDir: tscPather(entrypoint, platform),
|
|
331
|
+
outDir: tscPather(entrypoint, platform, this.name),
|
|
611
332
|
// declaration: true,
|
|
612
333
|
// skipLibCheck: true,
|
|
613
334
|
noEmit: true,
|
|
@@ -615,11 +336,11 @@ export class PM_Main extends PM {
|
|
|
615
336
|
include: addableFiles, //["src/**/*"],
|
|
616
337
|
// exclude: ["**/*.test.ts", "**/*.spec.ts"],
|
|
617
338
|
});
|
|
618
|
-
const tscPath = tscPather(entrypoint, platform);
|
|
339
|
+
const tscPath = tscPather(entrypoint, platform, this.name);
|
|
619
340
|
|
|
620
341
|
let allDiagnostics = program.getSemanticDiagnostics();
|
|
621
342
|
|
|
622
|
-
const
|
|
343
|
+
const results: string[] = [];
|
|
623
344
|
allDiagnostics.forEach((diagnostic) => {
|
|
624
345
|
if (diagnostic.file) {
|
|
625
346
|
let { line, character } = ts.getLineAndCharacterOfPosition(
|
|
@@ -630,25 +351,21 @@ export class PM_Main extends PM {
|
|
|
630
351
|
diagnostic.messageText,
|
|
631
352
|
"\n"
|
|
632
353
|
);
|
|
633
|
-
|
|
354
|
+
results.push(
|
|
634
355
|
`${diagnostic.file.fileName} (${line + 1},${
|
|
635
356
|
character + 1
|
|
636
357
|
}): ${message}`
|
|
637
358
|
);
|
|
638
359
|
} else {
|
|
639
|
-
|
|
360
|
+
results.push(
|
|
361
|
+
ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")
|
|
362
|
+
);
|
|
640
363
|
}
|
|
641
364
|
});
|
|
642
365
|
|
|
643
|
-
fs.writeFileSync(tscPath,
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
this.checkForShutdown();
|
|
647
|
-
}
|
|
648
|
-
// fs.writeFileSync(
|
|
649
|
-
// tscExitCodePather(entrypoint, platform),
|
|
650
|
-
// d.length.toString()
|
|
651
|
-
// );
|
|
366
|
+
fs.writeFileSync(tscPath, results.join("\n"));
|
|
367
|
+
|
|
368
|
+
this.typeCheckIsNowDone(entrypoint, results.length);
|
|
652
369
|
};
|
|
653
370
|
|
|
654
371
|
eslintCheck = async (
|
|
@@ -656,8 +373,9 @@ export class PM_Main extends PM {
|
|
|
656
373
|
platform: "web" | "node",
|
|
657
374
|
addableFiles: string[]
|
|
658
375
|
) => {
|
|
659
|
-
this.bigBoard[entrypoint].staticErrors = "?";
|
|
660
376
|
console.log(ansiC.green(ansiC.inverse(`eslint < ${entrypoint}`)));
|
|
377
|
+
this.lintIsRunning(entrypoint);
|
|
378
|
+
|
|
661
379
|
const results = (await eslint.lintFiles(addableFiles))
|
|
662
380
|
.filter((r) => r.messages.length)
|
|
663
381
|
.filter((r) => {
|
|
@@ -669,17 +387,10 @@ export class PM_Main extends PM {
|
|
|
669
387
|
});
|
|
670
388
|
|
|
671
389
|
fs.writeFileSync(
|
|
672
|
-
lintPather(entrypoint, platform),
|
|
390
|
+
lintPather(entrypoint, platform, this.name),
|
|
673
391
|
await formatter.format(results)
|
|
674
392
|
);
|
|
675
|
-
this.
|
|
676
|
-
if (this.shutdownMode) {
|
|
677
|
-
this.checkForShutdown();
|
|
678
|
-
}
|
|
679
|
-
// fs.writeFileSync(
|
|
680
|
-
// lintExitCodePather(entrypoint, platform),
|
|
681
|
-
// results.length.toString()
|
|
682
|
-
// );
|
|
393
|
+
this.lintIsNowDone(entrypoint, results.length);
|
|
683
394
|
};
|
|
684
395
|
|
|
685
396
|
makePrompt = async (
|
|
@@ -688,22 +399,21 @@ export class PM_Main extends PM {
|
|
|
688
399
|
platform: "web" | "node"
|
|
689
400
|
) => {
|
|
690
401
|
this.bigBoard[entryPoint].prompt = "?";
|
|
691
|
-
const promptPath =
|
|
692
|
-
"./docs/",
|
|
693
|
-
platform,
|
|
694
|
-
entryPoint.split(".").slice(0, -1).join("."),
|
|
695
|
-
`prompt.txt`
|
|
696
|
-
);
|
|
402
|
+
const promptPath = promptPather(entryPoint, platform, this.name);
|
|
697
403
|
|
|
698
404
|
const testPaths = path.join(
|
|
699
|
-
"
|
|
405
|
+
"testeranto",
|
|
406
|
+
"reports",
|
|
407
|
+
this.name,
|
|
700
408
|
platform,
|
|
701
409
|
entryPoint.split(".").slice(0, -1).join("."),
|
|
702
410
|
`tests.json`
|
|
703
411
|
);
|
|
704
412
|
|
|
705
413
|
const featuresPath = path.join(
|
|
706
|
-
"
|
|
414
|
+
"testeranto",
|
|
415
|
+
"reports",
|
|
416
|
+
this.name,
|
|
707
417
|
platform,
|
|
708
418
|
entryPoint.split(".").slice(0, -1).join("."),
|
|
709
419
|
`featurePrompt.txt`
|
|
@@ -718,71 +428,122 @@ ${addableFiles
|
|
|
718
428
|
})
|
|
719
429
|
.join("\n")}
|
|
720
430
|
|
|
721
|
-
/read ${lintPather(entryPoint, platform)}
|
|
722
|
-
/read ${tscPather(entryPoint, platform)}
|
|
431
|
+
/read ${lintPather(entryPoint, platform, this.name)}
|
|
432
|
+
/read ${tscPather(entryPoint, platform, this.name)}
|
|
723
433
|
/read ${testPaths}
|
|
724
434
|
|
|
725
435
|
/load ${featuresPath}
|
|
726
436
|
|
|
727
437
|
/code Fix the failing tests described in ${testPaths}. Correct any type signature errors described in the files ${tscPather(
|
|
728
438
|
entryPoint,
|
|
729
|
-
platform
|
|
439
|
+
platform,
|
|
440
|
+
this.name
|
|
730
441
|
)}. Implement any method which throws "Function not implemented. Resolve the lint errors described in ${lintPather(
|
|
731
442
|
entryPoint,
|
|
732
|
-
platform
|
|
443
|
+
platform,
|
|
444
|
+
this.name
|
|
733
445
|
)}"
|
|
734
446
|
`
|
|
735
447
|
);
|
|
736
448
|
this.bigBoard[
|
|
737
449
|
entryPoint
|
|
738
|
-
].prompt = `aider --model deepseek/deepseek-chat --load
|
|
450
|
+
].prompt = `aider --model deepseek/deepseek-chat --load testeranto/${
|
|
451
|
+
this.name
|
|
452
|
+
}/reports/${platform}/${entryPoint
|
|
739
453
|
.split(".")
|
|
740
454
|
.slice(0, -1)
|
|
741
455
|
.join(".")}/prompt.txt`;
|
|
742
|
-
|
|
743
|
-
this.checkForShutdown();
|
|
744
|
-
}
|
|
456
|
+
this.checkForShutdown();
|
|
745
457
|
};
|
|
746
458
|
|
|
747
459
|
checkForShutdown = () => {
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
}
|
|
460
|
+
this.writeBigBoard();
|
|
461
|
+
|
|
462
|
+
if (this.mode === "dev") return;
|
|
463
|
+
|
|
464
|
+
let inflight = false;
|
|
465
|
+
|
|
466
|
+
Object.keys(this.bigBoard).forEach((k) => {
|
|
467
|
+
if (this.bigBoard[k].prompt === "?") {
|
|
468
|
+
console.log(ansiC.blue(ansiC.inverse(`🕕 prompt ${k}`)));
|
|
469
|
+
inflight = true;
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
Object.keys(this.bigBoard).forEach((k) => {
|
|
474
|
+
if (this.bigBoard[k].runTimeError === "?") {
|
|
475
|
+
console.log(ansiC.blue(ansiC.inverse(`🕕 runTimeError ${k}`)));
|
|
476
|
+
inflight = true;
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
Object.keys(this.bigBoard).forEach((k) => {
|
|
481
|
+
if (this.bigBoard[k].staticErrors === "?") {
|
|
482
|
+
console.log(ansiC.blue(ansiC.inverse(`🕕 staticErrors ${k}`)));
|
|
483
|
+
inflight = true;
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
Object.keys(this.bigBoard).forEach((k) => {
|
|
488
|
+
if (this.bigBoard[k].typeErrors === "?") {
|
|
489
|
+
console.log(ansiC.blue(ansiC.inverse(`🕕 typeErrors ${k}`)));
|
|
490
|
+
inflight = true;
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
this.writeBigBoard();
|
|
495
|
+
|
|
496
|
+
if (!inflight) {
|
|
760
497
|
this.browser.disconnect().then(() => {
|
|
761
|
-
|
|
762
|
-
"docs/summary.json",
|
|
763
|
-
JSON.stringify(this.bigBoard, null, 2)
|
|
764
|
-
);
|
|
765
|
-
console.log(ansiC.inverse("Goodbye"));
|
|
498
|
+
console.log(ansiC.inverse(`${this.name} has been tested. Goodbye.`));
|
|
766
499
|
process.exit();
|
|
767
500
|
});
|
|
768
501
|
}
|
|
769
502
|
};
|
|
770
503
|
|
|
771
|
-
|
|
772
|
-
this.bigBoard[src].
|
|
504
|
+
typeCheckIsRunning = (src: string) => {
|
|
505
|
+
this.bigBoard[src].typeErrors = "?";
|
|
773
506
|
};
|
|
774
507
|
|
|
775
|
-
|
|
776
|
-
this.bigBoard[src].
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
508
|
+
typeCheckIsNowDone = (src: string, failures: number) => {
|
|
509
|
+
this.bigBoard[src].typeErrors = failures;
|
|
510
|
+
this.writeBigBoard();
|
|
511
|
+
this.checkForShutdown();
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
lintIsRunning = (src: string) => {
|
|
515
|
+
this.bigBoard[src].staticErrors = "?";
|
|
516
|
+
this.writeBigBoard();
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
lintIsNowDone = (src: string, failures: number) => {
|
|
520
|
+
this.bigBoard[src].staticErrors = failures;
|
|
521
|
+
this.writeBigBoard();
|
|
522
|
+
this.checkForShutdown();
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
bddTestIsRunning = (src: string) => {
|
|
526
|
+
this.bigBoard[src].runTimeError = "?";
|
|
527
|
+
this.writeBigBoard();
|
|
528
|
+
};
|
|
529
|
+
|
|
530
|
+
bddTestIsNowDone = (src: string, failures: number) => {
|
|
531
|
+
this.bigBoard[src].runTimeError = failures;
|
|
532
|
+
this.writeBigBoard();
|
|
533
|
+
this.checkForShutdown();
|
|
780
534
|
};
|
|
781
535
|
|
|
782
536
|
launchNode = async (src: string, dest: string) => {
|
|
783
|
-
// console.log(ansiC.yellow(`! node, ${src}`));
|
|
784
537
|
console.log(ansiC.green(ansiC.inverse(`! node, ${src}`)));
|
|
785
|
-
this.
|
|
538
|
+
this.bddTestIsRunning(src);
|
|
539
|
+
|
|
540
|
+
const reportDest = `testeranto/reports/${this.name}/${src
|
|
541
|
+
.split(".")
|
|
542
|
+
.slice(0, -1)
|
|
543
|
+
.join(".")}/node`;
|
|
544
|
+
if (!fs.existsSync(reportDest)) {
|
|
545
|
+
fs.mkdirSync(reportDest, { recursive: true });
|
|
546
|
+
}
|
|
786
547
|
|
|
787
548
|
const destFolder = dest.replace(".mjs", "");
|
|
788
549
|
|
|
@@ -804,7 +565,7 @@ ${addableFiles
|
|
|
804
565
|
scheduled: true,
|
|
805
566
|
name: src,
|
|
806
567
|
ports: portsToUse,
|
|
807
|
-
fs:
|
|
568
|
+
fs: reportDest,
|
|
808
569
|
browserWSEndpoint: this.browser.wsEndpoint(),
|
|
809
570
|
});
|
|
810
571
|
} else if (testConfigResource.ports > 0) {
|
|
@@ -869,18 +630,16 @@ ${addableFiles
|
|
|
869
630
|
defaultModule
|
|
870
631
|
.receiveTestResourceConfig(argz)
|
|
871
632
|
.then(async ({ features, failed }: IFinalResults) => {
|
|
872
|
-
this.receiveFeatures(features, destFolder, src);
|
|
873
|
-
// console.log(`${src} completed with ${failed} errors`);
|
|
633
|
+
this.receiveFeatures(features, destFolder, src, "node");
|
|
874
634
|
statusMessagePretty(failed, src);
|
|
875
|
-
this.
|
|
635
|
+
this.bddTestIsNowDone(src, failed);
|
|
876
636
|
})
|
|
877
637
|
.catch((e) => {
|
|
878
638
|
console.log(ansiC.red(ansiC.inverse(`${src} errored with: ${e}`)));
|
|
879
|
-
|
|
639
|
+
this.bddTestIsNowDone(src, -1);
|
|
880
640
|
})
|
|
881
641
|
.finally(() => {
|
|
882
642
|
webSideCares.forEach((webSideCar) => webSideCar.close());
|
|
883
|
-
this.testIsNowDone(src);
|
|
884
643
|
});
|
|
885
644
|
});
|
|
886
645
|
});
|
|
@@ -918,7 +677,6 @@ ${addableFiles
|
|
|
918
677
|
page.exposeFunction(
|
|
919
678
|
"custom-screenshot",
|
|
920
679
|
async (ssOpts: ScreenshotOptions, testName: string) => {
|
|
921
|
-
// console.log("main.ts browser custom-screenshot", testName);
|
|
922
680
|
const p = ssOpts.path as string;
|
|
923
681
|
const dir = path.dirname(p);
|
|
924
682
|
fs.mkdirSync(dir, {
|
|
@@ -935,10 +693,8 @@ ${addableFiles
|
|
|
935
693
|
screenshots[testName] = [];
|
|
936
694
|
}
|
|
937
695
|
screenshots[testName].push(sPromise);
|
|
938
|
-
// sPromise.then(())
|
|
939
696
|
await sPromise;
|
|
940
697
|
return sPromise;
|
|
941
|
-
// page.evaluate(`window["screenshot done"]`);
|
|
942
698
|
}
|
|
943
699
|
);
|
|
944
700
|
|
|
@@ -983,9 +739,6 @@ ${addableFiles
|
|
|
983
739
|
(fp: string, testName: string) => {
|
|
984
740
|
const f = fs.createWriteStream(fp);
|
|
985
741
|
|
|
986
|
-
// if (!files[testName]) {
|
|
987
|
-
// files[testName] = new Set();
|
|
988
|
-
// }
|
|
989
742
|
files[testName].add(fp);
|
|
990
743
|
|
|
991
744
|
const p = new Promise<string>((res, rej) => {
|
|
@@ -1014,24 +767,12 @@ ${addableFiles
|
|
|
1014
767
|
return fileStreams2[uid].end();
|
|
1015
768
|
});
|
|
1016
769
|
|
|
1017
|
-
// page.exposeFunction("customclose", (p: string, testName: string) => {
|
|
1018
|
-
// fs.writeFileSync(
|
|
1019
|
-
// p + "/manifest.json",
|
|
1020
|
-
// JSON.stringify(Array.from(files[testName]))
|
|
1021
|
-
// );
|
|
1022
|
-
// delete files[testName];
|
|
1023
|
-
|
|
1024
|
-
// Promise.all(screenshots[testName] || []).then(() => {
|
|
1025
|
-
// delete screenshots[testName];
|
|
1026
|
-
// // page.close();
|
|
1027
|
-
// });
|
|
1028
|
-
// });
|
|
1029
|
-
|
|
1030
770
|
return page;
|
|
1031
771
|
})
|
|
1032
772
|
.then(async (page) => {
|
|
1033
773
|
await page.goto(`file://${`${dest}.html`}`, {});
|
|
1034
774
|
|
|
775
|
+
/* @ts-ignore:next-line */
|
|
1035
776
|
res(page);
|
|
1036
777
|
});
|
|
1037
778
|
});
|
|
@@ -1119,10 +860,17 @@ ${addableFiles
|
|
|
1119
860
|
}
|
|
1120
861
|
};
|
|
1121
862
|
|
|
1122
|
-
launchWeb = (
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
863
|
+
launchWeb = (src: string, dest: string) => {
|
|
864
|
+
console.log(ansiC.green(ansiC.inverse(`! web ${src}`)));
|
|
865
|
+
this.bddTestIsRunning(src);
|
|
866
|
+
|
|
867
|
+
const reportDest = `testeranto/reports/${this.name}/${src
|
|
868
|
+
.split(".")
|
|
869
|
+
.slice(0, -1)
|
|
870
|
+
.join(".")}/web`;
|
|
871
|
+
if (!fs.existsSync(reportDest)) {
|
|
872
|
+
fs.mkdirSync(reportDest, { recursive: true });
|
|
873
|
+
}
|
|
1126
874
|
|
|
1127
875
|
// sidecars.map((sidecar) => {
|
|
1128
876
|
// if (sidecar[1] === "node") {
|
|
@@ -1139,7 +887,7 @@ ${addableFiles
|
|
|
1139
887
|
const webArgz = JSON.stringify({
|
|
1140
888
|
name: dest,
|
|
1141
889
|
ports: [].toString(),
|
|
1142
|
-
fs:
|
|
890
|
+
fs: reportDest,
|
|
1143
891
|
browserWSEndpoint: this.browser.wsEndpoint(),
|
|
1144
892
|
});
|
|
1145
893
|
|
|
@@ -1165,9 +913,9 @@ ${addableFiles
|
|
|
1165
913
|
this.browser
|
|
1166
914
|
.newPage()
|
|
1167
915
|
.then((page) => {
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
916
|
+
page.on("console", (msg) => {
|
|
917
|
+
console.log("web > ", msg.args(), msg.text());
|
|
918
|
+
});
|
|
1171
919
|
|
|
1172
920
|
page.exposeFunction(
|
|
1173
921
|
"screencast",
|
|
@@ -1297,45 +1045,6 @@ ${addableFiles
|
|
|
1297
1045
|
return fileStreams2[uid].end();
|
|
1298
1046
|
});
|
|
1299
1047
|
|
|
1300
|
-
// page.exposeFunction("customclose", (p: string, testName: string) => {
|
|
1301
|
-
// // console.log("closing", p);
|
|
1302
|
-
|
|
1303
|
-
// console.log("\t GOODBYE customclose");
|
|
1304
|
-
|
|
1305
|
-
// fs.writeFileSync(
|
|
1306
|
-
// p + "/manifest.json",
|
|
1307
|
-
// JSON.stringify(Array.from(files[testName]))
|
|
1308
|
-
// );
|
|
1309
|
-
// delete files[testName];
|
|
1310
|
-
|
|
1311
|
-
// // console.log("screenshots[testName]", screenshots[testName]);
|
|
1312
|
-
// Promise.all(screenshots[testName] || []).then(() => {
|
|
1313
|
-
// delete screenshots[testName];
|
|
1314
|
-
// });
|
|
1315
|
-
|
|
1316
|
-
// // globalThis["writeFileSync"](
|
|
1317
|
-
// // p + "/manifest.json",
|
|
1318
|
-
// // // files.entries()
|
|
1319
|
-
// // JSON.stringify(Array.from(files[testName]))
|
|
1320
|
-
// // );
|
|
1321
|
-
|
|
1322
|
-
// // console.log("closing doneFileStream2", doneFileStream2);
|
|
1323
|
-
// // console.log("closing doneFileStream2", doneFileStream2);
|
|
1324
|
-
// // Promise.all([...doneFileStream2, ...screenshots2]).then(() => {
|
|
1325
|
-
// // page.close();
|
|
1326
|
-
// // });
|
|
1327
|
-
|
|
1328
|
-
// // Promise.all(screenshots).then(() => {
|
|
1329
|
-
// // page.close();
|
|
1330
|
-
// // });
|
|
1331
|
-
// // setTimeout(() => {
|
|
1332
|
-
// // console.log("Delayed for 1 second.");
|
|
1333
|
-
// // page.close();
|
|
1334
|
-
// // }, 5000);
|
|
1335
|
-
|
|
1336
|
-
// // return page.close();
|
|
1337
|
-
// });
|
|
1338
|
-
|
|
1339
1048
|
page.exposeFunction("page", () => {
|
|
1340
1049
|
return (page.mainFrame() as unknown as { _id: string })._id;
|
|
1341
1050
|
});
|
|
@@ -1388,43 +1097,43 @@ ${addableFiles
|
|
|
1388
1097
|
})
|
|
1389
1098
|
.then(async (page) => {
|
|
1390
1099
|
const close = () => {
|
|
1391
|
-
if (!files[
|
|
1392
|
-
files[
|
|
1100
|
+
if (!files[src]) {
|
|
1101
|
+
files[src] = new Set();
|
|
1393
1102
|
}
|
|
1394
1103
|
// files[t].add(filepath);
|
|
1395
1104
|
|
|
1396
1105
|
fs.writeFileSync(
|
|
1397
1106
|
destFolder + "/manifest.json",
|
|
1398
|
-
JSON.stringify(Array.from(files[
|
|
1107
|
+
JSON.stringify(Array.from(files[src]))
|
|
1399
1108
|
);
|
|
1400
|
-
delete files[
|
|
1109
|
+
delete files[src];
|
|
1401
1110
|
|
|
1402
|
-
Promise.all(screenshots[
|
|
1403
|
-
delete screenshots[
|
|
1111
|
+
Promise.all(screenshots[src] || []).then(() => {
|
|
1112
|
+
delete screenshots[src];
|
|
1404
1113
|
page.close();
|
|
1405
|
-
|
|
1406
|
-
this.testIsNowDone(t);
|
|
1407
1114
|
stderrStream.close();
|
|
1408
1115
|
stdoutStream.close();
|
|
1409
1116
|
});
|
|
1410
1117
|
};
|
|
1411
1118
|
|
|
1412
1119
|
page.on("pageerror", (err: Error) => {
|
|
1413
|
-
console.debug(`Error from ${
|
|
1120
|
+
console.debug(`Error from ${src}: [${err.name}] `);
|
|
1414
1121
|
stderrStream.write(err.name);
|
|
1415
1122
|
|
|
1416
1123
|
if (err.cause) {
|
|
1417
|
-
console.debug(`Error from ${
|
|
1124
|
+
console.debug(`Error from ${src} cause: [${err.cause}] `);
|
|
1418
1125
|
stderrStream.write(err.cause);
|
|
1419
1126
|
}
|
|
1420
1127
|
|
|
1421
1128
|
if (err.stack) {
|
|
1422
|
-
console.debug(`Error from stack ${
|
|
1129
|
+
console.debug(`Error from stack ${src}: [${err.stack}] `);
|
|
1423
1130
|
stderrStream.write(err.stack);
|
|
1424
1131
|
}
|
|
1425
1132
|
|
|
1426
|
-
console.debug(`Error from message ${
|
|
1133
|
+
console.debug(`Error from message ${src}: [${err.message}] `);
|
|
1427
1134
|
stderrStream.write(err.message);
|
|
1135
|
+
|
|
1136
|
+
this.bddTestIsNowDone(src, -1);
|
|
1428
1137
|
close();
|
|
1429
1138
|
});
|
|
1430
1139
|
page.on("console", (log: ConsoleMessage) => {
|
|
@@ -1442,17 +1151,17 @@ ${addableFiles
|
|
|
1442
1151
|
await page
|
|
1443
1152
|
.evaluate(evaluation)
|
|
1444
1153
|
.then(async ({ failed, features }: IFinalResults) => {
|
|
1445
|
-
this.receiveFeatures(features, destFolder,
|
|
1154
|
+
this.receiveFeatures(features, destFolder, src, "web");
|
|
1446
1155
|
// console.log(`${t} completed with ${failed} errors`);
|
|
1447
|
-
statusMessagePretty(failed,
|
|
1448
|
-
this.
|
|
1156
|
+
statusMessagePretty(failed, src);
|
|
1157
|
+
this.bddTestIsNowDone(src, failed);
|
|
1449
1158
|
})
|
|
1450
1159
|
.catch((e) => {
|
|
1451
1160
|
// console.log(red, `${t} errored with`, e);
|
|
1452
|
-
console.log(ansiC.red(ansiC.inverse(`${
|
|
1161
|
+
console.log(ansiC.red(ansiC.inverse(`${src} errored with: ${e}`)));
|
|
1453
1162
|
})
|
|
1454
1163
|
.finally(() => {
|
|
1455
|
-
|
|
1164
|
+
this.bddTestIsNowDone(src, -1);
|
|
1456
1165
|
close();
|
|
1457
1166
|
});
|
|
1458
1167
|
|
|
@@ -1463,11 +1172,12 @@ ${addableFiles
|
|
|
1463
1172
|
receiveFeatures = (
|
|
1464
1173
|
features: string[],
|
|
1465
1174
|
destFolder: string,
|
|
1466
|
-
srcTest: string
|
|
1175
|
+
srcTest: string,
|
|
1176
|
+
platform: "node" | "web"
|
|
1467
1177
|
) => {
|
|
1468
1178
|
const featureDestination = path.resolve(
|
|
1469
1179
|
process.cwd(),
|
|
1470
|
-
"
|
|
1180
|
+
"reports",
|
|
1471
1181
|
"features",
|
|
1472
1182
|
"strings",
|
|
1473
1183
|
srcTest.split(".").slice(0, -1).join(".") + ".features.txt"
|
|
@@ -1483,7 +1193,7 @@ ${addableFiles
|
|
|
1483
1193
|
const u = new URL(featureStringKey);
|
|
1484
1194
|
|
|
1485
1195
|
if (u.protocol === "file:") {
|
|
1486
|
-
const newPath = `${process.cwd()}/
|
|
1196
|
+
const newPath = `${process.cwd()}/testeranto/features/internal/${path.relative(
|
|
1487
1197
|
process.cwd(),
|
|
1488
1198
|
u.pathname
|
|
1489
1199
|
)}`;
|
|
@@ -1508,7 +1218,7 @@ ${addableFiles
|
|
|
1508
1218
|
// });
|
|
1509
1219
|
accum.files.push(newPath);
|
|
1510
1220
|
} else if (u.protocol === "http:" || u.protocol === "https:") {
|
|
1511
|
-
const newPath = `${process.cwd()}/
|
|
1221
|
+
const newPath = `${process.cwd()}/testeranto/features/external${
|
|
1512
1222
|
u.hostname
|
|
1513
1223
|
}${u.pathname}`;
|
|
1514
1224
|
const body = await this.configs.featureIngestor(featureStringKey);
|
|
@@ -1530,7 +1240,11 @@ ${addableFiles
|
|
|
1530
1240
|
// writeFileAndCreateDir(`${featureDestination}`, JSON.stringify(strings));
|
|
1531
1241
|
|
|
1532
1242
|
fs.writeFileSync(
|
|
1533
|
-
`${destFolder}/featurePrompt.txt`,
|
|
1243
|
+
// `${destFolder}/featurePrompt.txt`,
|
|
1244
|
+
`testeranto/reports/${this.name}/${srcTest
|
|
1245
|
+
.split(".")
|
|
1246
|
+
.slice(0, -1)
|
|
1247
|
+
.join(".")}/${platform}/featurePrompt.txt`,
|
|
1534
1248
|
files
|
|
1535
1249
|
.map((f) => {
|
|
1536
1250
|
return `/read ${f}`;
|
|
@@ -1542,14 +1256,9 @@ ${addableFiles
|
|
|
1542
1256
|
// this.writeBigBoard();
|
|
1543
1257
|
};
|
|
1544
1258
|
|
|
1545
|
-
receiveExitCode = (srcTest: string, failures: number) => {
|
|
1546
|
-
this.bigBoard[srcTest].runTimeError = failures;
|
|
1547
|
-
this.writeBigBoard();
|
|
1548
|
-
};
|
|
1549
|
-
|
|
1550
1259
|
writeBigBoard = () => {
|
|
1551
1260
|
fs.writeFileSync(
|
|
1552
|
-
|
|
1261
|
+
`./testeranto/reports/${this.name}/summary.json`,
|
|
1553
1262
|
JSON.stringify(this.bigBoard, null, 2)
|
|
1554
1263
|
);
|
|
1555
1264
|
};
|