testeranto 0.172.0 → 0.173.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.
- package/README.md +2 -4
- package/dist/common/src/PM/base.js +4 -0
- package/dist/common/src/PM/main.js +11 -4
- package/dist/common/src/PM/node.js +1 -1
- package/dist/common/src/PM/web.js +3 -3
- package/dist/common/src/ReportServer.js +2 -126
- package/dist/common/src/ReportServer.test.ts/index.js +78 -0
- package/dist/common/src/ReportServerLib.js +135 -0
- package/dist/common/src/components/pure/ProjectPageView.test/implementation.js +1 -1
- package/dist/common/src/lib/abstractBase.js +2 -0
- package/dist/common/src/lib/baseBuilder.test/baseBuilder.test.implementation.js +10 -9
- package/dist/common/src/lib/baseBuilder.test/baseBuilder.test.specification.js +7 -7
- package/dist/common/src/lib/basebuilder.js +8 -2
- package/dist/common/src/lib/pmProxy.js +54 -150
- package/dist/common/testeranto.config.js +35 -20
- package/dist/common/tsconfig.common.tsbuildinfo +1 -1
- package/dist/module/src/PM/base.js +4 -0
- package/dist/module/src/PM/main.js +11 -4
- package/dist/module/src/PM/node.js +1 -1
- package/dist/module/src/PM/web.js +3 -3
- package/dist/module/src/ReportServer.js +2 -123
- package/dist/module/src/ReportServer.test.ts/index.js +73 -0
- package/dist/module/src/ReportServerLib.js +128 -0
- package/dist/module/src/TestPage.js +29 -17
- package/dist/module/src/components/pure/ProjectPageView.test/implementation.js +1 -1
- package/dist/module/src/components/pure/TestPageView.js +29 -17
- package/dist/module/src/lib/abstractBase.js +2 -0
- package/dist/module/src/lib/baseBuilder.test/baseBuilder.test.implementation.js +10 -9
- package/dist/module/src/lib/baseBuilder.test/baseBuilder.test.specification.js +7 -7
- package/dist/module/src/lib/basebuilder.js +8 -2
- package/dist/module/src/lib/pmProxy.js +54 -150
- package/dist/module/testeranto.config.js +35 -20
- package/dist/module/tsconfig.module.tsbuildinfo +1 -1
- package/dist/prebuild/App.js +3 -3
- package/dist/prebuild/ReportServer.mjs +15 -9
- package/dist/prebuild/run.mjs +14 -4
- package/dist/types/src/PM/node.d.ts +1 -1
- package/dist/types/src/PM/web.d.ts +1 -1
- package/dist/types/src/ReportServer.test.ts/index.d.ts +29 -0
- package/dist/types/src/ReportServerLib.d.ts +2 -0
- package/dist/types/src/Types.d.ts +0 -1
- package/dist/types/src/components/pure/ProjectPageView.test/index.d.ts +2 -1
- package/dist/types/src/lib/abstractBase.d.ts +1 -1
- package/dist/types/src/lib/baseBuilder.test/baseBuilder.test.types.d.ts +7 -4
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/PM/base.ts +5 -0
- package/src/PM/main.ts +12 -4
- package/src/PM/node.ts +1 -1
- package/src/PM/web.ts +3 -3
- package/src/ReportServer.test.ts/index.ts +194 -0
- package/src/ReportServer.ts +2 -132
- package/src/ReportServerLib.ts +144 -0
- package/src/TestPage.tsx +65 -5
- package/src/Types.ts +0 -1
- package/src/components/pure/ProjectPageView.test/implementation.tsx +1 -1
- package/src/components/pure/TestPageView.tsx +65 -5
- package/src/lib/abstractBase.ts +4 -1
- package/src/lib/baseBuilder.test/baseBuilder.test.implementation.ts +22 -10
- package/src/lib/baseBuilder.test/baseBuilder.test.specification.ts +9 -9
- package/src/lib/baseBuilder.test/baseBuilder.test.types.ts +7 -4
- package/src/lib/basebuilder.ts +7 -4
- package/src/lib/pmProxy.ts +78 -155
- package/testeranto/App.js +3 -3
- package/testeranto/bundles/node/allTests/metafile.json +38 -781
- package/testeranto/bundles/node/allTests/src/lib/baseBuilder.test/baseBuilder.test.node.mjs +983 -24
- package/testeranto/bundles/node/core/metafile.json +486 -0
- package/testeranto/bundles/{pure/allTests/chunk-VMUSFSZM.mjs → node/core/src/lib/baseBuilder.test/baseBuilder.test.node.mjs} +797 -412
- package/testeranto/bundles/node/staticSite/metafile.json +593 -0
- package/testeranto/bundles/node/staticSite/src/ReportServer.test.ts/index.mjs +1594 -0
- package/testeranto/bundles/pure/allTests/metafile.json +122 -550
- package/testeranto/bundles/pure/allTests/src/lib/baseBuilder.test/baseBuilder.test.pure.mjs +740 -27
- package/testeranto/bundles/pure/core/metafile.json +626 -0
- package/testeranto/bundles/{node/allTests/chunk-E75CSRER.mjs → pure/core/src/lib/baseBuilder.test/baseBuilder.test.pure.mjs} +777 -483
- package/testeranto/bundles/pure/staticSite/metafile.json +8 -0
- package/testeranto/bundles/web/allTests/metafile.json +777 -22
- package/testeranto/bundles/web/allTests/src/lib/baseBuilder.test/baseBuilder.test.web.mjs +893 -45
- package/testeranto/bundles/web/core/metafile.json +780 -0
- package/testeranto/bundles/web/core/src/lib/baseBuilder.test/baseBuilder.test.web.html +19 -0
- package/testeranto/bundles/web/{allTests/chunk-U7AW26HL.mjs → core/src/lib/baseBuilder.test/baseBuilder.test.web.mjs} +506 -411
- package/testeranto/bundles/web/staticSite/metafile.json +8 -0
- package/testeranto/projects.json +2 -1
- package/testeranto/reports/allTests/config.json +0 -64
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/lint_errors.txt +2 -0
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/logs.txt +11 -13
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/prompt.txt +10 -0
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/suite-0/given-testInitialization/then-0/butThen/hello.txt +1 -0
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/tests.json +10 -18
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/type_errors.txt +25 -13
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.pure/pure/lint_errors.txt +2 -0
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.pure/pure/prompt.txt +8 -0
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.pure/pure/type_errors.txt +24 -12
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/lint_errors.txt +2 -0
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/logs.txt +49 -55
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/prompt.txt +12 -2
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/suite-0/given-testInitialization/then-0/butThen/hello.txt +1 -0
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/tests.json +10 -18
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/type_errors.txt +24 -12
- package/testeranto/reports/allTests/summary.json +6 -62
- package/testeranto/reports/core/config.json +24 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.node/node/lint_errors.txt +2 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.node/node/logs.txt +32 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.node/node/message.txt +2 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.node/node/prompt.txt +26 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.node/node/suite-0/given-testInitialization/then-0/butThen/hello.txt +1 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.node/node/tests.json +69 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.node/node/type_errors.txt +74 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.pure/pure/lint_errors.txt +2 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.pure/pure/message.txt +2 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.pure/pure/prompt.txt +26 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.pure/pure/type_errors.txt +74 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.web/web/lint_errors.txt +2 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.web/web/logs.txt +61 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.web/web/message.txt +2 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.web/web/prompt.txt +26 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.web/web/suite-0/given-testInitialization/then-0/butThen/hello.txt +1 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.web/web/tests.json +69 -0
- package/testeranto/reports/core/src/lib/baseBuilder.test/baseBuilder.test.web/web/type_errors.txt +74 -0
- package/testeranto/reports/core/summary.json +23 -0
- package/testeranto/reports/staticSite/config.json +24 -0
- package/testeranto/reports/staticSite/src/ReportServer.test.ts/index/node/lint_errors.txt +5 -0
- package/testeranto/reports/staticSite/src/ReportServer.test.ts/index/node/logs.txt +44 -0
- package/testeranto/reports/staticSite/src/ReportServer.test.ts/index/node/message.txt +2 -0
- package/testeranto/reports/staticSite/src/ReportServer.test.ts/index/node/prompt.txt +23 -0
- package/testeranto/reports/{allTests/src/lib/core.test/core.test → staticSite/src/ReportServer.test.ts/index}/node/type_errors.txt +21 -32
- package/testeranto/reports/staticSite/summary.json +9 -0
- package/testeranto/reportsnode_build_errors +8 -11
- package/testeranto.config.ts +37 -20
- package/testeranto/bundles/node/allTests/chunk-3EUGBAOM.mjs +0 -113
- package/testeranto/bundles/node/allTests/chunk-M6DO7VMB.mjs +0 -252
- package/testeranto/bundles/node/allTests/src/lib/BaseSuite.test/node.test.mjs +0 -323
- package/testeranto/bundles/node/allTests/src/lib/classBuilder.test/classBuilder.test.mjs +0 -411
- package/testeranto/bundles/node/allTests/src/lib/core.test/core.test.mjs +0 -528
- package/testeranto/bundles/node/allTests/src/lib/pmProxy.test/index.mjs +0 -4752
- package/testeranto/bundles/pure/allTests/chunk-KHDVEHF7.mjs +0 -185
- package/testeranto/bundles/pure/allTests/src/Pure.test.mjs +0 -429
- package/testeranto/bundles/pure/allTests/src/lib/BaseSuite.test/pure.test.mjs +0 -425
- package/testeranto/bundles/web/allTests/chunk-HPYA4YZC.mjs +0 -2283
- package/testeranto/bundles/web/allTests/src/components/pure/ProjectPageView.test/index.html +0 -19
- package/testeranto/bundles/web/allTests/src/components/pure/ProjectPageView.test/index.mjs +0 -37524
- package/testeranto/bundles/web/allTests/src/lib/BaseSuite.test/web.test.html +0 -19
- package/testeranto/bundles/web/allTests/src/lib/BaseSuite.test/web.test.mjs +0 -440
- package/testeranto/reports/allTests/src/Pure.test/pure/lint_errors.txt +0 -0
- package/testeranto/reports/allTests/src/Pure.test/pure/message.txt +0 -2
- package/testeranto/reports/allTests/src/Pure.test/pure/prompt.txt +0 -13
- package/testeranto/reports/allTests/src/Pure.test/pure/type_errors.txt +0 -101
- package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/lint_errors.txt +0 -13
- package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/logs.txt +0 -50
- package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/message.txt +0 -2
- package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/prompt.txt +0 -17
- package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/tests.json +0 -32
- package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/type_errors.txt +0 -68
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/node.test/node/lint_errors.txt +0 -0
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/node.test/node/logs.txt +0 -52
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/node.test/node/message.txt +0 -2
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/node.test/node/prompt.txt +0 -13
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/node.test/node/tests.json +0 -31
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/node.test/node/type_errors.txt +0 -111
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/pure.test/pure/bdd_errors.txt +0 -1
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/pure.test/pure/lint_errors.txt +0 -0
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/pure.test/pure/message.txt +0 -2
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/pure.test/pure/prompt.txt +0 -14
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/pure.test/pure/tests.json +0 -31
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/pure.test/pure/type_errors.txt +0 -111
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/web.test/web/bdd_errors.txt +0 -1
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/web.test/web/lint_errors.txt +0 -0
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/web.test/web/logs.txt +0 -108
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/web.test/web/message.txt +0 -2
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/web.test/web/prompt.txt +0 -14
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/web.test/web/tests.json +0 -31
- package/testeranto/reports/allTests/src/lib/BaseSuite.test/web.test/web/type_errors.txt +0 -111
- package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/bdd_errors.txt +0 -1
- package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/lint_errors.txt +0 -0
- package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/logs.txt +0 -700
- package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/message.txt +0 -2
- package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/prompt.txt +0 -16
- package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/tests.json +0 -164
- package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/type_errors.txt +0 -138
- package/testeranto/reports/allTests/src/lib/core.test/core.test/node/lint_errors.txt +0 -21
- package/testeranto/reports/allTests/src/lib/core.test/core.test/node/logs.txt +0 -7
- package/testeranto/reports/allTests/src/lib/core.test/core.test/node/message.txt +0 -2
- package/testeranto/reports/allTests/src/lib/core.test/core.test/node/prompt.txt +0 -18
- package/testeranto/reports/allTests/src/lib/pmProxy.test/index/node/bdd_errors.txt +0 -1
- package/testeranto/reports/allTests/src/lib/pmProxy.test/index/node/lint_errors.txt +0 -20
- package/testeranto/reports/allTests/src/lib/pmProxy.test/index/node/logs.txt +0 -31
- package/testeranto/reports/allTests/src/lib/pmProxy.test/index/node/message.txt +0 -2
- package/testeranto/reports/allTests/src/lib/pmProxy.test/index/node/prompt.txt +0 -16
- package/testeranto/reports/allTests/src/lib/pmProxy.test/index/node/tests.json +0 -134
- package/testeranto/reports/allTests/src/lib/pmProxy.test/index/node/type_errors.txt +0 -76
- package/testeranto/reportspure_build_errors +0 -343
- package/testeranto/reportsweb_build_errors +0 -25
- /package/testeranto/reports/{allTests/src/components/pure/ProjectPageView.test/index/web → core/src/lib/baseBuilder.test/baseBuilder.test.node/node}/bdd_errors.txt +0 -0
- /package/testeranto/reports/{allTests/src/lib/BaseSuite.test/node.test/node → core/src/lib/baseBuilder.test/baseBuilder.test.web/web}/bdd_errors.txt +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "testeranto",
|
|
3
3
|
"description": "the AI powered BDD test framework for typescript projects",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.173.0",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": "18.18.0"
|
|
7
7
|
},
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"@swc/core": "^1.3.26",
|
|
156
156
|
"@types/express": "^5.0.0",
|
|
157
157
|
"@types/express-session": "^1.18.1",
|
|
158
|
-
"@types/node": "^
|
|
158
|
+
"@types/node": "^24.1.0",
|
|
159
159
|
"@types/react": "18.2.0",
|
|
160
160
|
"@types/react-dom": "18.2.0",
|
|
161
161
|
"@types/react-test-renderer": "19.0.0",
|
package/src/PM/base.ts
CHANGED
|
@@ -167,6 +167,11 @@ export abstract class PM_Base {
|
|
|
167
167
|
contents: string,
|
|
168
168
|
testName: string
|
|
169
169
|
): Promise<boolean> {
|
|
170
|
+
console.log("writeFileSync");
|
|
171
|
+
console.log("filepath", filepath);
|
|
172
|
+
console.log("contents", contents);
|
|
173
|
+
console.log("testName", testName);
|
|
174
|
+
|
|
170
175
|
return new Promise<boolean>(async (res) => {
|
|
171
176
|
fs.mkdirSync(path.dirname(filepath), {
|
|
172
177
|
recursive: true,
|
package/src/PM/main.ts
CHANGED
|
@@ -105,10 +105,13 @@ function isValidUrl(string) {
|
|
|
105
105
|
|
|
106
106
|
// Wait for file to exist, checks every 2 seconds by default
|
|
107
107
|
async function pollForFile(path, timeout = 2000) {
|
|
108
|
+
console.log(`pollForFile: ${path}...`);
|
|
109
|
+
|
|
108
110
|
const intervalObj = setInterval(function () {
|
|
109
111
|
const file = path;
|
|
110
112
|
const fileExists = fs.existsSync(file);
|
|
111
113
|
if (fileExists) {
|
|
114
|
+
console.log(`metafile found: ${path}!`);
|
|
112
115
|
clearInterval(intervalObj);
|
|
113
116
|
}
|
|
114
117
|
}, timeout);
|
|
@@ -242,9 +245,9 @@ export class PM_Main extends PM_WithEslintAndTsc {
|
|
|
242
245
|
slowMo: 1,
|
|
243
246
|
waitForInitialPage: false,
|
|
244
247
|
executablePath,
|
|
245
|
-
headless:
|
|
248
|
+
headless: true,
|
|
246
249
|
dumpio: false,
|
|
247
|
-
devtools:
|
|
250
|
+
devtools: false,
|
|
248
251
|
|
|
249
252
|
args: [
|
|
250
253
|
"--disable-features=site-per-process",
|
|
@@ -717,7 +720,12 @@ export class PM_Main extends PM_WithEslintAndTsc {
|
|
|
717
720
|
const child = spawn(
|
|
718
721
|
"node",
|
|
719
722
|
// "node",
|
|
720
|
-
[
|
|
723
|
+
[
|
|
724
|
+
// "--inspect-brk",
|
|
725
|
+
builtfile,
|
|
726
|
+
testResources,
|
|
727
|
+
ipcfile,
|
|
728
|
+
],
|
|
721
729
|
{
|
|
722
730
|
stdio: ["pipe", "pipe", "pipe", "ipc"],
|
|
723
731
|
}
|
|
@@ -1330,7 +1338,7 @@ export class PM_Main extends PM_WithEslintAndTsc {
|
|
|
1330
1338
|
});
|
|
1331
1339
|
|
|
1332
1340
|
page.on("console", (log: ConsoleMessage) => {
|
|
1333
|
-
console.log("console message: ", log.text());
|
|
1341
|
+
// console.log("console message: ", log.text());
|
|
1334
1342
|
if (oStream.closed) {
|
|
1335
1343
|
console.log("missed console message: ", log.text());
|
|
1336
1344
|
return;
|
package/src/PM/node.ts
CHANGED
|
@@ -182,7 +182,7 @@ export class PM_Node extends PM {
|
|
|
182
182
|
return await this.send("write", ...arguments);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
async writeFileSync(filepath
|
|
185
|
+
async writeFileSync([filepath, contents]: [string, string]) {
|
|
186
186
|
return await this.send<boolean>(
|
|
187
187
|
"writeFileSync",
|
|
188
188
|
this.testResourceConfiguration.fs + "/" + filepath,
|
package/src/PM/web.ts
CHANGED
|
@@ -111,8 +111,8 @@ export class PM_Web extends PM {
|
|
|
111
111
|
customScreenShot(x: ScreenshotOptions, y: any) {
|
|
112
112
|
const opts = x[0];
|
|
113
113
|
const page = x[1];
|
|
114
|
-
console.log("customScreenShot 2 opts", opts);
|
|
115
|
-
console.log("customScreenShot 2 page", page);
|
|
114
|
+
// console.log("customScreenShot 2 opts", opts);
|
|
115
|
+
// console.log("customScreenShot 2 page", page);
|
|
116
116
|
return window["customScreenShot"](
|
|
117
117
|
{
|
|
118
118
|
...opts,
|
|
@@ -135,7 +135,7 @@ export class PM_Web extends PM {
|
|
|
135
135
|
return window["write"](uid, contents);
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
writeFileSync(filepath
|
|
138
|
+
writeFileSync([filepath, contents]: [string, string]) {
|
|
139
139
|
return window["writeFileSync"](
|
|
140
140
|
this.testResourceConfiguration.fs + "/" + filepath,
|
|
141
141
|
contents,
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
|
4
|
+
|
|
5
|
+
import { IncomingMessage, Server, ServerResponse } from "http";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
Ibdd_in,
|
|
9
|
+
Ibdd_out,
|
|
10
|
+
ITestAdapter,
|
|
11
|
+
ITestImplementation,
|
|
12
|
+
ITestSpecification,
|
|
13
|
+
} from "../CoreTypes";
|
|
14
|
+
import testeranto from "../Node";
|
|
15
|
+
import { ReportServerOfPort } from "../ReportServerLib";
|
|
16
|
+
import { PM } from "../PM";
|
|
17
|
+
import { ITTestResourceConfiguration } from "../lib";
|
|
18
|
+
import { IPM } from "../lib/types";
|
|
19
|
+
import { PM_Node } from "../PM/node";
|
|
20
|
+
import { util } from "chai";
|
|
21
|
+
|
|
22
|
+
type O = Ibdd_out<
|
|
23
|
+
{ Default: [] },
|
|
24
|
+
{
|
|
25
|
+
"the http server which is used in development": [];
|
|
26
|
+
},
|
|
27
|
+
// There are no "whens", it is a stateless server.
|
|
28
|
+
{},
|
|
29
|
+
{
|
|
30
|
+
"the frontpage looks good": [];
|
|
31
|
+
"the projects page looks good": [];
|
|
32
|
+
"a project page looks good": [];
|
|
33
|
+
"a test page looks good": [];
|
|
34
|
+
}
|
|
35
|
+
>;
|
|
36
|
+
|
|
37
|
+
const specification: ITestSpecification<I, O> = (Suite, Given, When, Then) => [
|
|
38
|
+
Suite.Default("the http server which is used in development", {
|
|
39
|
+
initialization: Given["the http server which is used in development"](
|
|
40
|
+
["It should serve the front page", "It should serve the ReportApp"],
|
|
41
|
+
[],
|
|
42
|
+
[
|
|
43
|
+
Then["the frontpage looks good"](),
|
|
44
|
+
// Then["the projects page looks good"](),
|
|
45
|
+
// Then["a project page looks good"](),
|
|
46
|
+
// Then["a test page looks good"](),
|
|
47
|
+
]
|
|
48
|
+
),
|
|
49
|
+
}),
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
const implementation: ITestImplementation<I, O, M> = {
|
|
53
|
+
suites: {
|
|
54
|
+
Default: "the http server which is used in development",
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
givens: {
|
|
58
|
+
"the http server which is used in development": function (
|
|
59
|
+
subject
|
|
60
|
+
): Server<typeof IncomingMessage, typeof ServerResponse> {
|
|
61
|
+
// throw new Error("Function not implemented.");
|
|
62
|
+
return subject;
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
// There are no "whens", it is a stateless server.
|
|
67
|
+
whens: {},
|
|
68
|
+
|
|
69
|
+
thens: {
|
|
70
|
+
"the frontpage looks good": async (port, utils) => {
|
|
71
|
+
// throw new Error("Function not implemented.");
|
|
72
|
+
|
|
73
|
+
// utils.newPage(`localhost:${port}`);
|
|
74
|
+
debugger;
|
|
75
|
+
const page = await utils.newPage();
|
|
76
|
+
utils.goto(page, `localhost:${port}`);
|
|
77
|
+
utils.customScreenShot({ path: `frontpage.png` }, page);
|
|
78
|
+
|
|
79
|
+
return;
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
"the projects page looks good": function (): (
|
|
83
|
+
port,
|
|
84
|
+
utils: PM
|
|
85
|
+
) => Server<typeof IncomingMessage, typeof ServerResponse> {
|
|
86
|
+
throw new Error("Function not implemented.");
|
|
87
|
+
},
|
|
88
|
+
"a project page looks good": function (): (
|
|
89
|
+
port,
|
|
90
|
+
utils: PM
|
|
91
|
+
) => Server<typeof IncomingMessage, typeof ServerResponse> {
|
|
92
|
+
throw new Error("Function not implemented.");
|
|
93
|
+
},
|
|
94
|
+
"a test page looks good": function (): (
|
|
95
|
+
port,
|
|
96
|
+
utils: PM
|
|
97
|
+
) => Server<typeof IncomingMessage, typeof ServerResponse> {
|
|
98
|
+
throw new Error("Function not implemented.");
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const adapter: ITestAdapter<I> = {
|
|
104
|
+
assertThis: function (
|
|
105
|
+
x: Server<typeof IncomingMessage, typeof ServerResponse>
|
|
106
|
+
) {
|
|
107
|
+
throw new Error("Function not implemented.");
|
|
108
|
+
},
|
|
109
|
+
andWhen: function (
|
|
110
|
+
store: Server<typeof IncomingMessage, typeof ServerResponse>,
|
|
111
|
+
whenCB: Server<typeof IncomingMessage, typeof ServerResponse>,
|
|
112
|
+
testResource: ITTestResourceConfiguration,
|
|
113
|
+
pm: IPM
|
|
114
|
+
): Promise<Server<typeof IncomingMessage, typeof ServerResponse>> {
|
|
115
|
+
throw new Error("Function not implemented.");
|
|
116
|
+
},
|
|
117
|
+
butThen: function (
|
|
118
|
+
store: Server<typeof IncomingMessage, typeof ServerResponse>,
|
|
119
|
+
thenCB: Server<typeof IncomingMessage, typeof ServerResponse>,
|
|
120
|
+
testResource: ITTestResourceConfiguration,
|
|
121
|
+
pm: IPM
|
|
122
|
+
): Promise<Server<typeof IncomingMessage, typeof ServerResponse>> {
|
|
123
|
+
throw new Error("Function not implemented.");
|
|
124
|
+
},
|
|
125
|
+
afterAll: function (
|
|
126
|
+
store: Server<typeof IncomingMessage, typeof ServerResponse>,
|
|
127
|
+
pm: IPM
|
|
128
|
+
) {
|
|
129
|
+
throw new Error("Function not implemented.");
|
|
130
|
+
},
|
|
131
|
+
afterEach: function (
|
|
132
|
+
store: Server<typeof IncomingMessage, typeof ServerResponse>,
|
|
133
|
+
key: string,
|
|
134
|
+
pm: IPM
|
|
135
|
+
): Promise<unknown> {
|
|
136
|
+
throw new Error("Function not implemented.");
|
|
137
|
+
},
|
|
138
|
+
beforeAll: async function (
|
|
139
|
+
input: (
|
|
140
|
+
port: number
|
|
141
|
+
) => Server<typeof IncomingMessage, typeof ServerResponse>,
|
|
142
|
+
testResource: ITTestResourceConfiguration,
|
|
143
|
+
pm: IPM
|
|
144
|
+
): Promise<number> {
|
|
145
|
+
await new Promise((res, rej) => input(testResource.ports[0]));
|
|
146
|
+
return testResource.ports[0];
|
|
147
|
+
},
|
|
148
|
+
beforeEach: function (
|
|
149
|
+
subject: number,
|
|
150
|
+
initializer: (
|
|
151
|
+
c?: any
|
|
152
|
+
) => Server<typeof IncomingMessage, typeof ServerResponse>,
|
|
153
|
+
testResource: ITTestResourceConfiguration,
|
|
154
|
+
initialValues: any,
|
|
155
|
+
pm: IPM
|
|
156
|
+
): Promise<Server<typeof IncomingMessage, typeof ServerResponse>> {
|
|
157
|
+
throw new Error("Function not implemented.");
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
type I = Ibdd_in<
|
|
162
|
+
(port: number) => Server<typeof IncomingMessage, typeof ServerResponse>,
|
|
163
|
+
number,
|
|
164
|
+
Server<typeof IncomingMessage, typeof ServerResponse>,
|
|
165
|
+
// Server<typeof IncomingMessage, typeof ServerResponse>,
|
|
166
|
+
number,
|
|
167
|
+
Server<typeof IncomingMessage, typeof ServerResponse>,
|
|
168
|
+
Server<typeof IncomingMessage, typeof ServerResponse>,
|
|
169
|
+
Server<typeof IncomingMessage, typeof ServerResponse>
|
|
170
|
+
>;
|
|
171
|
+
|
|
172
|
+
type M = {
|
|
173
|
+
givens: {
|
|
174
|
+
[K in keyof O["givens"]]: (...args: any[]) => IProjectPageViewProps;
|
|
175
|
+
};
|
|
176
|
+
whens: {
|
|
177
|
+
[K in keyof O["whens"]]: (
|
|
178
|
+
...args: any[]
|
|
179
|
+
) => (
|
|
180
|
+
props: IProjectPageViewProps,
|
|
181
|
+
utils: any
|
|
182
|
+
) => IProjectPageViewProps & { container?: HTMLElement };
|
|
183
|
+
};
|
|
184
|
+
thens: {
|
|
185
|
+
[K in keyof O["thens"]]: (port: number, pm: PM_Node) => void;
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export default testeranto<I, O, M>(
|
|
190
|
+
ReportServerOfPort,
|
|
191
|
+
specification,
|
|
192
|
+
implementation,
|
|
193
|
+
adapter
|
|
194
|
+
);
|
package/src/ReportServer.ts
CHANGED
|
@@ -1,135 +1,5 @@
|
|
|
1
1
|
// simple http server to preview reports
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import http from "http";
|
|
5
|
-
import path from "path";
|
|
6
|
-
import fs from "fs";
|
|
3
|
+
import { ReportServerOfPort } from "./ReportServerLib";
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
cache: false,
|
|
10
|
-
headers: {
|
|
11
|
-
"Cache-Control": "no-cache, no-store, must-revalidate",
|
|
12
|
-
"Pragma": "no-cache",
|
|
13
|
-
"Expires": "0"
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
const server = http.createServer((req, res) => {
|
|
18
|
-
// Handle potential double responses
|
|
19
|
-
let responded = false;
|
|
20
|
-
|
|
21
|
-
const safeResponse = (handler: () => void) => {
|
|
22
|
-
if (responded) return;
|
|
23
|
-
responded = true;
|
|
24
|
-
try {
|
|
25
|
-
handler();
|
|
26
|
-
} catch (err) {
|
|
27
|
-
console.error('Error handling request:', err);
|
|
28
|
-
if (!res.headersSent) {
|
|
29
|
-
res.writeHead(500);
|
|
30
|
-
}
|
|
31
|
-
res.end('Internal Server Error');
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
req.on('error', (err) => {
|
|
36
|
-
console.error('Request error:', err);
|
|
37
|
-
safeResponse(() => {
|
|
38
|
-
if (!res.headersSent) {
|
|
39
|
-
res.writeHead(400);
|
|
40
|
-
}
|
|
41
|
-
res.end('Bad Request');
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
req.on('end', () => {
|
|
46
|
-
safeResponse(() => {
|
|
47
|
-
const filePath = path.join(process.cwd(), req.url || '');
|
|
48
|
-
|
|
49
|
-
// First check if file exists
|
|
50
|
-
fs.stat(filePath, (err, stats) => {
|
|
51
|
-
if (err || !stats.isFile()) {
|
|
52
|
-
// Check if directory exists
|
|
53
|
-
fs.stat(filePath, (dirErr, dirStats) => {
|
|
54
|
-
if (!dirErr && dirStats.isDirectory()) {
|
|
55
|
-
// Serve directory listing
|
|
56
|
-
fs.readdir(filePath, (readErr, files) => {
|
|
57
|
-
if (readErr) {
|
|
58
|
-
res.writeHead(500);
|
|
59
|
-
return res.end('Error reading directory');
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
63
|
-
res.write(`
|
|
64
|
-
<html>
|
|
65
|
-
<head>
|
|
66
|
-
<title>Directory Listing: ${req.url}</title>
|
|
67
|
-
<style>
|
|
68
|
-
body { font-family: sans-serif; margin: 2rem; }
|
|
69
|
-
h1 { color: #333; }
|
|
70
|
-
ul { list-style: none; padding: 0; }
|
|
71
|
-
li { padding: 0.5rem; }
|
|
72
|
-
li a { color: #0366d6; text-decoration: none; }
|
|
73
|
-
li a:hover { text-decoration: underline; }
|
|
74
|
-
</style>
|
|
75
|
-
</head>
|
|
76
|
-
<body>
|
|
77
|
-
<h1>Directory: ${req.url}</h1>
|
|
78
|
-
<ul>
|
|
79
|
-
${files.map(file => `
|
|
80
|
-
<li>
|
|
81
|
-
<a href="${path.join(req.url || '', file)}">
|
|
82
|
-
${file}${file.endsWith('/') ? '/' : ''}
|
|
83
|
-
</a>
|
|
84
|
-
</li>
|
|
85
|
-
`).join('')}
|
|
86
|
-
</ul>
|
|
87
|
-
</body>
|
|
88
|
-
</html>
|
|
89
|
-
`);
|
|
90
|
-
res.end();
|
|
91
|
-
});
|
|
92
|
-
} else {
|
|
93
|
-
// Neither file nor directory exists - send 404
|
|
94
|
-
if (!res.headersSent) {
|
|
95
|
-
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
96
|
-
res.end('File not found');
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// File exists - serve it through node-static
|
|
104
|
-
const serve = () => {
|
|
105
|
-
fileServer.serve(req, res, (err) => {
|
|
106
|
-
if (err && !res.headersSent) {
|
|
107
|
-
res.writeHead(err.status || 500);
|
|
108
|
-
res.end(err.message);
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
// Ensure we don't double-serve
|
|
114
|
-
if (!res.headersSent) {
|
|
115
|
-
serve();
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
req.resume();
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
server.listen(8080, () => {
|
|
125
|
-
console.log('Server running on http://localhost:8080');
|
|
126
|
-
console.log('Serving files from:', process.cwd());
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
server.on('error', (err) => {
|
|
130
|
-
console.error('Server error:', err);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
process.on('uncaughtException', (err) => {
|
|
134
|
-
console.error('Uncaught exception:', err);
|
|
135
|
-
});
|
|
5
|
+
ReportServerOfPort(process.argv[2]);
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// simple http server to preview reports
|
|
2
|
+
|
|
3
|
+
import staticServer from "node-static";
|
|
4
|
+
import http from "http";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import fs from "fs";
|
|
7
|
+
|
|
8
|
+
const fileServer = new staticServer.Server("./", {
|
|
9
|
+
cache: false,
|
|
10
|
+
headers: {
|
|
11
|
+
"Cache-Control": "no-cache, no-store, must-revalidate",
|
|
12
|
+
Pragma: "no-cache",
|
|
13
|
+
Expires: "0",
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const server = http.createServer((req, res) => {
|
|
18
|
+
// Handle potential double responses
|
|
19
|
+
let responded = false;
|
|
20
|
+
|
|
21
|
+
const safeResponse = (handler: () => void) => {
|
|
22
|
+
if (responded) return;
|
|
23
|
+
responded = true;
|
|
24
|
+
try {
|
|
25
|
+
handler();
|
|
26
|
+
} catch (err) {
|
|
27
|
+
console.error("Error handling request:", err);
|
|
28
|
+
if (!res.headersSent) {
|
|
29
|
+
res.writeHead(500);
|
|
30
|
+
}
|
|
31
|
+
res.end("Internal Server Error");
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
req.on("error", (err) => {
|
|
36
|
+
console.error("Request error:", err);
|
|
37
|
+
safeResponse(() => {
|
|
38
|
+
if (!res.headersSent) {
|
|
39
|
+
res.writeHead(400);
|
|
40
|
+
}
|
|
41
|
+
res.end("Bad Request");
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
req.on("end", () => {
|
|
46
|
+
safeResponse(() => {
|
|
47
|
+
const filePath = path.join(process.cwd(), req.url || "");
|
|
48
|
+
|
|
49
|
+
// First check if file exists
|
|
50
|
+
fs.stat(filePath, (err, stats) => {
|
|
51
|
+
if (err || !stats.isFile()) {
|
|
52
|
+
// Check if directory exists
|
|
53
|
+
fs.stat(filePath, (dirErr, dirStats) => {
|
|
54
|
+
if (!dirErr && dirStats.isDirectory()) {
|
|
55
|
+
// Serve directory listing
|
|
56
|
+
fs.readdir(filePath, (readErr, files) => {
|
|
57
|
+
if (readErr) {
|
|
58
|
+
res.writeHead(500);
|
|
59
|
+
return res.end("Error reading directory");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
63
|
+
res.write(`
|
|
64
|
+
<html>
|
|
65
|
+
<head>
|
|
66
|
+
<title>Directory Listing: ${req.url}</title>
|
|
67
|
+
<style>
|
|
68
|
+
body { font-family: sans-serif; margin: 2rem; }
|
|
69
|
+
h1 { color: #333; }
|
|
70
|
+
ul { list-style: none; padding: 0; }
|
|
71
|
+
li { padding: 0.5rem; }
|
|
72
|
+
li a { color: #0366d6; text-decoration: none; }
|
|
73
|
+
li a:hover { text-decoration: underline; }
|
|
74
|
+
</style>
|
|
75
|
+
</head>
|
|
76
|
+
<body>
|
|
77
|
+
<h1>Directory: ${req.url}</h1>
|
|
78
|
+
<ul>
|
|
79
|
+
${files
|
|
80
|
+
.map(
|
|
81
|
+
(file) => `
|
|
82
|
+
<li>
|
|
83
|
+
<a href="${path.join(req.url || "", file)}">
|
|
84
|
+
${file}${file.endsWith("/") ? "/" : ""}
|
|
85
|
+
</a>
|
|
86
|
+
</li>
|
|
87
|
+
`
|
|
88
|
+
)
|
|
89
|
+
.join("")}
|
|
90
|
+
</ul>
|
|
91
|
+
</body>
|
|
92
|
+
</html>
|
|
93
|
+
`);
|
|
94
|
+
res.end();
|
|
95
|
+
});
|
|
96
|
+
} else {
|
|
97
|
+
// Neither file nor directory exists - send 404
|
|
98
|
+
if (!res.headersSent) {
|
|
99
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
100
|
+
res.end("File not found");
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// File exists - serve it through node-static
|
|
108
|
+
const serve = () => {
|
|
109
|
+
fileServer.serve(req, res, (err) => {
|
|
110
|
+
if (err && !res.headersSent) {
|
|
111
|
+
res.writeHead(err.status || 500);
|
|
112
|
+
res.end(err.message);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// Ensure we don't double-serve
|
|
118
|
+
if (!res.headersSent) {
|
|
119
|
+
serve();
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
req.resume();
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
server.on("error", (err) => {
|
|
129
|
+
console.error("Server error:", err);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
process.on("uncaughtException", (err) => {
|
|
133
|
+
console.error("Uncaught exception:", err);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const start = (port: number) =>
|
|
137
|
+
server.listen(port, () => {
|
|
138
|
+
console.log(`Server running on http://localhost:${port}`);
|
|
139
|
+
console.log("Serving files from:", process.cwd());
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
export const ReportServerOfPort = (port: number) => start(port);
|
|
143
|
+
|
|
144
|
+
// export default () => start(process.argv[2]);
|
package/src/TestPage.tsx
CHANGED
|
@@ -254,7 +254,27 @@ export const TestPage = () => {
|
|
|
254
254
|
<div key={i} className="mb-4 card">
|
|
255
255
|
<div className="card-header bg-primary text-white">
|
|
256
256
|
<div className="d-flex justify-content-between align-items-center">
|
|
257
|
-
<
|
|
257
|
+
<div>
|
|
258
|
+
<h4>Given: {given.name}</h4>
|
|
259
|
+
{given.features?.length > 0 && (
|
|
260
|
+
<div className="mt-1">
|
|
261
|
+
<small>Features:</small>
|
|
262
|
+
<ul className="list-unstyled">
|
|
263
|
+
{given.features.map((feature, fi) => (
|
|
264
|
+
<li key={fi}>
|
|
265
|
+
{feature.startsWith('http') ? (
|
|
266
|
+
<a href={feature} target="_blank" rel="noopener noreferrer" className="text-white">
|
|
267
|
+
{new URL(feature).hostname}
|
|
268
|
+
</a>
|
|
269
|
+
) : (
|
|
270
|
+
<span className="text-white">{feature}</span>
|
|
271
|
+
)}
|
|
272
|
+
</li>
|
|
273
|
+
))}
|
|
274
|
+
</ul>
|
|
275
|
+
</div>
|
|
276
|
+
)}
|
|
277
|
+
</div>
|
|
258
278
|
{given.artifacts?.length > 0 && (
|
|
259
279
|
<div className="dropdown">
|
|
260
280
|
<button
|
|
@@ -287,8 +307,28 @@ export const TestPage = () => {
|
|
|
287
307
|
<div key={`w-${j}`} className={`p-3 mb-2 ${when.error ? 'bg-danger text-white' : 'bg-success text-white'}`}>
|
|
288
308
|
<div className="d-flex justify-content-between align-items-start">
|
|
289
309
|
<div>
|
|
290
|
-
<
|
|
291
|
-
|
|
310
|
+
<div>
|
|
311
|
+
<strong>When:</strong> {when.name}
|
|
312
|
+
{when.features?.length > 0 && (
|
|
313
|
+
<div className="mt-2">
|
|
314
|
+
<small>Features:</small>
|
|
315
|
+
<ul className="list-unstyled">
|
|
316
|
+
{when.features.map((feature, fi) => (
|
|
317
|
+
<li key={fi}>
|
|
318
|
+
{feature.startsWith('http') ? (
|
|
319
|
+
<a href={feature} target="_blank" rel="noopener noreferrer">
|
|
320
|
+
{new URL(feature).hostname}
|
|
321
|
+
</a>
|
|
322
|
+
) : (
|
|
323
|
+
feature
|
|
324
|
+
)}
|
|
325
|
+
</li>
|
|
326
|
+
))}
|
|
327
|
+
</ul>
|
|
328
|
+
</div>
|
|
329
|
+
)}
|
|
330
|
+
{when.error && <pre className="mt-2">{when.error}</pre>}
|
|
331
|
+
</div>
|
|
292
332
|
</div>
|
|
293
333
|
{when.artifacts?.length > 0 && (
|
|
294
334
|
<div className="ms-3">
|
|
@@ -316,8 +356,28 @@ export const TestPage = () => {
|
|
|
316
356
|
<div key={`t-${k}`} className={`p-3 mb-2 ${then.error ? 'bg-danger text-white' : 'bg-success text-white'}`}>
|
|
317
357
|
<div className="d-flex justify-content-between align-items-start">
|
|
318
358
|
<div>
|
|
319
|
-
<
|
|
320
|
-
|
|
359
|
+
<div>
|
|
360
|
+
<strong>Then:</strong> {then.name}
|
|
361
|
+
{then.features?.length > 0 && (
|
|
362
|
+
<div className="mt-2">
|
|
363
|
+
<small>Features:</small>
|
|
364
|
+
<ul className="list-unstyled">
|
|
365
|
+
{then.features.map((feature, fi) => (
|
|
366
|
+
<li key={fi}>
|
|
367
|
+
{feature.startsWith('http') ? (
|
|
368
|
+
<a href={feature} target="_blank" rel="noopener noreferrer">
|
|
369
|
+
{new URL(feature).hostname}
|
|
370
|
+
</a>
|
|
371
|
+
) : (
|
|
372
|
+
feature
|
|
373
|
+
)}
|
|
374
|
+
</li>
|
|
375
|
+
))}
|
|
376
|
+
</ul>
|
|
377
|
+
</div>
|
|
378
|
+
)}
|
|
379
|
+
{then.error && <pre className="mt-2">{then.error}</pre>}
|
|
380
|
+
</div>
|
|
321
381
|
</div>
|
|
322
382
|
{then.artifacts?.length > 0 && (
|
|
323
383
|
<div className="ms-3">
|