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.
Files changed (34) hide show
  1. package/dist/stakeholder/index.tsx +66 -123
  2. package/git-temp +0 -0
  3. package/package.json +6 -9
  4. package/src/Types.ts +9 -10
  5. package/src/index.ts +12 -10
  6. package/src/lib/tiposkripto/src/BaseTiposkripto.ts +891 -240
  7. package/src/lib/tiposkripto/src/CoreTypes.ts +66 -28
  8. package/src/lib/tiposkripto/src/types.ts +28 -14
  9. package/src/lib/tiposkripto/src/verbs/BaseSuite.ts +344 -338
  10. package/src/lib/tiposkripto/src/verbs/aaa/BaseDescribe.ts +1 -1
  11. package/src/lib/tiposkripto/src/verbs/bdd/BaseGiven.ts +4 -4
  12. package/src/lib/tiposkripto/src/verbs/tdt/BaseConfirm.ts +53 -8
  13. package/src/lib/tiposkripto/src/verbs/tdt/BaseShould.ts +12 -4
  14. package/src/lib/tiposkripto/src/verbs/tdt/BaseValue.ts +1 -1
  15. package/src/lib/tiposkripto/tests/calculator/Calculator.test.implementation.ts +19 -18
  16. package/src/lib/tiposkripto/tests/calculator/Calculator.test.specification.ts +47 -330
  17. package/src/lib/tiposkripto/tests/calculator/Calculator.test.types.ts +33 -3
  18. package/src/lib/tiposkripto/tests/calculator/README.md +1 -0
  19. package/src/server/serverClasses/Server_Docker/utils/aider.ts +198 -200
  20. package/src/server/serverClasses/Server_Docker/utils/index.ts +7 -51
  21. package/src/server/serverClasses/Server_Docker/utils/startServiceLoggingPure.ts +122 -83
  22. package/src/server/serverClasses/Server_Docker.ts +53 -46
  23. package/src/server/serverClasses/Server_Http/Server_HTTP_Routes.ts +91 -2
  24. package/src/server/serverClasses/utils/embedConfigInHtml.ts +44 -0
  25. package/src/stakeholderApp/TabNavigation.tsx +2 -39
  26. package/src/stakeholderApp/VisualizationPanel.tsx +47 -48
  27. package/src/stakeholderApp/VisualizationTabs.tsx +106 -0
  28. package/src/stakeholderApp/graph.md +201 -0
  29. package/src/stakeholderApp/index.html +1 -9
  30. package/src/stakeholderApp/index.tsx +66 -123
  31. package/src/stakeholderApp/utils.ts +3 -16
  32. package/src/stakeholderExports.ts +4 -11
  33. package/tickets/stakeholderV2.md +6 -1
  34. 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
- // for instance, the columns in a kanban chart and to which attribute they map
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
- VisualizationPanel, TreePanel, TestResultsSummary, TabNavigation,
27
- createFileContentFromNode, togglePathInSet, type GraphData, type Node
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; // The content of tests.json
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
- // Always use embedded data from window
80
- const embeddedData = (window as any).TESTERANTO_EMBEDDED_DATA;
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 (!embeddedData) {
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 embedded data found. The server may not have generated the report properly.</p>
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
- style={{
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
- <TabNavigation activeTab={activeTab} onTabChange={setActiveTab} />
141
-
142
- {activeTab === "viz" && (
143
- <VisualizationPanel
144
- data={data}
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.234.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/StakeholderUtils": {
134
- "import": "./src/server/serverClasses/StakeholderUtils.tsx"
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
- tableRows: any[][],
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 TestBaseConfirm = Record<string, any>;
237
- export type TestBaseValue = Record<string, any>;
238
- export type TestExpectShape = Record<string, any>;
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
- // TODO auto add correct version instead of hardcode
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
- try {
23
- await fs.access(stakeholderIndexPath);
24
- } catch {
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${"0.233.7"} `);
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 v0.233.7 - running in ${mode} mode\n Press 'q' to initiate a graceful shutdown.\nPress 'CTRL + c' to quit forcefully.\n`);
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