testeranto 0.49.10 → 0.62.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 (241) hide show
  1. package/.nvmrc +1 -0
  2. package/README.md +71 -9
  3. package/dist/cjs-shim.js +12 -0
  4. package/dist/common/Features.js +2 -3
  5. package/dist/common/Node.js +53 -61
  6. package/dist/common/Project.js +272 -606
  7. package/dist/common/SubPackages/puppeteer.js +19 -0
  8. package/dist/common/{subPackages → SubPackages}/react/component/node.js +4 -4
  9. package/dist/common/{subPackages → SubPackages}/react/component/web.js +4 -4
  10. package/dist/common/SubPackages/react/jsx/index.js +13 -0
  11. package/dist/common/SubPackages/react/jsx/node.js +10 -0
  12. package/dist/common/SubPackages/react/jsx/web.js +10 -0
  13. package/dist/common/{subPackages → SubPackages}/react-dom/component/node.js +6 -6
  14. package/dist/common/{subPackages → SubPackages}/react-dom/component/web.js +11 -12
  15. package/dist/common/SubPackages/react-dom/jsx/node.js +39 -0
  16. package/dist/common/{subPackages → SubPackages}/react-dom/jsx/web.js +5 -14
  17. package/dist/common/{subPackages → SubPackages}/react-test-renderer/MemoExoticComponent/node.js +2 -2
  18. package/dist/common/{subPackages → SubPackages}/react-test-renderer/component/index.js +26 -15
  19. package/dist/common/{subPackages/react-test-renderer/jsx → SubPackages/react-test-renderer/component}/node.js +3 -5
  20. package/dist/common/{subPackages/react-test-renderer/jsx → SubPackages/react-test-renderer/component}/web.js +3 -5
  21. package/dist/common/{subPackages → SubPackages}/react-test-renderer/fc/node.js +4 -4
  22. package/dist/common/{subPackages → SubPackages}/react-test-renderer/fc/web.js +4 -4
  23. package/dist/common/{subPackages → SubPackages}/react-test-renderer/jsx/index.js +8 -2
  24. package/dist/common/{subPackages/react-test-renderer/jsx-promised → SubPackages/react-test-renderer/jsx}/node.js +4 -4
  25. package/dist/common/{subPackages/react → SubPackages/react-test-renderer}/jsx/web.js +4 -4
  26. package/dist/common/{subPackages → SubPackages}/react-test-renderer/jsx-promised/index.js +2 -2
  27. package/dist/common/{subPackages/react/jsx → SubPackages/react-test-renderer/jsx-promised}/node.js +2 -2
  28. package/dist/common/Types.js +32 -0
  29. package/dist/common/Web.js +41 -112
  30. package/dist/common/electron.js +188 -44
  31. package/dist/common/esbuildConfigs/features.js +14 -0
  32. package/dist/common/esbuildConfigs/index.js +20 -0
  33. package/dist/common/esbuildConfigs/node.js +35 -0
  34. package/dist/common/esbuildConfigs/report.js +48 -0
  35. package/dist/common/esbuildConfigs/tests.js +14 -0
  36. package/dist/common/esbuildConfigs/web.js +50 -0
  37. package/dist/common/lib/abstractBase.js +193 -0
  38. package/dist/common/lib/basebuilder.js +86 -0
  39. package/dist/common/lib/browser.js +26 -0
  40. package/dist/common/lib/classBuilder.js +41 -0
  41. package/dist/common/lib/core.js +52 -0
  42. package/dist/common/lib/index.js +19 -0
  43. package/dist/common/nodeWriterElectron.js +55 -0
  44. package/dist/common/preload.js +22 -21
  45. package/dist/common/report.html.js +31 -0
  46. package/dist/common/tsconfig.common.tsbuildinfo +1 -1
  47. package/dist/common/web.html.js +22 -0
  48. package/dist/module/Features.js +2 -3
  49. package/dist/module/Node.js +53 -61
  50. package/dist/module/Project.js +272 -583
  51. package/dist/module/SubPackages/puppeteer.js +14 -0
  52. package/dist/module/{subPackages → SubPackages}/react/component/node.js +3 -3
  53. package/dist/module/{subPackages → SubPackages}/react/component/web.js +3 -3
  54. package/dist/module/SubPackages/react/jsx/index.js +10 -0
  55. package/dist/module/SubPackages/react/jsx/node.js +5 -0
  56. package/dist/module/SubPackages/react/jsx/web.js +5 -0
  57. package/dist/module/{subPackages → SubPackages}/react-dom/component/node.js +5 -5
  58. package/dist/module/{subPackages → SubPackages}/react-dom/component/web.js +10 -11
  59. package/dist/module/SubPackages/react-dom/jsx/node.js +31 -0
  60. package/dist/module/{subPackages → SubPackages}/react-dom/jsx/web.js +4 -13
  61. package/dist/module/{subPackages → SubPackages}/react-test-renderer/MemoExoticComponent/node.js +2 -2
  62. package/dist/module/{subPackages → SubPackages}/react-test-renderer/component/index.js +23 -15
  63. package/dist/module/{subPackages → SubPackages}/react-test-renderer/component/node.js +2 -2
  64. package/dist/module/{subPackages → SubPackages}/react-test-renderer/component/web.js +2 -2
  65. package/dist/module/{subPackages → SubPackages}/react-test-renderer/fc/node.js +3 -3
  66. package/dist/module/{subPackages → SubPackages}/react-test-renderer/fc/web.js +3 -3
  67. package/dist/module/{subPackages → SubPackages}/react-test-renderer/jsx/index.js +8 -2
  68. package/dist/module/SubPackages/react-test-renderer/jsx/node.js +5 -0
  69. package/dist/module/SubPackages/react-test-renderer/jsx/web.js +5 -0
  70. package/dist/module/{subPackages → SubPackages}/react-test-renderer/jsx-promised/index.js +2 -2
  71. package/dist/module/{subPackages/react-test-renderer/jsx → SubPackages/react-test-renderer/jsx-promised}/node.js +1 -1
  72. package/dist/module/Types.js +30 -1
  73. package/dist/module/Web.js +41 -112
  74. package/dist/module/electron.js +189 -45
  75. package/dist/module/esbuildConfigs/features.js +12 -0
  76. package/dist/module/esbuildConfigs/index.js +18 -0
  77. package/dist/module/esbuildConfigs/node.js +30 -0
  78. package/dist/module/esbuildConfigs/report.js +48 -0
  79. package/dist/module/esbuildConfigs/tests.js +12 -0
  80. package/dist/module/esbuildConfigs/web.js +45 -0
  81. package/dist/module/lib/abstractBase.js +185 -0
  82. package/dist/module/lib/basebuilder.js +82 -0
  83. package/dist/module/lib/browser.js +22 -0
  84. package/dist/module/lib/classBuilder.js +37 -0
  85. package/dist/module/lib/core.js +49 -0
  86. package/dist/module/lib/index.js +15 -0
  87. package/dist/module/nodeWriterElectron.js +52 -0
  88. package/dist/module/preload.js +22 -21
  89. package/dist/module/report.html.js +29 -0
  90. package/dist/module/tsconfig.module.tsbuildinfo +1 -1
  91. package/dist/module/web.html.js +20 -0
  92. package/dist/prebuild/Report.css +10326 -0
  93. package/dist/prebuild/Report.js +37456 -0
  94. package/dist/types/Features.d.ts +5 -5
  95. package/dist/types/Node.d.ts +4 -11
  96. package/dist/types/NodeWriter.d.ts +1 -1
  97. package/dist/types/Project.d.ts +2 -27
  98. package/dist/types/SubPackages/puppeteer.d.ts +6 -0
  99. package/dist/types/SubPackages/react/component/node.d.ts +7 -0
  100. package/dist/types/SubPackages/react/component/web.d.ts +7 -0
  101. package/dist/types/SubPackages/react/jsx/index.d.ts +15 -0
  102. package/dist/types/SubPackages/react/jsx/node.d.ts +4 -0
  103. package/dist/types/SubPackages/react/jsx/web.d.ts +4 -0
  104. package/dist/types/{subPackages → SubPackages}/react-dom/component/node.d.ts +2 -4
  105. package/dist/types/SubPackages/react-dom/component/web.d.ts +5 -0
  106. package/dist/types/SubPackages/react-dom/jsx/node.d.ts +6 -0
  107. package/dist/types/SubPackages/react-dom/jsx/web.d.ts +5 -0
  108. package/dist/types/SubPackages/react-test-renderer/MemoExoticComponent/node.d.ts +5 -0
  109. package/dist/types/{subPackages → SubPackages}/react-test-renderer/component/index.d.ts +6 -6
  110. package/dist/types/SubPackages/react-test-renderer/component/node.d.ts +9 -0
  111. package/dist/types/SubPackages/react-test-renderer/component/web.d.ts +4 -0
  112. package/dist/types/SubPackages/react-test-renderer/fc/node.d.ts +8 -0
  113. package/dist/types/SubPackages/react-test-renderer/fc/web.d.ts +8 -0
  114. package/dist/types/{subPackages → SubPackages}/react-test-renderer/jsx/index.d.ts +5 -4
  115. package/dist/types/SubPackages/react-test-renderer/jsx/node.d.ts +9 -0
  116. package/dist/types/SubPackages/react-test-renderer/jsx/web.d.ts +9 -0
  117. package/dist/types/{subPackages → SubPackages}/react-test-renderer/jsx-promised/index.d.ts +4 -4
  118. package/dist/types/SubPackages/react-test-renderer/jsx-promised/node.d.ts +5 -0
  119. package/dist/types/SubPackages/react-test-renderer/jsx-promised/web.d.ts +5 -0
  120. package/dist/types/Types.d.ts +116 -3
  121. package/dist/types/Web.d.ts +4 -11
  122. package/dist/types/esbuildConfigs/features.d.ts +4 -0
  123. package/dist/types/esbuildConfigs/index.d.ts +4 -0
  124. package/dist/types/esbuildConfigs/node.d.ts +4 -0
  125. package/dist/types/esbuildConfigs/report.d.ts +0 -0
  126. package/dist/types/esbuildConfigs/tests.d.ts +4 -0
  127. package/dist/types/esbuildConfigs/web.d.ts +4 -0
  128. package/dist/types/lib/abstractBase.d.ts +102 -0
  129. package/dist/types/lib/basebuilder.d.ts +24 -0
  130. package/dist/types/lib/browser.d.ts +6 -0
  131. package/dist/types/lib/classBuilder.d.ts +6 -0
  132. package/dist/types/lib/core.d.ts +7 -0
  133. package/dist/types/lib/index.d.ts +57 -0
  134. package/dist/types/nodeWriterElectron.d.ts +2 -0
  135. package/dist/types/report.html.d.ts +2 -0
  136. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  137. package/dist/types/web.html.d.ts +2 -0
  138. package/electronBuild.ts +32 -0
  139. package/index.html +30 -0
  140. package/package.json +120 -85
  141. package/src/Features.ts +2 -4
  142. package/src/Node.ts +114 -160
  143. package/src/NodeWriter.ts +1 -4
  144. package/src/Project.ts +610 -753
  145. package/src/Report.tsx +30 -15
  146. package/src/SubPackages/puppeteer.ts +46 -0
  147. package/src/{subPackages → SubPackages}/react/component/node.ts +12 -32
  148. package/src/SubPackages/react/component/web.ts +53 -0
  149. package/src/SubPackages/react/jsx/index.ts +43 -0
  150. package/src/SubPackages/react/jsx/node.ts +29 -0
  151. package/src/SubPackages/react/jsx/web.ts +28 -0
  152. package/src/{subPackages → SubPackages}/react-dom/component/node.ts +11 -25
  153. package/src/{subPackages → SubPackages}/react-dom/component/web.ts +27 -32
  154. package/src/{subPackages → SubPackages}/react-dom/jsx/index.ts +0 -1
  155. package/src/SubPackages/react-dom/jsx/node.ts +68 -0
  156. package/src/{subPackages → SubPackages}/react-dom/jsx/web.ts +18 -54
  157. package/src/{subPackages → SubPackages}/react-test-renderer/MemoExoticComponent/node.ts +9 -28
  158. package/src/{subPackages → SubPackages}/react-test-renderer/component/index.ts +31 -29
  159. package/src/SubPackages/react-test-renderer/component/node.ts +22 -0
  160. package/src/SubPackages/react-test-renderer/component/web.ts +22 -0
  161. package/src/{subPackages → SubPackages}/react-test-renderer/fc/node.ts +14 -28
  162. package/src/{subPackages → SubPackages}/react-test-renderer/fc/web.ts +9 -25
  163. package/src/{subPackages → SubPackages}/react-test-renderer/jsx/index.ts +19 -16
  164. package/src/SubPackages/react-test-renderer/jsx/node.ts +24 -0
  165. package/src/SubPackages/react-test-renderer/jsx/web.ts +20 -0
  166. package/src/{subPackages → SubPackages}/react-test-renderer/jsx-promised/index.ts +7 -15
  167. package/src/SubPackages/react-test-renderer/jsx-promised/node.ts +19 -0
  168. package/src/SubPackages/react-test-renderer/jsx-promised/web.ts +22 -0
  169. package/src/Types.ts +334 -3
  170. package/src/Web.ts +104 -230
  171. package/src/cjs-shim.js +12 -0
  172. package/src/electron.ts +237 -46
  173. package/src/esbuildConfigs/features.ts +18 -0
  174. package/src/esbuildConfigs/index.ts +22 -0
  175. package/src/esbuildConfigs/node.ts +59 -0
  176. package/src/esbuildConfigs/report.ts +51 -0
  177. package/src/esbuildConfigs/tests.ts +20 -0
  178. package/src/esbuildConfigs/web.ts +73 -0
  179. package/src/lib/abstractBase.ts +459 -0
  180. package/src/lib/basebuilder.ts +253 -0
  181. package/src/lib/browser.ts +34 -0
  182. package/src/lib/classBuilder.ts +137 -0
  183. package/src/lib/core.ts +182 -0
  184. package/src/lib/index.ts +116 -0
  185. package/src/nodeWriterElectron.ts +71 -0
  186. package/src/preload.ts +23 -21
  187. package/src/report.html.ts +29 -0
  188. package/src/web.html.ts +20 -0
  189. package/tests/Rectangle.test.ts +189 -0
  190. package/tsconfig.json +19 -6
  191. package/tsconfig.module.json +15 -4
  192. package/tsconfig.types.json +14 -4
  193. package/yarn-error.log +3144 -0
  194. package/dist/common/core.js +0 -397
  195. package/dist/common/subPackages/react/jsx/index.js +0 -26
  196. package/dist/common/subPackages/react-dom/jsx/node.js +0 -95
  197. package/dist/common/subPackages/react-test-renderer/component/node.js +0 -8
  198. package/dist/common/subPackages/react-test-renderer/component/web.js +0 -8
  199. package/dist/module/Report.js +0 -186
  200. package/dist/module/core.js +0 -388
  201. package/dist/module/subPackages/react/jsx/index.js +0 -22
  202. package/dist/module/subPackages/react/jsx/node.js +0 -5
  203. package/dist/module/subPackages/react/jsx/web.js +0 -5
  204. package/dist/module/subPackages/react-dom/jsx/node.js +0 -87
  205. package/dist/module/subPackages/react-test-renderer/jsx/web.js +0 -5
  206. package/dist/module/subPackages/react-test-renderer/jsx-promised/node.js +0 -5
  207. package/dist/types/core.d.ts +0 -220
  208. package/dist/types/subPackages/react/component/node.d.ts +0 -12
  209. package/dist/types/subPackages/react/component/web.d.ts +0 -12
  210. package/dist/types/subPackages/react/jsx/index.d.ts +0 -15
  211. package/dist/types/subPackages/react/jsx/node.d.ts +0 -4
  212. package/dist/types/subPackages/react/jsx/web.d.ts +0 -4
  213. package/dist/types/subPackages/react-dom/component/web.d.ts +0 -19
  214. package/dist/types/subPackages/react-dom/jsx/node.d.ts +0 -8
  215. package/dist/types/subPackages/react-dom/jsx/web.d.ts +0 -5
  216. package/dist/types/subPackages/react-test-renderer/MemoExoticComponent/node.d.ts +0 -8
  217. package/dist/types/subPackages/react-test-renderer/component/node.d.ts +0 -9
  218. package/dist/types/subPackages/react-test-renderer/component/web.d.ts +0 -9
  219. package/dist/types/subPackages/react-test-renderer/fc/node.d.ts +0 -9
  220. package/dist/types/subPackages/react-test-renderer/fc/web.d.ts +0 -9
  221. package/dist/types/subPackages/react-test-renderer/jsx/node.d.ts +0 -4
  222. package/dist/types/subPackages/react-test-renderer/jsx/web.d.ts +0 -4
  223. package/dist/types/subPackages/react-test-renderer/jsx-promised/node.d.ts +0 -4
  224. package/dist/types/subPackages/react-test-renderer/jsx-promised/web.d.ts +0 -4
  225. package/src/core.ts +0 -1399
  226. package/src/subPackages/react/component/web.ts +0 -80
  227. package/src/subPackages/react/jsx/index.ts +0 -64
  228. package/src/subPackages/react/jsx/node.ts +0 -29
  229. package/src/subPackages/react/jsx/web.ts +0 -29
  230. package/src/subPackages/react-dom/jsx/node.ts +0 -145
  231. package/src/subPackages/react-test-renderer/component/node.ts +0 -30
  232. package/src/subPackages/react-test-renderer/component/web.ts +0 -30
  233. package/src/subPackages/react-test-renderer/jsx/node.ts +0 -31
  234. package/src/subPackages/react-test-renderer/jsx/web.ts +0 -31
  235. package/src/subPackages/react-test-renderer/jsx-promised/node.ts +0 -31
  236. package/src/subPackages/react-test-renderer/jsx-promised/web.ts +0 -31
  237. /package/dist/common/{subPackages → SubPackages}/react-dom/jsx/index.js +0 -0
  238. /package/dist/common/{subPackages → SubPackages}/react-test-renderer/jsx-promised/web.js +0 -0
  239. /package/dist/module/{subPackages → SubPackages}/react-dom/jsx/index.js +0 -0
  240. /package/dist/module/{subPackages → SubPackages}/react-test-renderer/jsx-promised/web.js +0 -0
  241. /package/dist/types/{subPackages → SubPackages}/react-dom/jsx/index.d.ts +0 -0
package/src/Project.ts CHANGED
@@ -1,50 +1,22 @@
1
- import esbuild, { BuildOptions } from "esbuild";
1
+ import esbuild from "esbuild";
2
2
  import fs from "fs";
3
- import fsExists from "fs.promises.exists";
4
3
  import path from "path";
5
- import pm2 from "pm2";
6
4
  import readline from 'readline';
7
- import WebSocket, { WebSocketServer } from 'ws';
5
+ import { glob } from "glob";
8
6
 
9
- import { TesterantoFeatures } from "./Features";
10
7
  import { IBaseConfig, IRunTime, ITestTypes } from "./Types";
11
- import { ITTestResourceRequirement } from './core';
12
- import { glob } from "glob";
13
8
 
14
- readline.emitKeypressEvents(process.stdin);
15
- if (process.stdin.isTTY) process.stdin.setRawMode(true);
9
+ import esbuildNodeConfiger from "./esbuildConfigs/node.js";
10
+ import esbuildWebConfiger from "./esbuildConfigs/web.js";
11
+ import esbuildFeaturesConfiger from "./esbuildConfigs/features.js";
16
12
 
17
- const TIMEOUT = 2000;
18
- const OPEN_PORT = "";
19
-
20
- let webSocketServer: WebSocketServer;
21
-
22
- type ISchedulerProtocols = `ipc` | `ws`;
23
-
24
- type IAdios = {
25
- name: string;
26
- failed: any;
27
- testResourceConfiguration: {
28
- name: string;
29
- };
30
- results: {
31
- fails: any[];
32
- givens: any[];
33
- name: string;
34
- };
35
- };
36
-
37
- type IAdiosIPC = {
38
- process: {
39
- namespace: string;
40
- versioning: object;
41
- name: string;
42
- pm_id: number;
43
- };
44
- data: IAdios
45
- at: string;
46
- };
13
+ import webHtmlFrame from "./web.html.js";
14
+ import reportHtmlFrame from "./report.html.js";
47
15
 
16
+ import childProcess from 'child_process';
17
+
18
+ readline.emitKeypressEvents(process.stdin);
19
+ if (process.stdin.isTTY) process.stdin.setRawMode(true);
48
20
 
49
21
  const getRunnables = (
50
22
  tests: ITestTypes[],
@@ -68,34 +40,11 @@ const getRunnables = (
68
40
  }
69
41
 
70
42
  export class ITProject {
71
- clearScreen: boolean;
72
- devMode: boolean;
73
- exitCodes: Record<number, string> = {};
74
- features: TesterantoFeatures;
43
+ config: IBaseConfig;
75
44
  mode: `up` | `down` = `up`;
76
- ports: Record<string, string> = {};
77
- tests: ITestTypes[];
78
- websockets: Record<string, WebSocket> = {};
79
-
80
- resourceQueue: {
81
- requirement: ITTestResourceRequirement,
82
- protocol: ISchedulerProtocols,
83
- }[] = [];
84
-
85
- private spinCycle = 0;
86
- private spinAnimation = "←↖↑↗→↘↓↙";
87
45
 
88
46
  constructor(config: IBaseConfig) {
89
- this.clearScreen = config.clearScreen;
90
- this.devMode = config.devMode;
91
-
92
- // mark each port as open
93
- Object.values(config.ports).forEach((port) => {
94
- this.ports[port] = OPEN_PORT;
95
- });
96
-
97
- const testPath = `${process.cwd()}/${config.tests}`;
98
- const featurePath = `${process.cwd()}/${config.features}`;
47
+ this.config = config;
99
48
 
100
49
  process.stdin.on('keypress', (str, key) => {
101
50
  if (key.name === 'q') {
@@ -109,712 +58,620 @@ export class ITProject {
109
58
  }
110
59
  });
111
60
 
112
- import(testPath).then((tests) => {
113
- this.tests = tests.default;
114
-
115
- import(featurePath).then(async (features) => {
116
- this.features = features.default;
117
-
118
- await Promise.resolve(Promise.all(
119
- [
120
- ...this.getSecondaryEndpointsPoints("web")
121
- ]
122
- .map(async (sourceFilePath) => {
123
- const sourceFileSplit = sourceFilePath.split("/");
124
- const sourceDir = sourceFileSplit.slice(0, -1);
125
- const sourceFileName = sourceFileSplit[sourceFileSplit.length - 1];
126
- const sourceFileNameMinusJs = sourceFileName.split(".").slice(0, -1).join(".");
127
- const htmlFilePath = path.normalize(`${process.cwd()}/${config.outdir}/${sourceDir.join("/")}/${sourceFileNameMinusJs}.html`);
128
- const jsfilePath = `./${sourceFileNameMinusJs}.mjs`;
129
- return fs.promises.mkdir(path.dirname(htmlFilePath), { recursive: true }).then(x => fs.writeFileSync(htmlFilePath,
130
- `
131
- <!DOCTYPE html>
132
- <html lang="en">
133
- <head>
134
- <script type="module" src="${jsfilePath}"></script>
135
- </head>
136
-
137
- <body>
138
- <h1>${htmlFilePath}</h1>
139
- <div id="root">
140
-
141
- </div>
142
- </body>
143
-
144
- <footer></footer>
145
-
146
- </html>
147
- `))
148
- })
149
- ));
150
-
151
- const [nodeEntryPoints, webEntryPoints] = getRunnables(this.tests);
152
-
153
- const esbuildConfigNode: BuildOptions = {
154
- define: {
155
- "process.env.FLUENTFFMPEG_COV": "0"
156
- },
157
- absWorkingDir: process.cwd(),
158
- banner: {
159
- js: `import { createRequire } from 'module';const require = createRequire(import.meta.url);`
160
- },
161
- target: "esnext",
162
- format: "esm",
163
- splitting: true,
164
- outExtension: { '.js': '.mjs' },
165
- platform: "node",
166
- external: [
167
- "tests.test.js",
168
- "features.test.js", "react"],
169
-
170
- outbase: config.outbase,
171
- outdir: config.outdir,
172
- jsx: 'transform',
173
- entryPoints: [...nodeEntryPoints],
174
- bundle: true,
175
- minify: config.minify === true,
176
- write: true,
177
- loader: {
178
- '.js': 'jsx',
179
- '.png': 'binary',
180
- '.jpg': 'binary',
181
- },
182
- plugins: [
183
- ...(config.nodePlugins || []),
184
- {
185
- name: 'rebuild-notify',
186
- setup(build) {
187
- build.onEnd(result => {
188
- console.log(`node build ended with ${result.errors.length} errors`);
189
- console.log(result)
190
- result.errors.length !== 0 && process.exit(-1);
191
- })
192
- }
193
- },
194
- ],
195
- };
196
- const esbuildConfigWeb: BuildOptions = {
197
- target: "esnext",
198
- format: "esm",
199
- splitting: true,
200
- outExtension: { '.js': '.mjs' },
201
-
202
- alias: {
203
- react: path.resolve("./node_modules/react")
204
- },
205
-
206
- external: [
207
- "tests.test.js",
208
- "features.test.js",
209
- // "url",
210
- // "react",
211
- "electron",
212
- "path",
213
- "fs",
214
- "stream",
215
- ],
216
- platform: "browser",
217
-
218
- outbase: config.outbase,
219
- outdir: config.outdir,
220
- jsx: 'transform',
221
- entryPoints: [
222
- ...webEntryPoints,
223
- testPath,
224
- featurePath,
225
- ],
226
- bundle: true,
227
- minify: config.minify === true,
228
- write: true,
229
-
230
- loader: {
231
- '.js': 'jsx',
232
- '.png': 'binary',
233
- '.jpg': 'binary',
234
- },
235
- plugins: [
236
- ...(config.webPlugins || []),
237
- {
238
- name: 'rebuild-notify',
239
- setup(build) {
240
- build.onEnd(result => {
241
- console.log(`web build ended with ${result.errors.length} errors`);
242
- console.log(result)
243
- result.errors.length !== 0 && process.exit(-1);
244
- })
245
- }
246
- },
247
- ],
248
- };
249
-
250
- glob('./dist/chunk-*.mjs', { ignore: 'node_modules/**' }).then((chunks) => {
251
- console.log("deleting chunks", chunks)
252
- chunks.forEach((chunk) => {
253
- console.log("deleting chunk", chunk)
254
- fs.unlinkSync(chunk);
255
- })
256
-
257
- })
258
-
259
- esbuild.build({
260
- bundle: true,
261
- entryPoints: ["./node_modules/testeranto/dist/module/Report.js"],
262
- minify: config.minify === true,
263
- outbase: config.outbase,
264
- write: true,
265
- outfile: `${config.outdir}/Report.js`,
266
- external: ["tests.test.js", "features.test.js"]
267
- });
268
-
269
- fs.writeFileSync(`${config.outdir}/report.html`, `
270
- <!DOCTYPE html>
271
- <html lang="en">
272
-
273
- <head>
274
- <meta name="description" content="Webpage description goes here" />
275
- <meta charset="utf-8" />
276
- <title>kokomoBay - testeranto</title>
277
- <meta name="viewport" content="width=device-width, initial-scale=1" />
278
- <meta name="author" content="" />
279
- <link rel="stylesheet" href="./Report.css" />
280
-
281
- <script type="importmap">
282
- {
283
- "imports": {
284
- "tests.test.js": "./tests.test.js",
285
- "features.test.js": "./features.test.js"
286
- }
287
- }
288
- </script>
289
-
290
-
291
- <script src="./Report.js"></script>
292
- </head>
293
-
294
- <body>
295
- <div id="root">
296
- react is loading
297
- </div>
298
- </body>
299
-
300
- </html>
301
- `)
302
-
303
- Promise.all([
304
- esbuild.context(esbuildConfigNode)
305
- .then(async (nodeContext) => {
306
- await nodeContext.watch();
307
- }),
308
-
309
- esbuild.context(esbuildConfigWeb)
310
- .then(async (esbuildWeb) => {
311
- await esbuildWeb.watch();
312
- })
313
-
314
- ]).then(() => {
315
-
316
- if (config.devMode === false) {
317
- console.log("Your tests were built but not run because devMode was false. Exiting gracefully");
318
- process.exit(0);
319
-
320
- } else {
321
-
322
- pm2.connect(async (err) => {
323
-
324
- if (err) {
325
- console.error(err);
326
- process.exit(-1);
327
- } else {
328
- console.log(`pm2 is connected`);
329
- }
330
-
331
- // run a websocket as an alternative to node IPC
332
- webSocketServer = new WebSocketServer({
333
- port: 8080,
334
- host: "localhost",
335
- });
336
-
337
- webSocketServer.on('open', () => {
338
- console.log('open');
339
- });
340
-
341
- webSocketServer.on('close', (data) => {
342
- console.log('webSocketServer close: %s', data);
343
- });
344
-
345
- webSocketServer.on('listening', () => {
346
- console.log("webSocketServer listening", webSocketServer.address());
347
- });
348
-
349
- webSocketServer.on('connection', (webSocket: WebSocket) => {
350
- webSocket.on('message', (webSocketData) => {
351
- const payload = JSON.parse(webSocketData.valueOf().toString() as any);
352
- const messageType = payload.type;
353
-
354
- if (messageType === "testeranto:hola") {
355
- const name = payload.data.requirement.name;
356
- const requestedResources = payload.data;
357
-
358
- this.websockets[name] = webSocket
359
- console.log('hola WS! connected: ' + name + ' in ' + Object.getOwnPropertyNames(this.websockets))
360
- this.requestResource(requestedResources.requirement, 'ws');
361
-
362
- } else if (messageType === "testeranto:adios") {
363
- console.log("adios WS", payload.data.testResourceConfiguration.name);
364
- this.releaseTestResourceWs(payload as any);
365
- }
366
-
367
- });
368
- });
369
-
370
- const makePath = (fPath: string, rt: IRunTime): string => {
371
- return path.resolve("./" + config.outdir + "/" + fPath.replace(path.extname(fPath), "") + ".mjs");
372
- };
373
-
374
- const bootInterval = setInterval(async () => {
375
- const filesToLookup = this.tests
376
- .map(([p, rt]) => {
377
- const filepath = makePath(p, rt);
378
- return {
379
- filepath,
380
- exists: fsExists(filepath),
381
- };
382
- });
383
- const allFilesExist = (
384
- await Promise.all(filesToLookup.map((f) => f.exists))
385
- ).every((b) => b);
386
-
387
- if (!allFilesExist) {
388
- console.log(this.spinner(), "waiting for files to build...")
389
- filesToLookup.forEach((f) => {
390
- console.log(f.exists, "\t", f.filepath);
391
- })
392
-
393
- } else {
394
- clearInterval(bootInterval);
395
-
396
- pm2.launchBus((err, pm2_bus) => {
397
- pm2_bus.on("testeranto:hola", (packet: { data: { requirement: ITTestResourceRequirement } }) => {
398
- this.requestResource(
399
- packet.data.requirement,
400
- 'ipc'
401
- );
402
- });
403
-
404
- pm2_bus.on("testeranto:adios", (payload: IAdiosIPC) => {
405
- this.releaseTestResourcePm2(payload.data);
406
- });
407
- });
408
-
409
- this
410
- .tests
411
- .reduce((m, [inputFilePath, runtime]) => {
412
- const script = makePath(inputFilePath, runtime);
413
- const partialTestResourceByCommandLineArg = `${script} '${JSON.stringify(
414
- {
415
- name: inputFilePath,
416
- ports: [],
417
- fs: path.resolve(
418
- process.cwd(),
419
- config.outdir,
420
- inputFilePath
421
- ),
422
- }
423
- )}'`;
424
-
425
- if (runtime === "web") {
426
- const fileAsList = inputFilePath.split("/");
427
- const fileListHead = fileAsList.slice(0, -1);
428
- const fname = fileAsList[fileAsList.length - 1];
429
- const fnameOnly = fname.split(".").slice(0, -1).join(".");
430
- const htmlFile = [config.outdir, ...fileListHead, `${fnameOnly}.html`].join("/");
431
- const jsFile = path.resolve(htmlFile.split(".html")[0] + ".mjs")
432
- console.log("watching", jsFile);
433
-
434
- pm2.start(
435
- {
436
-
437
- script: `yarn electron node_modules/testeranto/dist/common/electron.js ${htmlFile} '${JSON.stringify(
438
- {
439
- scheduled: true,
440
- name: inputFilePath,
441
- ports: [],
442
- fs:
443
- path.resolve(
444
- process.cwd(),
445
- config.outdir,
446
- inputFilePath
447
- ),
448
- }
449
- )}'`,
450
- name: inputFilePath,
451
- autorestart: false,
452
- args: partialTestResourceByCommandLineArg,
453
- watch: [jsFile],
454
- },
455
- (err, proc) => {
456
- if (err) {
457
- console.error(err);
458
- return pm2.disconnect();
459
- }
460
- }
461
- );
462
-
463
- } else if (runtime === "node") {
464
- const resolvedPath = path.resolve(script);
465
-
466
- console.log("watching", resolvedPath);
467
- pm2.start({
468
-
469
- name: inputFilePath,
470
- script: `node ${resolvedPath} '${JSON.stringify(
471
- {
472
- scheduled: true,
473
- name: inputFilePath,
474
- ports: [],
475
- fs:
476
- path.resolve(
477
- process.cwd(),
478
- config.outdir,
479
- inputFilePath
480
- ),
481
- }
482
- )}'`,
483
- autorestart: false,
484
- watch: [resolvedPath],
485
- args: partialTestResourceByCommandLineArg
486
-
487
- }, (err, proc) => {
488
- if (err) {
489
- console.error(err);
490
- return pm2.disconnect();
491
- }
492
- });
493
- }
494
-
495
- this.exitCodes[inputFilePath] = null;
496
- return [inputFilePath, ...m];
497
- }, []);
498
- setInterval(this.mainLoop, TIMEOUT).unref();
499
- }
500
- }, TIMEOUT).unref();
501
- });
502
- }
503
- })
504
- })
505
- })
506
- }
507
-
508
- public requestResource(
509
- requirement: ITTestResourceRequirement,
510
- protocol: ISchedulerProtocols
511
- ) {
512
- this.resourceQueue.push({ requirement, protocol });
513
- }
514
-
515
- public getSecondaryEndpointsPoints(runtime?: IRunTime): string[] {
516
- if (runtime) {
517
- return this.tests
518
- .filter((t) => {
519
- return (t[1] === runtime);
61
+ const childElectron = childProcess.spawn("yarn", ["electron", "node_modules/testeranto/dist/common/electron.js"]);
62
+ // childElectron.stdout.on('data', function (msg) {
63
+ // console.log(msg.toString())
64
+ // });
65
+ const fileStream = fs.createWriteStream(`./${this.config.outdir}/electron.log`);
66
+ childElectron.stdout?.pipe(fileStream);
67
+
68
+ Promise.resolve(Promise.all(
69
+ [
70
+ ...this.getSecondaryEndpointsPoints("web"),
71
+ ]
72
+ .map(async (sourceFilePath) => {
73
+ const sourceFileSplit = sourceFilePath.split("/");
74
+ const sourceDir = sourceFileSplit.slice(0, -1);
75
+ const sourceFileName = sourceFileSplit[sourceFileSplit.length - 1];
76
+ const sourceFileNameMinusJs = sourceFileName.split(".").slice(0, -1).join(".");
77
+
78
+ const htmlFilePath = path.normalize(`${process.cwd()}/${config.outdir}/web/${sourceDir.join("/")}/${sourceFileNameMinusJs}.html`);
79
+ const jsfilePath = `./${sourceFileNameMinusJs}.mjs`;
80
+
81
+ return fs.promises.mkdir(path.dirname(htmlFilePath), { recursive: true }).then(x => fs.writeFileSync(htmlFilePath, webHtmlFrame(jsfilePath, htmlFilePath)
82
+ ))
520
83
  })
521
- .map((tc) => tc[0])
522
- }
84
+ ));
523
85
 
524
- return this.tests
525
- .map((tc) => tc[0])
526
- }
86
+ const [nodeEntryPoints, webEntryPoints] = getRunnables(this.config.tests);
527
87
 
528
- public initiateShutdown(reason: string) {
529
- console.log("Shutdown initiated because", reason);
530
- this.mode = "down";
531
- }
532
-
533
- private shutdown() {
534
- let i = 0;
535
- new Promise((res, reh) => {
536
- console.log("final results: ");
537
- const procsTable: any[] = [];
538
- pm2.list((err, procs) => {
539
- procs.forEach((proc, ndx) => {
540
- const exitCode = this.exitCodes[proc.name as string]
541
- if (exitCode !== 0) {
542
- i++;
543
- }
544
- procsTable.push({
545
- name: proc.name,
546
- pm_id: proc.pm_id,
547
- exitCode
548
- })
549
-
550
- if (ndx === procs.length - 1) {
551
- console.table(procsTable);
552
- res(i)
553
- }
554
- })
88
+ glob(`./${config.outdir}/chunk-*.mjs`, { ignore: 'node_modules/**' }).then((chunks) => {
89
+ console.log("deleting chunks", chunks)
90
+ chunks.forEach((chunk) => {
91
+ console.log("deleting chunk", chunk)
92
+ fs.unlinkSync(chunk);
555
93
  })
556
- }).then((failures: number) => {
557
- pm2.stop("all", (e) => console.error(e));
558
- pm2.disconnect();
559
- console.log(`gracefully exiting with ${failures} failures`)
560
- process.exit(failures);
561
- })
562
- }
563
-
564
- private spinner() {
565
- this.spinCycle = (this.spinCycle + 1) % this.spinAnimation.length;
566
- return this.spinAnimation[this.spinCycle];
567
- }
568
-
569
- private async releaseTestResourceWs(payload: any) {
570
- const name = payload.data.testResourceConfiguration.name;
571
- const failed = payload.data.failed;
572
-
573
- this.exitCodes[name] = failed;
574
-
575
- Object.keys(this.ports).forEach((port: string) => {
576
- if (this.ports[port] === name) {
577
- this.ports[port] = OPEN_PORT;
578
- }
579
- });
580
- }
581
-
582
- private async releaseTestResourcePm2(payload: IAdios) {
583
- const name = payload.testResourceConfiguration.name;
584
- const failed = payload.failed;
585
94
 
586
- this.exitCodes[name] = failed;
95
+ })
587
96
 
588
- pm2.list((err, processes) => {
589
- processes.forEach((proc: pm2.ProcessDescription) => {
590
- if (proc.name === name) {
591
- Object.keys(this.ports).forEach((port: string) => {
592
- if (this.ports[port] === name) {
593
- this.ports[port] = OPEN_PORT;
594
- }
595
- });
596
- }
97
+ fs.copyFileSync("node_modules/testeranto/dist/prebuild/report.js", "./docs/Report.js")
98
+ fs.copyFileSync("node_modules/testeranto/dist/prebuild/report.css", "./docs/Report.css")
99
+
100
+ fs.writeFileSync(`${config.outdir}/report.html`, reportHtmlFrame());
101
+
102
+ Promise.all([
103
+ esbuild.context(esbuildFeaturesConfiger(config))
104
+ .then(async (featuresContext) => {
105
+ console.log("features entry points", config.features);
106
+ await featuresContext.watch();
107
+ return featuresContext;
108
+ }),
109
+ esbuild.context(esbuildNodeConfiger(config, nodeEntryPoints))
110
+ .then(async (nodeContext) => {
111
+ console.log("node entry points", nodeEntryPoints);
112
+ await nodeContext.watch();
113
+ return nodeContext;
114
+ }),
115
+ esbuild.context(esbuildWebConfiger(config, webEntryPoints))
116
+ .then(async (esbuildWeb) => {
117
+ console.log("web entry points", webEntryPoints);
118
+ await esbuildWeb.watch();
119
+ return esbuildWeb;
120
+ }),
121
+
122
+ ]).then(async (contexts) => {
123
+ Promise.all(
124
+ config.tests.map(async ([test, runtime]) => {
125
+ return {
126
+ test,
127
+ runtime
128
+ };
129
+ })
130
+ ).then(async (modules) => {
131
+ fs.writeFileSync(`${config.outdir}/testeranto.json`, JSON.stringify(
132
+ {
133
+ modules,
134
+ buildDir: process.cwd() + "/" + config.outdir
135
+ }, null, 2));
597
136
  });
598
- });
599
- }
600
137
 
601
- private allocateViaWs(resourceRequest: {
602
- requirement: ITTestResourceRequirement;
603
- protocol: ISchedulerProtocols;
604
- }) {
605
-
606
- const name = resourceRequest.requirement.name;
607
- const testResourceRequirement = resourceRequest.requirement;
608
-
609
- const websocket = this.websockets[name];
610
-
611
- if (testResourceRequirement?.ports === 0) {
612
- websocket.send(JSON.stringify({
613
- data: {
614
- testResourceConfiguration: {
615
- ports: [],
616
- },
617
- }
618
- }));
619
- } else if ((testResourceRequirement?.ports || 0) > 0) {
620
- // clear any port-slots associated with this job
621
- Object.values(this.ports).forEach((jobMaybe, portNumber) => {
622
- if (jobMaybe && jobMaybe === name) {
623
- this.ports[portNumber] = OPEN_PORT;
624
- }
625
- });
138
+ if (config.devMode === false) {
139
+ console.log("Your tests were built but not run because devMode was false. Exiting gracefully");
140
+ process.exit(0);
626
141
 
627
- // find a list of open ports
628
- const foundOpenPorts = Object.keys(this.ports).filter(
629
- (p) => this.ports[p] === OPEN_PORT
630
- );
631
-
632
- if (foundOpenPorts.length >= testResourceRequirement.ports) {
633
- const selectionOfPorts = foundOpenPorts.slice(
634
- 0,
635
- testResourceRequirement.ports
636
- );
637
-
638
- websocket.send(JSON.stringify({
639
- data: {
640
- testResourceConfiguration: {
641
- ports: selectionOfPorts,
642
- },
643
- }
644
- }));
645
-
646
- // mark the selected ports as occupied
647
- for (const foundOpenPort of selectionOfPorts) {
648
- this.ports[foundOpenPort] = name;
649
- }
650
142
  } else {
651
- console.log(
652
- `no port was open so send the ${name} job to the back of the resourceQueue`
653
- );
654
- this.resourceQueue.push(resourceRequest);
143
+ // no-op
655
144
  }
656
- }
657
- }
658
-
659
- private allocateViaIpc(resourceRequest: {
660
- requirement: ITTestResourceRequirement;
661
- protocol: ISchedulerProtocols;
662
- }) {
663
- const pName = resourceRequest.requirement.name;
664
- const testResourceRequirement = resourceRequest.requirement;
665
-
666
- pm2.list((err, processes) => {
667
- console.error(err);
668
- processes.forEach((p) => {
669
- if (p.name === pName && p.pid) {
670
- const message = {
671
- // these fields must be present
672
- id: p.pid,
673
- topic: "some topic",
674
- type: "process:msg",
675
-
676
- // Data to be sent
677
- data: {
678
- testResourceConfiguration: {
679
- ports: [],
680
- // fs: fPath,
681
- },
682
- id: p.pm_id,
683
- },
684
- };
685
-
686
- if (testResourceRequirement?.ports === 0) {
687
- pm2.sendDataToProcessId(
688
- p.pm_id as number,
689
- message,
690
- function (err, res) {
691
- // console.log("sendDataToProcessId", err, res, message);
692
- }
693
- );
694
- }
695
-
696
- if ((testResourceRequirement?.ports || 0) > 0) {
697
- // clear any port-slots associated with this job
698
- Object.values(this.ports).forEach((jobMaybe, portNumber) => {
699
- if (jobMaybe && jobMaybe === pName) {
700
- this.ports[portNumber] = OPEN_PORT;
701
- }
702
- });
703
-
704
- // find a list of open ports
705
- const foundOpenPorts = Object.keys(this.ports).filter(
706
- (p) => this.ports[p] === OPEN_PORT
707
- );
708
- // if there are enough open port-slots...
709
- if (foundOpenPorts.length >= testResourceRequirement.ports) {
710
- const selectionOfPorts = foundOpenPorts.slice(
711
- 0,
712
- testResourceRequirement.ports
713
- );
714
-
715
- const message = {
716
- // these fields must be present
717
- id: p.pid, // id of process from "pm2 list" command or from pm2.list(errback) method
718
- topic: "some topic",
719
- // process:msg will be send as 'message' on target process
720
- type: "process:msg",
721
-
722
- // Data to be sent
723
- data: {
724
- testResourceConfiguration: {
725
- // fs: fPath,
726
- ports: selectionOfPorts,
727
- },
728
- id: p.pid,
729
- },
730
- };
731
- pm2.sendDataToProcessId(
732
- p.pm_id as number,
733
- message,
734
- function (err, res) {
735
- // no-op
736
- }
737
- );
738
- // mark the selected ports as occupied
739
- for (const foundOpenPort of selectionOfPorts) {
740
- this.ports[foundOpenPort] = p.pid.toString();
741
- }
742
- } else {
743
- console.log(
744
- `no port was open so send the ${p.pid} job to the back of the resourceQueue`
745
- );
746
- this.resourceQueue.push(resourceRequest);
747
- }
748
- }
749
- }
750
- })
751
145
  })
752
146
  }
753
147
 
754
- private mainLoop = async () => {
755
- if (this.clearScreen) {
756
- console.clear();
757
- }
758
-
759
- const procsTable: any[] = [];
760
- pm2.list((err, procs) => {
761
- procs.forEach((proc) => {
762
- procsTable.push({
763
- name: proc.name,
764
- pid: proc.pid,
765
- pm_id: proc.pm_id,
766
- mem: proc.monit?.memory,
767
- cpu: proc.monit?.cpu,
768
- "exit code": this.exitCodes[proc.name as string]
769
- })
770
- })
771
- console.table(procsTable);
772
-
773
- console.table(this.resourceQueue);
774
- console.log("webSocketServer.clients", Object.keys(this.websockets));
775
-
776
- const resourceRequest = this.resourceQueue.pop();
777
-
778
- if (!resourceRequest) {
779
- if (!this.devMode && this.mode === "up") {
780
- this.initiateShutdown("resource request queue is empty");
781
- }
148
+ public getSecondaryEndpointsPoints(runtime?: IRunTime): string[] {
782
149
 
783
- if (
784
- this.mode === "down" &&
785
- (
786
- procsTable.every(
787
- (p) => p.pid === 0 || p.pid === undefined
788
- ) ||
789
- procsTable.length === 0
790
- )
791
- ) {
792
- this.shutdown();
150
+ const meta = (ts: ITestTypes[], st: Set<string>): Set<string> => {
151
+ ts.forEach((t) => {
152
+ if (t[1] === runtime) {
153
+ st.add(t[0]);
793
154
  }
794
- } else {
795
- if (resourceRequest.protocol === "ipc") {
796
- this.allocateViaIpc(resourceRequest)
797
- } else if (resourceRequest.protocol === "ws") {
798
- this.allocateViaWs(resourceRequest)
155
+ if (Array.isArray(t[2])) {
156
+ meta(t[2], st);
799
157
  }
800
- }
158
+ })
159
+ return st;
160
+ }
161
+ return Array.from(meta(this.config.tests, new Set()));
162
+ }
801
163
 
802
- const upMessage = "Running tests while watching for changes. Use 'q' to initiate shutdown and `x` to kill.";
803
- const downMessage = "Shutdown is in progress. Please wait.";
804
- if (this.devMode) {
805
- if (this.mode === "up") {
806
- console.log(this.spinner(), upMessage);
807
- } else {
808
- console.log(this.spinner(), downMessage);
809
- }
164
+ public initiateShutdown(reason: string) {
165
+ console.log("Shutdown initiated because", reason);
166
+ this.mode = "down";
167
+ }
810
168
 
811
- } else {
812
- if (this.mode === "up") {
813
- console.log(this.spinner(), upMessage);
814
- } else {
815
- console.log(this.spinner(), downMessage);
816
- }
817
- }
818
- });
819
- };
169
+ // private shutdown() {
170
+ // let i = 0;
171
+ // new Promise((res, reh) => {
172
+ // console.log("final results: ");
173
+ // const procsTable: any[] = [];
174
+ // // pm2.list((err, procs) => {
175
+ // // procs.forEach((proc, ndx) => {
176
+ // // const exitCode = this.exitCodes[proc.name as string]
177
+ // // if (exitCode !== 0) {
178
+ // // i++;
179
+ // // }
180
+ // // procsTable.push({
181
+ // // name: proc.name,
182
+ // // pm_id: proc.pm_id,
183
+ // // exitCode
184
+ // // })
185
+
186
+ // // if (ndx === procs.length - 1) {
187
+ // // console.table(procsTable);
188
+ // // res(i)
189
+ // // }
190
+ // // })
191
+ // // })
192
+ // }).then((failures: number) => {
193
+ // // pm2.stop("all", (e) => console.error(e));
194
+ // // pm2.disconnect();
195
+ // console.log(`gracefully exiting with ${failures} failures`)
196
+ // process.exit(failures);
197
+ // })
198
+ // }
199
+
200
+ // private spinner() {
201
+ // this.spinCycle = (this.spinCycle + 1) % this.spinAnimation.length;
202
+ // return this.spinAnimation[this.spinCycle];
203
+ // }
204
+
205
+ // private async releaseTestResourceWs(payload: any) {
206
+ // const name = payload.data.testResourceConfiguration.name;
207
+ // const failed = payload.data.failed;
208
+
209
+ // this.exitCodes[name] = failed;
210
+
211
+ // Object.keys(this.ports).forEach((port: string) => {
212
+ // if (this.ports[port] === name) {
213
+ // this.ports[port] = OPEN_PORT;
214
+ // }
215
+ // });
216
+ // }
217
+
218
+ // private async releaseTestResourcePm2(payload: IAdios) {
219
+ // const name = payload.testResourceConfiguration.name;
220
+ // const failed = payload.failed;
221
+
222
+ // this.exitCodes[name] = failed;
223
+
224
+ // // pm2.list((err, processes) => {
225
+ // // processes.forEach((proc: pm2.ProcessDescription) => {
226
+ // // if (proc.name === name) {
227
+ // // Object.keys(this.ports).forEach((port: string) => {
228
+ // // if (this.ports[port] === name) {
229
+ // // this.ports[port] = OPEN_PORT;
230
+ // // }
231
+ // // });
232
+ // // }
233
+ // // });
234
+ // // });
235
+ // }
236
+
237
+ // private allocateViaWs(resourceRequest: {
238
+ // requirement: ITTestResourceRequirement;
239
+ // protocol: ISchedulerProtocols;
240
+ // }) {
241
+
242
+ // const name = resourceRequest.requirement.name;
243
+ // const testResourceRequirement = resourceRequest.requirement;
244
+
245
+ // const websocket = this.websockets[name];
246
+
247
+ // if (testResourceRequirement?.ports === 0) {
248
+ // websocket.send(JSON.stringify({
249
+ // data: {
250
+ // testResourceConfiguration: {
251
+ // ports: [],
252
+ // },
253
+ // }
254
+ // }));
255
+ // } else if ((testResourceRequirement?.ports || 0) > 0) {
256
+ // // clear any port-slots associated with this job
257
+ // Object.values(this.ports).forEach((jobMaybe, portNumber) => {
258
+ // if (jobMaybe && jobMaybe === name) {
259
+ // this.ports[portNumber] = OPEN_PORT;
260
+ // }
261
+ // });
262
+
263
+ // // find a list of open ports
264
+ // const foundOpenPorts = Object.keys(this.ports).filter(
265
+ // (p) => this.ports[p] === OPEN_PORT
266
+ // );
267
+
268
+ // if (foundOpenPorts.length >= testResourceRequirement.ports) {
269
+ // const selectionOfPorts = foundOpenPorts.slice(
270
+ // 0,
271
+ // testResourceRequirement.ports
272
+ // );
273
+
274
+ // websocket.send(JSON.stringify({
275
+ // data: {
276
+ // testResourceConfiguration: {
277
+ // ports: selectionOfPorts,
278
+ // },
279
+ // }
280
+ // }));
281
+
282
+ // // mark the selected ports as occupied
283
+ // for (const foundOpenPort of selectionOfPorts) {
284
+ // this.ports[foundOpenPort] = name;
285
+ // }
286
+ // } else {
287
+ // console.log(
288
+ // `no port was open so send the ${name} job to the back of the resourceQueue`
289
+ // );
290
+ // this.resourceQueue.push(resourceRequest);
291
+ // }
292
+ // }
293
+ // }
294
+
295
+ // private allocateViaIpc(resourceRequest: {
296
+ // requirement: ITTestResourceRequirement;
297
+ // protocol: ISchedulerProtocols;
298
+ // }) {
299
+ // const pName = resourceRequest.requirement.name;
300
+ // const testResourceRequirement = resourceRequest.requirement;
301
+
302
+ // // pm2.list((err, processes) => {
303
+ // // console.error(err);
304
+ // // processes.forEach((p) => {
305
+ // // if (p.name === pName && p.pid) {
306
+ // // const message = {
307
+ // // // these fields must be present
308
+ // // id: p.pid,
309
+ // // topic: "some topic",
310
+ // // type: "process:msg",
311
+
312
+ // // // Data to be sent
313
+ // // data: {
314
+ // // testResourceConfiguration: {
315
+ // // ports: [],
316
+ // // // fs: fPath,
317
+ // // },
318
+ // // id: p.pm_id,
319
+ // // },
320
+ // // };
321
+
322
+ // // if (testResourceRequirement?.ports === 0) {
323
+ // // pm2.sendDataToProcessId(
324
+ // // p.pm_id as number,
325
+ // // message,
326
+ // // function (err, res) {
327
+ // // // console.log("sendDataToProcessId", err, res, message);
328
+ // // }
329
+ // // );
330
+ // // }
331
+
332
+ // // if ((testResourceRequirement?.ports || 0) > 0) {
333
+ // // // clear any port-slots associated with this job
334
+ // // Object.values(this.ports).forEach((jobMaybe, portNumber) => {
335
+ // // if (jobMaybe && jobMaybe === pName) {
336
+ // // this.ports[portNumber] = OPEN_PORT;
337
+ // // }
338
+ // // });
339
+
340
+ // // // find a list of open ports
341
+ // // const foundOpenPorts = Object.keys(this.ports).filter(
342
+ // // (p) => this.ports[p] === OPEN_PORT
343
+ // // );
344
+ // // // if there are enough open port-slots...
345
+ // // if (foundOpenPorts.length >= testResourceRequirement.ports) {
346
+ // // const selectionOfPorts = foundOpenPorts.slice(
347
+ // // 0,
348
+ // // testResourceRequirement.ports
349
+ // // );
350
+
351
+ // // const message = {
352
+ // // // these fields must be present
353
+ // // id: p.pid, // id of process from "pm2 list" command or from pm2.list(errback) method
354
+ // // topic: "some topic",
355
+ // // // process:msg will be send as 'message' on target process
356
+ // // type: "process:msg",
357
+
358
+ // // // Data to be sent
359
+ // // data: {
360
+ // // testResourceConfiguration: {
361
+ // // // fs: fPath,
362
+ // // ports: selectionOfPorts,
363
+ // // },
364
+ // // id: p.pid,
365
+ // // },
366
+ // // };
367
+ // // pm2.sendDataToProcessId(
368
+ // // p.pm_id as number,
369
+ // // message,
370
+ // // function (err, res) {
371
+ // // // no-op
372
+ // // }
373
+ // // );
374
+ // // // mark the selected ports as occupied
375
+ // // for (const foundOpenPort of selectionOfPorts) {
376
+ // // this.ports[foundOpenPort] = p.pid.toString();
377
+ // // }
378
+ // // } else {
379
+ // // console.log(
380
+ // // `no port was open so send the ${p.pid} job to the back of the resourceQueue`
381
+ // // );
382
+ // // this.resourceQueue.push(resourceRequest);
383
+ // // }
384
+ // // }
385
+ // // }
386
+ // // })
387
+ // // })
388
+ // }
389
+
390
+ // private mainLoop = async () => {
391
+ // if (this.clearScreen) {
392
+ // console.clear();
393
+ // }
394
+
395
+ // const procsTable: any[] = [];
396
+ // // pm2.list((err, procs) => {
397
+ // // procs.forEach((proc) => {
398
+ // // procsTable.push({
399
+ // // name: proc.name,
400
+ // // pid: proc.pid,
401
+ // // pm_id: proc.pm_id,
402
+ // // mem: proc.monit?.memory,
403
+ // // cpu: proc.monit?.cpu,
404
+ // // "exit code": this.exitCodes[proc.name as string]
405
+ // // })
406
+ // // })
407
+ // // console.table(procsTable);
408
+
409
+ // // console.table(this.resourceQueue);
410
+ // // console.log("webSocketServer.clients", Object.keys(this.websockets));
411
+
412
+ // // const resourceRequest = this.resourceQueue.pop();
413
+
414
+ // // if (!resourceRequest) {
415
+ // // if (!this.devMode && this.mode === "up") {
416
+ // // this.initiateShutdown("resource request queue is empty");
417
+ // // }
418
+
419
+ // // if (
420
+ // // this.mode === "down" &&
421
+ // // (
422
+ // // procsTable.every(
423
+ // // (p) => p.pid === 0 || p.pid === undefined
424
+ // // ) ||
425
+ // // procsTable.length === 0
426
+ // // )
427
+ // // ) {
428
+ // // this.shutdown();
429
+ // // }
430
+ // // } else {
431
+ // // if (resourceRequest.protocol === "ipc") {
432
+ // // this.allocateViaIpc(resourceRequest)
433
+ // // } else if (resourceRequest.protocol === "ws") {
434
+ // // this.allocateViaWs(resourceRequest)
435
+ // // }
436
+ // // }
437
+
438
+ // // const upMessage = `
439
+ // // Running tests while watching for changes.
440
+ // // Use 'q' to initiate shutdown and 'x' to kill.
441
+ // // esbuild web server - ${JSON.stringify(this.esWebServerDetails)}
442
+ // // `;
443
+ // // const downMessage = "Shutdown is in progress. Please wait.";
444
+ // // if (this.devMode) {
445
+ // // if (this.mode === "up") {
446
+ // // console.log(this.spinner(), upMessage);
447
+ // // } else {
448
+ // // console.log(this.spinner(), downMessage);
449
+ // // }
450
+
451
+ // // } else {
452
+ // // if (this.mode === "up") {
453
+ // // console.log(this.spinner(), upMessage);
454
+ // // } else {
455
+ // // console.log(this.spinner(), downMessage);
456
+ // // }
457
+ // // }
458
+ // // });
459
+ // };
820
460
  }
461
+
462
+ // pm2.connect(async (err) => {
463
+ // if (err) {
464
+ // console.error(err);
465
+ // process.exit(-1);
466
+ // } else {
467
+ // console.log(`pm2 is connected`);
468
+ // }
469
+
470
+ // // run a websocket as an alternative to node IPC
471
+ // webSocketServer = new WebSocketServer({
472
+ // port: 8080,
473
+ // host: "localhost",
474
+ // });
475
+
476
+ // webSocketServer.on('open', () => {
477
+ // console.log('open');
478
+ // });
479
+
480
+ // webSocketServer.on('close', (data) => {
481
+ // console.log('webSocketServer close: %s', data);
482
+ // });
483
+
484
+ // webSocketServer.on('listening', () => {
485
+ // console.log("webSocketServer listening", webSocketServer.address());
486
+ // });
487
+
488
+ // webSocketServer.on('connection', (webSocket: WebSocket) => {
489
+ // webSocket.on('message', (webSocketData) => {
490
+ // const payload = JSON.parse(webSocketData.valueOf().toString() as any);
491
+ // const messageType = payload.type;
492
+
493
+ // if (messageType === "testeranto:hola") {
494
+ // const name = payload.data.requirement.name;
495
+ // const requestedResources = payload.data;
496
+
497
+ // this.websockets[name] = webSocket
498
+ // console.log('hola WS! connected: ' + name + ' in ' + Object.getOwnPropertyNames(this.websockets))
499
+ // this.requestResource(requestedResources.requirement, 'ws');
500
+
501
+ // } else if (messageType === "testeranto:adios") {
502
+ // console.log("adios WS", payload.data.testResourceConfiguration.name);
503
+ // this.releaseTestResourceWs(payload as any);
504
+ // }
505
+
506
+ // });
507
+ // });
508
+
509
+ // const makePath = (fPath: string, rt: IRunTime): string => {
510
+ // return path.resolve("./" + config.outdir + "/" +
511
+ // rt +
512
+ // // (rt === "electron" || rt === "chromium" ? "web" : "node") +
513
+ // "/" + fPath.replace(path.extname(fPath), "") + ".mjs");
514
+ // };
515
+
516
+ // const bootInterval = setInterval(async () => {
517
+ // const filesToLookup = this.tests
518
+ // .map(([p, rt]) => {
519
+ // const filepath = makePath(p, rt);
520
+ // return {
521
+ // filepath,
522
+ // exists: fsExists(filepath),
523
+ // };
524
+ // });
525
+ // const allFilesExist = (
526
+ // await Promise.all(filesToLookup.map((f) => f.exists))
527
+ // ).every((b) => b);
528
+
529
+ // if (!allFilesExist) {
530
+ // console.log(this.spinner(), "waiting for files to build...")
531
+ // filesToLookup.forEach((f) => {
532
+ // console.log(f.exists, "\t", f.filepath);
533
+ // })
534
+
535
+ // } else {
536
+ // clearInterval(bootInterval);
537
+
538
+ // pm2.launchBus((err, pm2_bus) => {
539
+ // pm2_bus.on("testeranto:hola", (packet: { data: { requirement: ITTestResourceRequirement } }) => {
540
+ // this.requestResource(
541
+ // packet.data.requirement,
542
+ // 'ipc'
543
+ // );
544
+ // });
545
+
546
+ // pm2_bus.on("testeranto:adios", (payload: IAdiosIPC) => {
547
+ // this.releaseTestResourcePm2(payload.data);
548
+ // });
549
+ // });
550
+
551
+ // this
552
+ // .tests
553
+ // .reduce((m, [inputFilePath, runtime]) => {
554
+ // const script = makePath(inputFilePath, runtime);
555
+ // const partialTestResourceByCommandLineArg = `${script} '${JSON.stringify(
556
+ // {
557
+ // name: inputFilePath,
558
+ // ports: [],
559
+ // fs: path.resolve(
560
+ // process.cwd(),
561
+ // config.outdir,
562
+ // inputFilePath
563
+ // ),
564
+ // }
565
+ // )}'`;
566
+
567
+ // if (runtime === "web") {
568
+ // pm2.start(electron_pm2_StartOptions(
569
+ // partialTestResourceByCommandLineArg,
570
+ // inputFilePath,
571
+ // config
572
+ // ),
573
+ // (err, proc) => {
574
+ // if (err) {
575
+ // console.error(err);
576
+ // return pm2.disconnect();
577
+ // }
578
+ // }
579
+ // );
580
+
581
+ // // } else if (runtime === "chromium") {
582
+ // // pm2.start(
583
+ // // chromium_pm2_StartOptions(
584
+ // // partialTestResourceByCommandLineArg,
585
+ // // inputFilePath,
586
+ // // config,
587
+ // // ),
588
+ // // (err, proc) => {
589
+ // // if (err) {
590
+ // // console.error(err);
591
+ // // return pm2.disconnect();
592
+ // // }
593
+ // // }
594
+ // // );
595
+
596
+ // } else if (runtime === "node") {
597
+ // const resolvedPath = path.resolve(script);
598
+
599
+ // console.log("watching", resolvedPath);
600
+ // pm2.start(node_pm2_StartOptions(
601
+ // partialTestResourceByCommandLineArg,
602
+ // inputFilePath,
603
+ // config,
604
+ // resolvedPath
605
+ // ), (err, proc) => {
606
+ // if (err) {
607
+ // console.error(err);
608
+ // return pm2.disconnect();
609
+ // }
610
+ // });
611
+ // }
612
+
613
+ // this.exitCodes[inputFilePath] = null;
614
+ // return [inputFilePath, ...m];
615
+ // }, []);
616
+ // setInterval(this.mainLoop, TIMEOUT).unref();
617
+ // }
618
+ // }, TIMEOUT).unref();
619
+ // });
620
+ // public requestResource(
621
+ // requirement: ITTestResourceRequirement,
622
+ // protocol: ISchedulerProtocols
623
+ // ) {
624
+ // this.resourceQueue.push({ requirement, protocol });
625
+ // }
626
+ // const OPEN_PORT = "";
627
+
628
+ // type ISchedulerProtocols = `ipc` | `ws`;
629
+
630
+ // type IAdios = {
631
+ // name: string;
632
+ // failed: any;
633
+ // testResourceConfiguration: {
634
+ // name: string;
635
+ // };
636
+ // results: {
637
+ // fails: any[];
638
+ // givens: any[];
639
+ // name: string;
640
+ // };
641
+ // };
642
+
643
+ // type IAdiosIPC = {
644
+ // process: {
645
+ // namespace: string;
646
+ // versioning: object;
647
+ // name: string;
648
+ // pm_id: number;
649
+ // };
650
+ // data: IAdios
651
+ // at: string;
652
+ // };
653
+ // clearScreen: boolean;
654
+ // devMode: boolean;
655
+ // exitCodes: Record<number, string> = {};
656
+ // features: TesterantoFeatures;
657
+
658
+ // ports: Record<string, string> = {};
659
+ // tests: ITestTypes[];
660
+ // websockets: Record<string, WebSocket> = {};
661
+
662
+ // resourceQueue: {
663
+ // requirement: ITTestResourceRequirement,
664
+ // protocol: ISchedulerProtocols,
665
+ // }[] = [];
666
+
667
+ // private spinCycle = 0;
668
+ // private spinAnimation = "←↖↑↗→↘↓↙";
669
+ // console.log("sending", JSON.stringify(this.tests));
670
+ // childElectron.stdin.write(JSON.stringify(this.tests));
671
+ // not necessary
672
+ // this.esWebServerDetails = await eWeb.serve({
673
+ // servedir: jsonConfig.outdir,
674
+ // });
675
+
676
+ // fs.copyFileSync("node_modules/testeranto/dist/index.css", "index.css")
677
+ //