testeranto 0.167.0 → 0.172.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 (185) hide show
  1. package/dist/common/src/NavBar.js +45 -0
  2. package/dist/common/src/PM/main.js +81 -59
  3. package/dist/common/src/Pure.js +16 -14
  4. package/dist/common/src/ReportServer.js +48 -5
  5. package/dist/common/src/Web.js +35 -20
  6. package/dist/common/src/components/SunriseAnimation.test/implementation.js +1 -0
  7. package/dist/common/src/components/SunriseAnimation.test/index.js +1 -0
  8. package/dist/common/src/components/SunriseAnimation.test/interface.js +1 -0
  9. package/dist/common/src/components/SunriseAnimation.test/specification.js +1 -0
  10. package/dist/common/src/components/TestStatusBadge.js +55 -0
  11. package/dist/common/src/components/pure/ProjectPageView.js +204 -0
  12. package/dist/common/src/components/pure/ProjectPageView.test/adapter.js +20 -0
  13. package/dist/common/src/components/pure/ProjectPageView.test/implementation.js +71 -0
  14. package/dist/common/src/components/pure/ProjectPageView.test/index.js +10 -0
  15. package/dist/common/src/components/pure/ProjectPageView.test/specification.js +19 -0
  16. package/dist/common/src/components/pure/ProjectPageView.test/types.js +2 -0
  17. package/dist/common/src/lib/BaseSuite.js +3 -3
  18. package/dist/common/src/lib/BaseSuite.test/test.js +1 -1
  19. package/dist/common/src/lib/abstractBase.js +41 -14
  20. package/dist/common/src/lib/baseBuilder.test/baseBuilder.test.adapter.js +1 -1
  21. package/dist/common/src/lib/pmProxy.js +185 -64
  22. package/dist/common/testeranto.config.js +6 -0
  23. package/dist/common/tsconfig.common.tsbuildinfo +1 -1
  24. package/dist/module/src/App.js +3 -3
  25. package/dist/module/src/PM/main.js +81 -59
  26. package/dist/module/src/ProjectsPage.js +1 -110
  27. package/dist/module/src/Pure.js +16 -14
  28. package/dist/module/src/ReportServer.js +48 -5
  29. package/dist/module/src/TestPage.js +45 -16
  30. package/dist/module/src/Web.js +35 -20
  31. package/dist/module/src/components/SunriseAnimation.test/implementation.js +1 -0
  32. package/dist/module/src/components/SunriseAnimation.test/index.js +1 -0
  33. package/dist/module/src/components/SunriseAnimation.test/interface.js +1 -0
  34. package/dist/module/src/components/SunriseAnimation.test/specification.js +1 -0
  35. package/dist/module/src/components/pure/ProjectPageView.js +197 -0
  36. package/dist/module/src/components/pure/ProjectPageView.test/adapter.js +17 -0
  37. package/dist/module/src/components/pure/ProjectPageView.test/implementation.js +68 -0
  38. package/dist/module/src/components/pure/ProjectPageView.test/index.js +5 -0
  39. package/dist/module/src/components/pure/ProjectPageView.test/specification.js +15 -0
  40. package/dist/module/src/components/pure/ProjectPageView.test/types.js +1 -0
  41. package/dist/module/src/components/pure/ProjectsPageView.js +58 -0
  42. package/dist/module/src/components/pure/TestPageView.js +136 -0
  43. package/dist/module/src/components/stateful/ProjectPage.js +63 -0
  44. package/dist/module/src/components/stateful/ProjectsPage.js +55 -0
  45. package/dist/module/src/components/stateful/TestPage.js +82 -0
  46. package/dist/module/src/lib/BaseSuite.js +3 -3
  47. package/dist/module/src/lib/BaseSuite.test/test.js +1 -1
  48. package/dist/module/src/lib/abstractBase.js +41 -14
  49. package/dist/module/src/lib/baseBuilder.test/baseBuilder.test.adapter.js +1 -1
  50. package/dist/module/src/lib/pmProxy.js +185 -64
  51. package/dist/module/testeranto.config.js +6 -0
  52. package/dist/module/tsconfig.module.tsbuildinfo +1 -1
  53. package/dist/prebuild/App.css +13 -9
  54. package/dist/prebuild/App.js +600 -551
  55. package/dist/prebuild/ReportServer.mjs +44 -4
  56. package/dist/prebuild/run.mjs +67 -39
  57. package/dist/types/src/NavBar.d.ts +19 -0
  58. package/dist/types/src/PM/index.d.ts +3 -1
  59. package/dist/types/src/PM/main.d.ts +0 -4
  60. package/dist/types/src/PM/node.d.ts +2 -2
  61. package/dist/types/src/components/SunriseAnimation.test/interface.d.ts +0 -0
  62. package/dist/types/src/components/SunriseAnimation.test/specification.d.ts +0 -0
  63. package/dist/types/src/components/TestStatusBadge.d.ts +15 -0
  64. package/dist/types/src/components/pure/ProjectPageView.d.ts +14 -0
  65. package/dist/types/src/components/pure/ProjectPageView.test/adapter.d.ts +3 -0
  66. package/dist/types/src/components/pure/ProjectPageView.test/implementation.d.ts +3 -0
  67. package/dist/types/src/components/pure/ProjectPageView.test/index.d.ts +2 -0
  68. package/dist/types/src/components/pure/ProjectPageView.test/specification.d.ts +3 -0
  69. package/dist/types/src/components/pure/ProjectPageView.test/types.d.ts +39 -0
  70. package/dist/types/src/lib/BaseSuite.d.ts +2 -0
  71. package/dist/types/src/lib/abstractBase.d.ts +12 -0
  72. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  73. package/package.json +5 -3
  74. package/src/App.tsx +5 -9
  75. package/src/PM/index.ts +1 -1
  76. package/src/PM/main.ts +87 -82
  77. package/src/PM/node.ts +2 -2
  78. package/src/ProjectsPage.tsx +1 -164
  79. package/src/Pure.ts +16 -16
  80. package/src/ReportServer.ts +49 -6
  81. package/src/TestPage.tsx +78 -5
  82. package/src/Web.ts +35 -35
  83. package/src/components/SunriseAnimation.test/implementation.ts +0 -0
  84. package/src/components/SunriseAnimation.test/index.ts +0 -0
  85. package/src/components/SunriseAnimation.test/interface.ts +0 -0
  86. package/src/components/SunriseAnimation.test/specification.ts +0 -0
  87. package/src/components/pure/ProjectPageView.test/adapter.ts +21 -0
  88. package/src/components/pure/ProjectPageView.test/implementation.tsx +84 -0
  89. package/src/components/pure/ProjectPageView.test/index.ts +8 -0
  90. package/src/components/pure/ProjectPageView.test/specification.ts +31 -0
  91. package/src/components/pure/ProjectPageView.test/types.ts +55 -0
  92. package/src/components/pure/ProjectPageView.tsx +332 -0
  93. package/src/components/pure/ProjectsPageView.tsx +99 -0
  94. package/src/components/pure/TestPageView.tsx +278 -0
  95. package/src/components/stateful/ProjectPage.tsx +83 -0
  96. package/src/components/stateful/ProjectsPage.tsx +73 -0
  97. package/src/components/stateful/TestPage.tsx +107 -0
  98. package/src/lib/BaseSuite.test/test.ts +1 -1
  99. package/src/lib/BaseSuite.ts +9 -4
  100. package/src/lib/abstractBase.ts +45 -14
  101. package/src/lib/baseBuilder.test/baseBuilder.test.adapter.ts +1 -1
  102. package/src/lib/pmProxy.ts +184 -87
  103. package/testeranto/App.css +13 -9
  104. package/testeranto/App.js +600 -551
  105. package/testeranto/bundles/node/allTests/{chunk-4ONUZRZ4.mjs → chunk-3EUGBAOM.mjs} +1 -1
  106. package/testeranto/bundles/node/allTests/{chunk-IDCUSTSM.mjs → chunk-E75CSRER.mjs} +246 -115
  107. package/testeranto/bundles/node/allTests/{chunk-NQEP7SN4.mjs → chunk-M6DO7VMB.mjs} +1 -1
  108. package/testeranto/bundles/node/allTests/metafile.json +37 -37
  109. package/testeranto/bundles/node/allTests/src/lib/BaseSuite.test/node.test.mjs +4 -4
  110. package/testeranto/bundles/node/allTests/src/lib/baseBuilder.test/baseBuilder.test.node.mjs +3 -3
  111. package/testeranto/bundles/node/allTests/src/lib/classBuilder.test/classBuilder.test.mjs +3 -3
  112. package/testeranto/bundles/node/allTests/src/lib/core.test/core.test.mjs +2 -17
  113. package/testeranto/bundles/node/allTests/src/lib/pmProxy.test/index.mjs +354 -252
  114. package/testeranto/bundles/pure/allTests/{chunk-5SBJWHSZ.mjs → chunk-KHDVEHF7.mjs} +2 -17
  115. package/testeranto/bundles/pure/allTests/{chunk-4ULDTZFU.mjs → chunk-VMUSFSZM.mjs} +246 -115
  116. package/testeranto/bundles/pure/allTests/metafile.json +72 -42
  117. package/testeranto/bundles/pure/allTests/src/Pure.test.mjs +2 -2
  118. package/testeranto/bundles/pure/allTests/src/lib/BaseSuite.test/pure.test.mjs +3 -3
  119. package/testeranto/bundles/pure/allTests/src/lib/baseBuilder.test/baseBuilder.test.pure.mjs +2 -29
  120. package/testeranto/bundles/web/allTests/chunk-HPYA4YZC.mjs +2283 -0
  121. package/testeranto/bundles/web/allTests/{chunk-46E6YGGN.mjs → chunk-U7AW26HL.mjs} +292 -142
  122. package/testeranto/bundles/web/allTests/metafile.json +22 -943
  123. package/testeranto/bundles/web/allTests/src/components/pure/ProjectPageView.test/index.html +19 -0
  124. package/testeranto/bundles/web/allTests/src/components/pure/ProjectPageView.test/index.mjs +37524 -0
  125. package/testeranto/bundles/web/allTests/src/lib/BaseSuite.test/web.test.mjs +20 -2
  126. package/testeranto/bundles/web/allTests/src/lib/baseBuilder.test/baseBuilder.test.web.mjs +26 -2
  127. package/testeranto/reports/allTests/config.json +8 -0
  128. package/testeranto/reports/allTests/src/Pure.test/pure/type_errors.txt +9 -3
  129. package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/bdd_errors.txt +1 -0
  130. package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/lint_errors.txt +13 -0
  131. package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/logs.txt +50 -0
  132. package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/message.txt +2 -0
  133. package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/prompt.txt +17 -0
  134. package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/tests.json +32 -0
  135. package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/type_errors.txt +68 -0
  136. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node.test/node/logs.txt +22 -39
  137. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node.test/node/tests.json +6 -3
  138. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node.test/node/type_errors.txt +8 -1
  139. package/testeranto/reports/allTests/src/lib/BaseSuite.test/pure.test/pure/tests.json +6 -3
  140. package/testeranto/reports/allTests/src/lib/BaseSuite.test/pure.test/pure/type_errors.txt +9 -3
  141. package/testeranto/reports/allTests/src/lib/BaseSuite.test/web.test/web/logs.txt +66 -55
  142. package/testeranto/reports/allTests/src/lib/BaseSuite.test/web.test/web/prompt.txt +2 -2
  143. package/testeranto/reports/allTests/src/lib/BaseSuite.test/web.test/web/tests.json +6 -3
  144. package/testeranto/reports/allTests/src/lib/BaseSuite.test/web.test/web/type_errors.txt +10 -5
  145. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/logs.txt +16 -48
  146. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/tests.json +18 -9
  147. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/type_errors.txt +8 -1
  148. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.pure/pure/type_errors.txt +10 -5
  149. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/logs.txt +62 -33
  150. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/prompt.txt +2 -2
  151. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/tests.json +18 -9
  152. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/type_errors.txt +10 -5
  153. package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/logs.txt +37 -50
  154. package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/tests.json +36 -18
  155. package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/type_errors.txt +8 -1
  156. package/testeranto/reports/allTests/src/lib/core.test/core.test/node/logs.txt +2 -2
  157. package/testeranto/reports/allTests/src/lib/core.test/core.test/node/type_errors.txt +9 -3
  158. package/testeranto/reports/allTests/src/lib/pmProxy.test/index/node/logs.txt +28 -43
  159. package/testeranto/reports/allTests/src/lib/pmProxy.test/index/node/tests.json +28 -14
  160. package/testeranto/reports/allTests/src/lib/pmProxy.test/index/node/type_errors.txt +8 -1
  161. package/testeranto/reports/allTests/summary.json +15 -8
  162. package/testeranto/reportsnode_build_errors +20 -0
  163. package/testeranto/reportspure_build_errors +343 -0
  164. package/testeranto/reportsweb_build_errors +25 -0
  165. package/testeranto.config.ts +7 -0
  166. package/tsc.log +100 -26
  167. package/dist/tsconfig.tsbuildinfo +0 -1
  168. package/testeranto/bundles/node/allTests/chunk-FFBRDUBH.mjs +0 -677
  169. package/testeranto/bundles/node/allTests/chunk-H2IBV7SY.mjs +0 -113
  170. package/testeranto/bundles/node/allTests/chunk-ZHOULXPN.mjs +0 -252
  171. package/testeranto/bundles/pure/allTests/chunk-CSMXYJ65.mjs +0 -200
  172. package/testeranto/bundles/pure/allTests/chunk-QK4IXLF6.mjs +0 -674
  173. package/testeranto/bundles/web/allTests/chunk-TU3MJSSI.mjs +0 -855
  174. package/testeranto/bundles/web/allTests/src/lib/BaseSuite.test/web.test/manifest.json +0 -1
  175. package/testeranto/bundles/web/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/manifest.json +0 -1
  176. package/testeranto/reports/allTests/src/Pure.test/pure/manifest.json +0 -1
  177. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node.test/node/manifest.json +0 -1
  178. package/testeranto/reports/allTests/src/lib/BaseSuite.test/pure.test/pure/manifest.json +0 -1
  179. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/manifest.json +0 -1
  180. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.pure/pure/manifest.json +0 -1
  181. package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/manifest.json +0 -1
  182. package/testeranto/reports/allTests/src/lib/core.test/core.test/node/manifest.json +0 -1
  183. package/testeranto/reports/allTests/src/lib/pmProxy.test/index/node/manifest.json +0 -1
  184. /package/{testeranto/reports/allTests/src/Pure.test/pure/logs.txt → dist/types/src/components/SunriseAnimation.test/implementation.d.ts} +0 -0
  185. /package/{testeranto/reports/allTests/src/lib/BaseSuite.test/pure.test/pure/logs.txt → dist/types/src/components/SunriseAnimation.test/index.d.ts} +0 -0
@@ -0,0 +1,278 @@
1
+ import React from 'react';
2
+ import { Tab, Container, Alert, Button } from 'react-bootstrap';
3
+ import { NavBar } from '../../NavBar';
4
+ import { TestStatusBadge } from '../TestStatusBadge';
5
+
6
+ export const TestPageView = ({
7
+ route,
8
+ setRoute,
9
+ navigate,
10
+ projectName,
11
+ testName,
12
+ decodedTestPath,
13
+ runtime,
14
+ testData,
15
+ logs,
16
+ typeErrors,
17
+ lintErrors,
18
+ testsExist,
19
+ errorCounts,
20
+ }) => {
21
+ return (
22
+ <Container fluid={true}>
23
+ <NavBar
24
+ title={decodedTestPath}
25
+ backLink={`/projects/${projectName}`}
26
+ navItems={[
27
+ {
28
+ label: '',
29
+ badge: {
30
+ variant: runtime === 'node' ? 'primary' :
31
+ runtime === 'web' ? 'success' :
32
+ 'info',
33
+ text: runtime
34
+ },
35
+ className: 'pe-none d-flex align-items-center gap-2'
36
+ },
37
+ {
38
+ to: `#results`,
39
+ label: (
40
+ <TestStatusBadge
41
+ testName={decodedTestPath}
42
+ testsExist={testsExist}
43
+ runTimeErrors={errorCounts.runTimeErrors}
44
+ variant="compact"
45
+ />
46
+ ),
47
+ className: !testsExist || errorCounts.runTimeErrors > 0
48
+ ? 'text-danger fw-bold'
49
+ : '',
50
+ active: route === 'results'
51
+ },
52
+ {
53
+ to: `#logs`,
54
+ label: `Runtime logs`,
55
+ active: route === 'logs'
56
+ },
57
+ {
58
+ to: `#types`,
59
+ label: errorCounts.typeErrors > 0
60
+ ? `tsc (❌ * ${errorCounts.typeErrors})`
61
+ : 'tsc ✅ ',
62
+ active: route === 'types'
63
+ },
64
+ {
65
+ to: `#lint`,
66
+ label: errorCounts.staticErrors > 0
67
+ ? `eslint (❌ *${errorCounts.staticErrors}) `
68
+ : 'eslint ✅',
69
+ active: route === 'lint'
70
+ },
71
+ ]}
72
+ rightContent={
73
+ <Button
74
+ variant="info"
75
+ onClick={async () => {
76
+ try {
77
+ const promptPath = `testeranto/reports/${projectName}/${testName.split('.').slice(0, -1).join('.')}/${runtime}/prompt.txt`;
78
+ const messagePath = `testeranto/reports/${projectName}/${testName.split('.').slice(0, -1).join('.')}/${runtime}/message.txt`;
79
+ const command = `aider --load ${promptPath} --message-file ${messagePath}`;
80
+ await navigator.clipboard.writeText(command);
81
+ alert("Copied aider command to clipboard!");
82
+ } catch (err) {
83
+ alert("Failed to copy command to clipboard");
84
+ console.error("Copy failed:", err);
85
+ }
86
+ }}
87
+ className="ms-2"
88
+ >
89
+ 🤖
90
+ </Button>
91
+ }
92
+ />
93
+
94
+ <Tab.Container activeKey={route} onSelect={(k) => {
95
+ if (k) {
96
+ setRoute(k);
97
+ navigate(`#${k}`, { replace: true });
98
+ }
99
+ }}>
100
+ <Tab.Content className="mt-3">
101
+ <Tab.Pane eventKey="results">
102
+ {!testsExist ? (
103
+ <Alert variant="danger" className="mt-3">
104
+ <h4>Tests did not run to completion</h4>
105
+ <p>The test results file (tests.json) was not found or could not be loaded.</p>
106
+ <div className="mt-3">
107
+ <Button
108
+ variant="outline-light"
109
+ onClick={() => setRoute('logs')}
110
+ className="me-2"
111
+ >
112
+ View Runtime Logs
113
+ </Button>
114
+ <Button
115
+ variant="outline-light"
116
+ onClick={() => navigate(`/projects/${projectName}#${runtime}`)}
117
+ >
118
+ View Build Logs
119
+ </Button>
120
+ </div>
121
+ </Alert>
122
+ ) : testData ? (
123
+ <div className="test-results">
124
+ {testData.givens.map((given, i) => (
125
+ <div key={i} className="mb-4 card">
126
+ <div className="card-header bg-primary text-white">
127
+ <div className="d-flex justify-content-between align-items-center">
128
+ <h4>Given: {given.name}</h4>
129
+ {given.artifacts?.length > 0 && (
130
+ <div className="dropdown">
131
+ <button
132
+ className="btn btn-sm btn-light dropdown-toggle"
133
+ type="button"
134
+ data-bs-toggle="dropdown"
135
+ >
136
+ Artifacts ({given.artifacts.length})
137
+ </button>
138
+ <ul className="dropdown-menu dropdown-menu-end">
139
+ {given.artifacts.map((artifact, ai) => (
140
+ <li key={ai}>
141
+ <a
142
+ className="dropdown-item"
143
+ href={`/testeranto/reports/${projectName}/${testName.split('.').slice(0, -1).join('.')}/${runtime}/${artifact}`}
144
+ target="_blank"
145
+ rel="noopener noreferrer"
146
+ >
147
+ {artifact.split('/').pop()}
148
+ </a>
149
+ </li>
150
+ ))}
151
+ </ul>
152
+ </div>
153
+ )}
154
+ </div>
155
+ </div>
156
+ <div className="card-body">
157
+ {given.whens.map((when, j) => (
158
+ <div key={`w-${j}`} className={`p-3 mb-2 ${when.error ? 'bg-danger text-white' : 'bg-success text-white'}`}>
159
+ <div className="d-flex justify-content-between align-items-start">
160
+ <div>
161
+ <strong>When:</strong> {when.name}
162
+ {when.error && <pre className="mt-2">{when.error}</pre>}
163
+ </div>
164
+ {when.artifacts?.length > 0 && (
165
+ <div className="ms-3">
166
+ <strong>Artifacts:</strong>
167
+ <ul className="list-unstyled">
168
+ {when.artifacts.map((artifact, ai) => (
169
+ <li key={ai}>
170
+ <a
171
+ href={`/testeranto/reports/${projectName}/${testName.split('.').slice(0, -1).join('.')}/${runtime}/${artifact}`}
172
+ target="_blank"
173
+ className="text-white"
174
+ rel="noopener noreferrer"
175
+ >
176
+ {artifact.split('/').pop()}
177
+ </a>
178
+ </li>
179
+ ))}
180
+ </ul>
181
+ </div>
182
+ )}
183
+ </div>
184
+ </div>
185
+ ))}
186
+ {given.thens.map((then, k) => (
187
+ <div key={`t-${k}`} className={`p-3 mb-2 ${then.error ? 'bg-danger text-white' : 'bg-success text-white'}`}>
188
+ <div className="d-flex justify-content-between align-items-start">
189
+ <div>
190
+ <strong>Then:</strong> {then.name}
191
+ {then.error && <pre className="mt-2">{then.error}</pre>}
192
+ </div>
193
+ {then.artifacts?.length > 0 && (
194
+ <div className="ms-3">
195
+ <strong>Artifacts:</strong>
196
+ <ul className="list-unstyled">
197
+ {then.artifacts.map((artifact, ai) => (
198
+ <li key={ai}>
199
+ <a
200
+ href={`/testeranto/reports/${projectName}/${testName.split('.').slice(0, -1).join('.')}/${runtime}/${artifact}`}
201
+ target="_blank"
202
+ className="text-white"
203
+ rel="noopener noreferrer"
204
+ >
205
+ {artifact.split('/').pop()}
206
+ </a>
207
+ </li>
208
+ ))}
209
+ </ul>
210
+ </div>
211
+ )}
212
+ </div>
213
+ </div>
214
+ ))}
215
+ </div>
216
+ </div>
217
+ ))}
218
+ </div>
219
+ ) : (
220
+ <Alert variant="warning">No test results found</Alert>
221
+ )}
222
+ </Tab.Pane>
223
+ <Tab.Pane eventKey="logs">
224
+ {logs === undefined ? (
225
+ <Alert variant="danger">
226
+ <h4>Logs file missing</h4>
227
+ <p>The runtime logs file (logs.txt) was not found.</p>
228
+ <p>This suggests the test may not have executed properly.</p>
229
+ </Alert>
230
+ ) : logs === '' ? (
231
+ <Alert variant="success">
232
+ <h4>No runtime logs</h4>
233
+ <p>The test executed successfully with no log output.</p>
234
+ </Alert>
235
+ ) : (
236
+ <pre className="bg-dark text-white p-3">{logs}</pre>
237
+ )}
238
+ </Tab.Pane>
239
+ <Tab.Pane eventKey="types">
240
+ {typeErrors ? (
241
+ <pre className="bg-dark text-white p-3">{typeErrors}</pre>
242
+ ) : (
243
+ <Alert variant="warning">No type errors found</Alert>
244
+ )}
245
+ </Tab.Pane>
246
+ <Tab.Pane eventKey="lint">
247
+ {lintErrors ? (
248
+ <pre className="bg-dark text-white p-3">{lintErrors}</pre>
249
+ ) : (
250
+ <Alert variant="warning">No lint errors found</Alert>
251
+ )}
252
+ </Tab.Pane>
253
+ <Tab.Pane eventKey="coverage">
254
+ <div className="coverage-report">
255
+ <Alert variant="info">
256
+ Coverage reports coming soon!
257
+ </Alert>
258
+ <div className="coverage-stats">
259
+ <div className="stat-card bg-success text-white">
260
+ <h4>85%</h4>
261
+ <p>Lines Covered</p>
262
+ </div>
263
+ <div className="stat-card bg-warning text-dark">
264
+ <h4>72%</h4>
265
+ <p>Branches Covered</p>
266
+ </div>
267
+ <div className="stat-card bg-info text-white">
268
+ <h4>91%</h4>
269
+ <p>Functions Covered</p>
270
+ </div>
271
+ </div>
272
+ </div>
273
+ </Tab.Pane>
274
+ </Tab.Content>
275
+ </Tab.Container>
276
+ </Container>
277
+ );
278
+ };
@@ -0,0 +1,83 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import React, { useEffect, useState } from 'react';
3
+ import { useParams, useNavigate, useLocation } from 'react-router-dom';
4
+ import { ProjectPageView } from '../pure/ProjectPageView';
5
+ import { ISummary } from '../../Types';
6
+
7
+ export const ProjectPage = () => {
8
+ const [summary, setSummary] = useState<ISummary | null>(null);
9
+ const [nodeLogs, setNodeLogs] = useState<any>(null);
10
+ const [webLogs, setWebLogs] = useState<any>(null);
11
+ const [pureLogs, setPureLogs] = useState<any>(null);
12
+ const [config, setConfig] = useState<object>({});
13
+ const [loading, setLoading] = useState(true);
14
+ const [error, setError] = useState<string | null>(null);
15
+ const [projectName, setProjectName] = useState('');
16
+ const navigate = useNavigate();
17
+ const location = useLocation();
18
+ const [route, setRoute] = useState('tests');
19
+
20
+ useEffect(() => {
21
+ const hash = location.hash.replace('#', '');
22
+ if (hash && ['tests', 'node', 'web', 'pure'].includes(hash)) {
23
+ setRoute(hash);
24
+ } else {
25
+ setRoute('tests');
26
+ }
27
+ }, [location.hash]);
28
+
29
+ const { projectName: name } = useParams();
30
+
31
+ useEffect(() => {
32
+ if (!name) return;
33
+ setProjectName(name);
34
+
35
+ const fetchData = async () => {
36
+ try {
37
+ const [summaryRes, nodeRes, webRes, pureRes, configRes] = await Promise.all([
38
+ fetch(`reports/${name}/summary.json`),
39
+ fetch(`bundles/node/${name}/metafile.json`),
40
+ fetch(`bundles/web/${name}/metafile.json`),
41
+ fetch(`bundles/pure/${name}/metafile.json`),
42
+ fetch(`reports/${name}/config.json`)
43
+ ]);
44
+
45
+ const [summaryData, nodeData, webData, pureData, configData] = await Promise.all([
46
+ summaryRes.ok ? summaryRes.json() : {},
47
+ nodeRes.ok ? nodeRes.json() : { errors: ["Failed to load node build logs"] },
48
+ webRes.ok ? webRes.json() : { errors: ["Failed to load web build logs"] },
49
+ pureRes.ok ? pureRes.json() : { errors: ["Failed to load pure build logs"] },
50
+ configRes.ok ? configRes.json() : { tests: [] }
51
+ ]);
52
+
53
+ setSummary(summaryData);
54
+ setNodeLogs(nodeData);
55
+ setWebLogs(webData);
56
+ setPureLogs(pureData);
57
+ setConfig(configData);
58
+ } catch (err) {
59
+ setError(err instanceof Error ? err.message : 'Unknown error');
60
+ } finally {
61
+ setLoading(false);
62
+ }
63
+ };
64
+
65
+ fetchData();
66
+ }, [name]);
67
+
68
+ return (
69
+ <ProjectPageView
70
+ summary={summary}
71
+ nodeLogs={nodeLogs}
72
+ webLogs={webLogs}
73
+ pureLogs={pureLogs}
74
+ config={config}
75
+ loading={loading}
76
+ error={error}
77
+ projectName={projectName}
78
+ route={route}
79
+ setRoute={setRoute}
80
+ navigate={navigate}
81
+ />
82
+ );
83
+ };
@@ -0,0 +1,73 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import React, { useEffect, useState } from 'react';
3
+ import { useNavigate } from 'react-router-dom';
4
+ import { ProjectsPageView } from '../pure/ProjectsPageView';
5
+ import { ISummary } from '../../Types';
6
+
7
+ export const ProjectsPage = () => {
8
+ const [projects, setProjects] = useState<any[]>([]);
9
+ const [summaries, setSummaries] = useState<Record<string, ISummary>>({});
10
+ const [loading, setLoading] = useState(true);
11
+ const [error, setError] = useState<string | null>(null);
12
+ const [configs, setConfigs] = useState<Record<string, object>>({});
13
+ const navigate = useNavigate();
14
+
15
+ useEffect(() => {
16
+ const fetchProjects = async () => {
17
+ try {
18
+ const projectsRes = await fetch(`projects.json`);
19
+ const projectNames = await projectsRes.json();
20
+
21
+ const projectsData = await Promise.all(
22
+ projectNames.map(async (name) => {
23
+ const [summaryRes, nodeRes, webRes, pureRes, configRes] = await Promise.all([
24
+ fetch(`reports/${name}/summary.json`),
25
+ fetch(`bundles/node/${name}/metafile.json`),
26
+ fetch(`bundles/web/${name}/metafile.json`),
27
+ fetch(`bundles/pure/${name}/metafile.json`),
28
+ fetch(`reports/${name}/config.json`),
29
+ ]);
30
+
31
+ const [summary, nodeData, webData, pureData, configData] = await Promise.all([
32
+ summaryRes.json(),
33
+ nodeRes.ok ? nodeRes.json() : { errors: ["Failed to load node build logs"] },
34
+ webRes.ok ? webRes.json() : { errors: ["Failed to load web build logs"] },
35
+ pureRes.ok ? pureRes.json() : { errors: ["Failed to load pure build logs"] },
36
+ configRes.json(),
37
+ ]);
38
+
39
+ setSummaries(prev => ({ ...prev, [name]: summary }));
40
+ setConfigs(prev => ({ ...prev, [name]: configData }));
41
+
42
+ return {
43
+ name,
44
+ testCount: Object.keys(summary).length,
45
+ nodeStatus: nodeData.errors?.length ? 'failed' : nodeData.warnings?.length ? 'warning' : 'success',
46
+ webStatus: webData.errors?.length ? 'failed' : webData.warnings?.length ? 'warning' : 'success',
47
+ pureStatus: pureData.errors?.length ? 'failed' : pureData.warnings?.length ? 'warning' : 'success',
48
+ };
49
+ })
50
+ );
51
+
52
+ setProjects(projectsData);
53
+ } catch (err) {
54
+ setError(err instanceof Error ? err.message : 'Unknown error');
55
+ } finally {
56
+ setLoading(false);
57
+ }
58
+ };
59
+
60
+ fetchProjects();
61
+ }, []);
62
+
63
+ return (
64
+ <ProjectsPageView
65
+ projects={projects}
66
+ summaries={summaries}
67
+ configs={configs}
68
+ loading={loading}
69
+ error={error}
70
+ navigate={navigate}
71
+ />
72
+ );
73
+ };
@@ -0,0 +1,107 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { useLocation, useNavigate, useParams } from 'react-router-dom';
3
+
4
+ import { TestPageView } from '../pure/TestPageView';
5
+ import { fetchTestData } from '../../utils/api';
6
+
7
+ export const TestPage = () => {
8
+ const navigate = useNavigate();
9
+ const location = useLocation();
10
+ const [route, setRoute] = useState('results');
11
+
12
+ // Sync route with hash changes
13
+ useEffect(() => {
14
+ const hash = location.hash.replace('#', '');
15
+ if (hash && ['results', 'logs', 'types', 'lint', 'coverage'].includes(hash)) {
16
+ setRoute(hash);
17
+ } else {
18
+ setRoute('results');
19
+ }
20
+ }, [location.hash]);
21
+
22
+ const [testName, setTestName] = useState('');
23
+ const [testData, setTestData] = useState(null);
24
+ const [logs, setLogs] = useState('');
25
+ const [typeErrors, setTypeErrors] = useState('');
26
+ const [lintErrors, setLintErrors] = useState('');
27
+ const [loading, setLoading] = useState(true);
28
+ const [error, setError] = useState(null);
29
+ const [testsExist, setTestsExist] = useState(true);
30
+ const [errorCounts, setErrorCounts] = useState({
31
+ typeErrors: 0,
32
+ staticErrors: 0,
33
+ runTimeErrors: 0
34
+ });
35
+ const [summary, setSummary] = useState(null);
36
+
37
+ const { projectName, '*': splat } = useParams();
38
+ const pathParts = splat ? splat.split('/') : [];
39
+ const runtime = pathParts.pop() || '';
40
+ const testPath = pathParts.join('/');
41
+ const decodedTestPath = testPath ? decodeURIComponent(testPath) : '';
42
+
43
+ useEffect(() => {
44
+ if (!projectName || !testPath || !runtime) return;
45
+ setTestName(testPath);
46
+
47
+ const fetchData = async () => {
48
+ try {
49
+ const testResponse = await fetchTestData(projectName, testPath, runtime);
50
+ setTestData(testResponse.testData);
51
+ setTestsExist(!!testResponse.testData);
52
+ setLogs(testResponse.logs === null ? undefined : testResponse.logs);
53
+ setTypeErrors(testResponse.typeErrors);
54
+ setLintErrors(testResponse.lintErrors);
55
+
56
+ try {
57
+ const summaryResponse = await fetch(`reports/${projectName}/summary.json`);
58
+ if (!summaryResponse.ok) throw new Error('Failed to fetch summary');
59
+ const allSummaries = await summaryResponse.json();
60
+ const testSummary = allSummaries[testPath];
61
+
62
+ if (testSummary) {
63
+ const counts = {
64
+ typeErrors: Number(testSummary.typeErrors) || 0,
65
+ staticErrors: Number(testSummary.staticErrors) || 0,
66
+ runTimeErrors: Number(testSummary.runTimeErrors) || 0
67
+ };
68
+
69
+ setSummary(testSummary);
70
+ setErrorCounts(counts);
71
+ setTestsExist(testSummary.testsExist !== false);
72
+ }
73
+ } catch (err) {
74
+ console.error('Failed to load summary:', err);
75
+ }
76
+ } catch (err) {
77
+ setError(err instanceof Error ? err.message : 'Unknown error');
78
+ setTestsExist(false);
79
+ } finally {
80
+ setLoading(false);
81
+ }
82
+ };
83
+
84
+ fetchData();
85
+ }, []);
86
+
87
+ return (
88
+ <TestPageView
89
+ route={route}
90
+ setRoute={setRoute}
91
+ navigate={navigate}
92
+ projectName={projectName}
93
+ testName={testName}
94
+ decodedTestPath={decodedTestPath}
95
+ runtime={runtime}
96
+ testData={testData}
97
+ logs={logs}
98
+ typeErrors={typeErrors}
99
+ lintErrors={lintErrors}
100
+ loading={loading}
101
+ error={error}
102
+ testsExist={testsExist}
103
+ errorCounts={errorCounts}
104
+ summary={summary}
105
+ />
106
+ );
107
+ };
@@ -432,7 +432,7 @@ export const testAdapter: ITestAdapter<I> = {
432
432
 
433
433
  return result;
434
434
  } catch (e) {
435
- console.error("Then error:", e);
435
+ console.error("Then error:", e.toString());
436
436
  console.error("Full store state:", JSON.stringify(store, null, 2));
437
437
  throw e;
438
438
  }
@@ -19,13 +19,18 @@ export abstract class BaseSuite<I extends Ibdd_in_any, O extends Ibdd_out_any> {
19
19
  if (!suiteName) {
20
20
  throw new Error("BaseSuite requires a non-empty name");
21
21
  }
22
- console.log("[DEBUG] BaseSuite constructor - name:", suiteName, "index:", index);
22
+ console.log(
23
+ "[DEBUG] BaseSuite constructor - name:",
24
+ suiteName,
25
+ "index:",
26
+ index
27
+ );
23
28
  this.name = suiteName;
24
29
  this.index = index;
25
30
  this.givens = givens;
26
31
  this.fails = 0;
27
32
  console.log("[DEBUG] BaseSuite initialized:", this.name, this.index);
28
- console.log("[DEBUG] BaseSuite givens:", Object.keys(givens));
33
+ console.log("[DEBUG] BaseSuite givens:", Object.keys(givens).toString());
29
34
  }
30
35
 
31
36
  public features() {
@@ -36,7 +41,7 @@ export abstract class BaseSuite<I extends Ibdd_in_any, O extends Ibdd_out_any> {
36
41
  .filter((value, index, array) => {
37
42
  return array.indexOf(value) === index;
38
43
  });
39
- console.debug("[DEBUG] Features extracted:", features);
44
+ console.debug("[DEBUG] Features extracted:", features.toString());
40
45
  return features || [];
41
46
  } catch (e) {
42
47
  console.error("[ERROR] Failed to extract features:", e);
@@ -114,7 +119,7 @@ export abstract class BaseSuite<I extends Ibdd_in_any, O extends Ibdd_out_any> {
114
119
  .catch((e) => {
115
120
  this.failed = true;
116
121
  this.fails = this.fails + 1;
117
- console.error("Given error 1:", e);
122
+ // console.error("Given error 1:", e.toString());
118
123
  throw e;
119
124
  });
120
125
  }