testeranto 0.234.0 → 0.235.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/dist/stakeholder/index.tsx +66 -123
- package/git-temp +0 -0
- package/package.json +6 -9
- package/src/Types.ts +9 -10
- package/src/index.ts +12 -10
- package/src/lib/tiposkripto/src/BaseTiposkripto.ts +891 -240
- package/src/lib/tiposkripto/src/CoreTypes.ts +66 -28
- package/src/lib/tiposkripto/src/types.ts +28 -14
- package/src/lib/tiposkripto/src/verbs/BaseSuite.ts +344 -338
- package/src/lib/tiposkripto/src/verbs/aaa/BaseDescribe.ts +1 -1
- package/src/lib/tiposkripto/src/verbs/bdd/BaseGiven.ts +4 -4
- package/src/lib/tiposkripto/src/verbs/tdt/BaseConfirm.ts +53 -8
- package/src/lib/tiposkripto/src/verbs/tdt/BaseShould.ts +12 -4
- package/src/lib/tiposkripto/src/verbs/tdt/BaseValue.ts +1 -1
- package/src/lib/tiposkripto/tests/calculator/Calculator.test.implementation.ts +19 -18
- package/src/lib/tiposkripto/tests/calculator/Calculator.test.specification.ts +47 -330
- package/src/lib/tiposkripto/tests/calculator/Calculator.test.types.ts +33 -3
- package/src/lib/tiposkripto/tests/calculator/README.md +1 -0
- package/src/server/serverClasses/Server_Docker/utils/aider.ts +198 -200
- package/src/server/serverClasses/Server_Docker/utils/index.ts +7 -51
- package/src/server/serverClasses/Server_Docker/utils/startServiceLoggingPure.ts +122 -83
- package/src/server/serverClasses/Server_Docker.ts +53 -46
- package/src/server/serverClasses/Server_Http/Server_HTTP_Routes.ts +91 -2
- package/src/server/serverClasses/utils/embedConfigInHtml.ts +44 -0
- package/src/stakeholderApp/TabNavigation.tsx +2 -39
- package/src/stakeholderApp/VisualizationPanel.tsx +47 -48
- package/src/stakeholderApp/VisualizationTabs.tsx +106 -0
- package/src/stakeholderApp/graph.md +201 -0
- package/src/stakeholderApp/index.html +1 -9
- package/src/stakeholderApp/index.tsx +66 -123
- package/src/stakeholderApp/utils.ts +3 -16
- package/src/stakeholderExports.ts +4 -11
- package/tickets/stakeholderV2.md +6 -1
- package/src/server/serverClasses/Server_Docker/StakeholderAppBundler.ts +0 -33
|
@@ -1,31 +1,14 @@
|
|
|
1
1
|
// NOTE: this file is not a part of our build process, but a downstream process run by the user
|
|
2
2
|
// this file is copied to the users project where they can customize it
|
|
3
|
-
//
|
|
3
|
+
// This is where a user configures the visualization.
|
|
4
4
|
|
|
5
5
|
import React, { useState } from "react";
|
|
6
6
|
import ReactDOM from "react-dom/client";
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
// NOTE! You cannot do this
|
|
11
|
-
// This tsx is copied to the user's host and bundled on thelfy
|
|
12
|
-
///////////////////////////////////////////////////////////////////////////////////////////
|
|
13
|
-
// import { createFileContentFromNode } from "./stateless/createFileContentFromNode";
|
|
14
|
-
// import { togglePathInSet } from "./stateless/setUtils";
|
|
15
|
-
// import { TabNavigation } from "./TabNavigation";
|
|
16
|
-
// import { TestResultsSummary } from "./TestResultsSummary";
|
|
17
|
-
// import { TreePanel } from "./TreePanel";
|
|
18
|
-
// import { VisualizationPanel } from "./VisualizationPanel";
|
|
19
|
-
///////////////////////////////////////////////////////////////////////////////////////////
|
|
20
|
-
// Instead you must reference the imports from the installed version of testeranto
|
|
21
|
-
// don't forget to expose those files in package.json
|
|
22
|
-
// import type { GraphData, Node } from "testeranto/grafeovidajo";
|
|
23
|
-
// import type { createFileContentFromNode, togglePathInSet } from "testeranto/stakeholder";
|
|
24
|
-
|
|
8
|
+
// IMPORTANT : all imports need tog through stakeholderExports
|
|
25
9
|
import {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
} from "testeranto/stakeholder";
|
|
10
|
+
VisualizationTabs,
|
|
11
|
+
} from "../../src/stakeholderExports";
|
|
29
12
|
|
|
30
13
|
|
|
31
14
|
export interface StakeholderData {
|
|
@@ -56,73 +39,82 @@ export interface StakeholderData {
|
|
|
56
39
|
timestamp: string;
|
|
57
40
|
workspaceRoot: string;
|
|
58
41
|
featureTree?: any;
|
|
59
|
-
// Add test results data
|
|
60
42
|
allTestResults?: {
|
|
61
43
|
[configKey: string]: {
|
|
62
|
-
[testName: string]: any;
|
|
44
|
+
[testName: string]: any;
|
|
63
45
|
};
|
|
64
46
|
};
|
|
65
|
-
// Add feature graph for visualization
|
|
66
47
|
featureGraph?: GraphData;
|
|
67
|
-
// Add file tree graph for visualization
|
|
68
48
|
fileTreeGraph?: GraphData;
|
|
69
|
-
// Add viz configuration
|
|
70
49
|
vizConfig?: any;
|
|
71
50
|
}
|
|
72
51
|
|
|
73
|
-
export interface StakeholderAppProps {
|
|
74
|
-
// Data is no longer passed as props - always use embedded data from window.TESTERANTO_EMBEDDED_DATA
|
|
75
|
-
data?: StakeholderData;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
52
|
export const DefaultStakeholderApp: React.FC = () => {
|
|
79
|
-
|
|
80
|
-
const
|
|
53
|
+
const [data, setData] = React.useState<StakeholderData | null>(null);
|
|
54
|
+
const [loading, setLoading] = React.useState(true);
|
|
55
|
+
const [error, setError] = React.useState<string | null>(null);
|
|
56
|
+
|
|
57
|
+
React.useEffect(() => {
|
|
58
|
+
const loadData = async () => {
|
|
59
|
+
setLoading(true);
|
|
60
|
+
setError(null);
|
|
61
|
+
|
|
62
|
+
// 1. Try Server API
|
|
63
|
+
// try {
|
|
64
|
+
// const response = await fetch('/api/graph-data');
|
|
65
|
+
// if (!response.ok) throw new Error(`API ${response.status}`);
|
|
66
|
+
|
|
67
|
+
// const result = await response.json();
|
|
68
|
+
// setData(result.data || result);
|
|
69
|
+
// setLoading(false);
|
|
70
|
+
// return;
|
|
71
|
+
// } catch (apiError) {
|
|
72
|
+
// console.warn("API failed, trying JSON file...", apiError.message);
|
|
73
|
+
// }
|
|
74
|
+
|
|
75
|
+
// 2. Try Static JSON
|
|
76
|
+
try {
|
|
77
|
+
const response = await fetch('/testeranto/reports/graph-data.json');
|
|
78
|
+
if (!response.ok) throw new Error(`JSON file ${response.status}`);
|
|
79
|
+
|
|
80
|
+
const jsonData = await response.json();
|
|
81
|
+
setData(jsonData);
|
|
82
|
+
setLoading(false);
|
|
83
|
+
return;
|
|
84
|
+
} catch (jsonError) {
|
|
85
|
+
console.warn("JSON file failed:", jsonError.message);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 3. Final Fail-safe (If everything above failed)
|
|
89
|
+
setError("All data sources failed.");
|
|
90
|
+
setLoading(false);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
loadData();
|
|
95
|
+
}, []);
|
|
96
|
+
|
|
97
|
+
if (loading) {
|
|
98
|
+
return (
|
|
99
|
+
<div style={{ padding: "40px", textAlign: "center" }}>
|
|
100
|
+
<h2>Loading Testeranto Stakeholder Report...</h2>
|
|
101
|
+
<p>Attempting to load data...</p>
|
|
102
|
+
</div>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
81
105
|
|
|
82
|
-
if (!
|
|
106
|
+
if (error || !data) {
|
|
83
107
|
return (
|
|
84
108
|
<div style={{ padding: "40px", textAlign: "center" }}>
|
|
85
109
|
<h1 style={{ color: "#d32f2f" }}>Error Loading Report</h1>
|
|
86
|
-
<p>No
|
|
110
|
+
<p>{error || "No data could be loaded."}</p>
|
|
87
111
|
<p>Please make sure the Testeranto server has generated the report files.</p>
|
|
88
112
|
</div>
|
|
89
113
|
);
|
|
90
114
|
}
|
|
91
115
|
|
|
92
|
-
const data: StakeholderData = embeddedData;
|
|
93
|
-
|
|
94
|
-
const [expandedPaths, setExpandedPaths] = useState<Set<string>>(
|
|
95
|
-
new Set([".", "root"]),
|
|
96
|
-
);
|
|
97
|
-
const [selectedFile, setSelectedFile] = useState<string | null>(null);
|
|
98
|
-
const [selectedFileContent, setSelectedFileContent] = useState<any>(null);
|
|
99
|
-
const [activeTab, setActiveTab] = useState<"tree" | "viz">("tree");
|
|
100
|
-
const [vizType, setVizType] = useState<
|
|
101
|
-
"eisenhower" | "gantt" | "kanban" | "tree" | "file-tree"
|
|
102
|
-
>("file-tree");
|
|
103
|
-
|
|
104
|
-
const toggleExpand = (path: string) => {
|
|
105
|
-
setExpandedPaths(togglePathInSet(expandedPaths, path));
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const handleFileSelect = (node: any) => {
|
|
109
|
-
setSelectedFile(node.path);
|
|
110
|
-
const content = createFileContentFromNode(node, embeddedData);
|
|
111
|
-
setSelectedFileContent(content);
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const handleTestResultClick = (
|
|
115
|
-
configKey: string,
|
|
116
|
-
testName: string,
|
|
117
|
-
testData: any,
|
|
118
|
-
) => {
|
|
119
|
-
setSelectedFile(`${configKey}/${testName}`);
|
|
120
|
-
setSelectedFileContent(testData);
|
|
121
|
-
};
|
|
122
|
-
|
|
123
116
|
const handleNodeClick = (node: Node) => {
|
|
124
117
|
console.log("Node clicked:", node);
|
|
125
|
-
// You could implement node selection here
|
|
126
118
|
};
|
|
127
119
|
|
|
128
120
|
const handleNodeHover = (node: Node | null) => {
|
|
@@ -130,68 +122,20 @@ export const DefaultStakeholderApp: React.FC = () => {
|
|
|
130
122
|
};
|
|
131
123
|
|
|
132
124
|
return (
|
|
133
|
-
<div
|
|
134
|
-
|
|
135
|
-
padding: "20px",
|
|
136
|
-
fontFamily: "sans-serif",
|
|
137
|
-
}}
|
|
138
|
-
>
|
|
125
|
+
<div style={{ padding: "20px", fontFamily: "sans-serif" }}>
|
|
126
|
+
<h1>Testeranto Stakeholder Report</h1>
|
|
139
127
|
<div style={{ marginBottom: "20px" }}>
|
|
140
|
-
<
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
vizType={vizType}
|
|
146
|
-
onVizTypeChange={setVizType}
|
|
147
|
-
onNodeClick={handleNodeClick}
|
|
148
|
-
onNodeHover={handleNodeHover}
|
|
149
|
-
/>
|
|
150
|
-
)}
|
|
151
|
-
|
|
152
|
-
{activeTab === "tree" && (
|
|
153
|
-
<>
|
|
154
|
-
<TreePanel
|
|
155
|
-
featureTree={data.featureTree}
|
|
156
|
-
expandedPaths={expandedPaths}
|
|
157
|
-
selectedFile={selectedFile}
|
|
158
|
-
onToggleExpand={toggleExpand}
|
|
159
|
-
onFileSelect={handleFileSelect}
|
|
160
|
-
selectedFileContent={selectedFileContent}
|
|
161
|
-
configs={data.configs}
|
|
162
|
-
allTestResults={data.allTestResults}
|
|
163
|
-
onTestResultClick={handleTestResultClick}
|
|
164
|
-
/>
|
|
165
|
-
{!selectedFile && data.allTestResults && (
|
|
166
|
-
<TestResultsSummary
|
|
167
|
-
allTestResults={data.allTestResults}
|
|
168
|
-
onTestResultClick={handleTestResultClick}
|
|
169
|
-
/>
|
|
170
|
-
)}
|
|
171
|
-
</>
|
|
172
|
-
)}
|
|
128
|
+
<VisualizationTabs
|
|
129
|
+
data={data}
|
|
130
|
+
onNodeClick={handleNodeClick}
|
|
131
|
+
onNodeHover={handleNodeHover}
|
|
132
|
+
/>
|
|
173
133
|
</div>
|
|
174
134
|
</div>
|
|
175
135
|
);
|
|
176
136
|
};
|
|
177
137
|
|
|
178
|
-
// Function to render the app
|
|
179
138
|
export function renderApp(rootElement: HTMLElement) {
|
|
180
|
-
// Always use embedded data from window
|
|
181
|
-
const embeddedData = (window as any).TESTERANTO_EMBEDDED_DATA;
|
|
182
|
-
|
|
183
|
-
if (!embeddedData) {
|
|
184
|
-
console.error("No stakeholder data available");
|
|
185
|
-
rootElement.innerHTML = `
|
|
186
|
-
<div style="padding: 40px; text-align: center;">
|
|
187
|
-
<h1 style="color: #d32f2f;">Error Loading Report</h1>
|
|
188
|
-
<p>No embedded data found. The server may not have generated the report properly.</p>
|
|
189
|
-
<p>Please make sure the Testeranto server has generated the report files.</p>
|
|
190
|
-
</div>
|
|
191
|
-
`;
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
139
|
const root = ReactDOM.createRoot(rootElement);
|
|
196
140
|
root.render(
|
|
197
141
|
<React.StrictMode>
|
|
@@ -200,5 +144,4 @@ export function renderApp(rootElement: HTMLElement) {
|
|
|
200
144
|
);
|
|
201
145
|
}
|
|
202
146
|
|
|
203
|
-
// Export for use in HTML
|
|
204
147
|
export default DefaultStakeholderApp;
|
package/git-temp
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "testeranto",
|
|
3
3
|
"displayName": "Testeranto",
|
|
4
4
|
"description": "the Dockerized, AI powered, BDD test framework for polyglot projects",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.235.0",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=20.19.0",
|
|
8
8
|
"vscode": "^1.60.0",
|
|
@@ -130,8 +130,8 @@
|
|
|
130
130
|
"ATDD"
|
|
131
131
|
],
|
|
132
132
|
"exports": {
|
|
133
|
-
"./src/server/serverClasses/
|
|
134
|
-
"import": "./src/
|
|
133
|
+
"./src/server/serverClasses/stakeholderExports": {
|
|
134
|
+
"import": "./src/stakeholderExports.ts"
|
|
135
135
|
},
|
|
136
136
|
"./src/cjs-shim.ts": {
|
|
137
137
|
"import": "./dist/cjs-shim.js",
|
|
@@ -234,11 +234,7 @@
|
|
|
234
234
|
"import": "./dist/module/NodeWriter.js",
|
|
235
235
|
"require": "./dist/common/NodeWriter.js"
|
|
236
236
|
},
|
|
237
|
-
"./src/**/*": "./src/**/*.ts"
|
|
238
|
-
"./stakeholder": {
|
|
239
|
-
"import": "./src/stakeholderExports.ts",
|
|
240
|
-
"require": "./src/stakeholderExports.ts"
|
|
241
|
-
}
|
|
237
|
+
"./src/**/*": "./src/**/*.ts"
|
|
242
238
|
},
|
|
243
239
|
"peerDependencies": {
|
|
244
240
|
"@types/react": "18.2.0",
|
|
@@ -323,6 +319,7 @@
|
|
|
323
319
|
"file-saver": "^2.0.5",
|
|
324
320
|
"fs-extra": "^11.2.0",
|
|
325
321
|
"fs.promises.exists": "^1.1.4",
|
|
322
|
+
"graphology": "^0.26.0",
|
|
326
323
|
"jiti": "*",
|
|
327
324
|
"js-yaml": "^4.1.0",
|
|
328
325
|
"license-checker": "^25.0.1",
|
|
@@ -365,4 +362,4 @@
|
|
|
365
362
|
"@esbuild/win32-x64": "^0.27.2",
|
|
366
363
|
"esbuild": "0.27.3"
|
|
367
364
|
}
|
|
368
|
-
}
|
|
365
|
+
}
|
package/src/Types.ts
CHANGED
|
@@ -108,10 +108,10 @@ export type ConfirmSpecification<
|
|
|
108
108
|
I extends Ibdd_in_any,
|
|
109
109
|
O extends Ibdd_out_any,
|
|
110
110
|
> = {
|
|
111
|
-
[K in keyof O["confirms"]]: (
|
|
111
|
+
[K in keyof O["confirms"]]: (input: O["confirms"][K]) => (
|
|
112
|
+
tableRows: [v: BaseValue, s: BaseShould][],
|
|
112
113
|
features: string[],
|
|
113
|
-
|
|
114
|
-
...xtras: O["confirms"][K]
|
|
114
|
+
|
|
115
115
|
) => BaseConfirm<I>
|
|
116
116
|
};
|
|
117
117
|
|
|
@@ -120,9 +120,9 @@ export type ValueSpecification<
|
|
|
120
120
|
O extends Ibdd_out_any,
|
|
121
121
|
> = {
|
|
122
122
|
[K in keyof O["values"]]: (
|
|
123
|
-
features: string[],
|
|
124
|
-
tableRows: any[][],
|
|
125
|
-
...xtras: O["values"][K]
|
|
123
|
+
// features: string[],
|
|
124
|
+
// tableRows: any[][],
|
|
125
|
+
// ...xtras: O["values"][K]
|
|
126
126
|
) => BaseValue<I>;
|
|
127
127
|
};
|
|
128
128
|
|
|
@@ -233,10 +233,9 @@ export type TestThenShape = Record<string, any>;
|
|
|
233
233
|
export type TestDescribeShape = Record<string, any>;
|
|
234
234
|
export type TestItShape = Record<string, any>;
|
|
235
235
|
|
|
236
|
-
export type
|
|
237
|
-
export type
|
|
238
|
-
export type
|
|
239
|
-
export type TestExpectVerify = Record<string, any>;
|
|
236
|
+
export type TestConfirmShape = Record<string, any>;
|
|
237
|
+
export type TestValueShape = Record<string, any>;
|
|
238
|
+
export type TestShouldShape = Record<string, any>;
|
|
240
239
|
|
|
241
240
|
export type IPluginFactory = (
|
|
242
241
|
register?: (entrypoint: string, sources: string[]) => any,
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import pkg from "../package.json";
|
|
2
|
+
|
|
3
|
+
const version = pkg.version;
|
|
2
4
|
|
|
3
5
|
import readline from "readline";
|
|
4
6
|
import { Server } from "./server/serverClasses/Server";
|
|
@@ -8,6 +10,9 @@ import fs from "fs/promises";
|
|
|
8
10
|
import stakeholderTsx from "../src/stakeholderApp/index.tsx" with { type: "text" };
|
|
9
11
|
|
|
10
12
|
const init = async () => {
|
|
13
|
+
|
|
14
|
+
console.log("initializing the testeranto folder");
|
|
15
|
+
|
|
11
16
|
const testerantoDir = join(process.cwd(), "testeranto");
|
|
12
17
|
const bundlesDir = join(testerantoDir, "bundles");
|
|
13
18
|
const reportsDir = join(testerantoDir, "reports");
|
|
@@ -19,11 +24,9 @@ const init = async () => {
|
|
|
19
24
|
|
|
20
25
|
// Copy stakeholder index.tsx if it doesn't exist
|
|
21
26
|
const stakeholderIndexPath = join(reportsDir, "index.tsx");
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
await fs.writeFile(stakeholderIndexPath, stakeholderTsx);
|
|
26
|
-
}
|
|
27
|
+
|
|
28
|
+
console.log(stakeholderIndexPath, stakeholderTsx);
|
|
29
|
+
await fs.writeFile(stakeholderIndexPath, stakeholderTsx);
|
|
27
30
|
|
|
28
31
|
}
|
|
29
32
|
|
|
@@ -31,17 +34,16 @@ const mode = process.argv[2] as "once" | "dev" | "-v" | "init";
|
|
|
31
34
|
|
|
32
35
|
(async () => {
|
|
33
36
|
if (mode === "-v") {
|
|
34
|
-
console.log(`v${
|
|
37
|
+
console.log(`v${version} `);
|
|
35
38
|
process.exit(0);
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
if (mode === "init") {
|
|
39
|
-
console.log("initializing the testeranto folder");
|
|
40
42
|
await init();
|
|
41
43
|
process.exit(0);
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
console.log(`hello testeranto
|
|
46
|
+
console.log(`hello testeranto v${version} - running in ${mode} mode\n Press 'q' to initiate a graceful shutdown.\nPress 'CTRL + c' to quit forcefully.\n`);
|
|
45
47
|
|
|
46
48
|
if (mode !== "once" && mode !== "dev" && mode != "-v") {
|
|
47
49
|
console.error(`The 3rd argument should be '-v', 'init', 'dev' or 'once', not '${mode}'.`);
|
|
@@ -50,7 +52,7 @@ const mode = process.argv[2] as "once" | "dev" | "-v" | "init";
|
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
await init();
|
|
53
|
-
|
|
55
|
+
|
|
54
56
|
const config = (await import(process.cwd() + '/testeranto/testeranto.ts')).default;
|
|
55
57
|
const server = new Server(config, mode);
|
|
56
58
|
|