testeranto 0.158.0 → 0.159.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/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.158.0",
4
+ "version": "0.159.0",
5
5
  "engines": {
6
6
  "node": "18.18.0"
7
7
  },
package/src/Init.ts CHANGED
@@ -8,7 +8,6 @@ export default async () => {
8
8
  `testeranto/bundles/node`,
9
9
  `testeranto/bundles/web`,
10
10
  `testeranto/bundles/pure`,
11
- `testeranto/reports`,
12
11
  `testeranto/reports/`,
13
12
  `testeranto/features/`,
14
13
  `testeranto/externalTests/`,
package/src/TestPage.tsx CHANGED
@@ -43,6 +43,13 @@ export const TestPage = () => {
43
43
  const [lintErrors, setLintErrors] = useState<string>('');
44
44
  const [loading, setLoading] = useState(true);
45
45
  const [error, setError] = useState<string | null>(null);
46
+ const [testsExist, setTestsExist] = useState<boolean>(true);
47
+ const [errorCounts, setErrorCounts] = useState({
48
+ typeErrors: 0,
49
+ staticErrors: 0,
50
+ runTimeErrors: 0
51
+ });
52
+ const [summary, setSummary] = useState<any>(null);
46
53
 
47
54
  const { projectName, '*': splat } = useParams();
48
55
  const pathParts = splat ? splat.split('/') : [];
@@ -57,13 +64,36 @@ export const TestPage = () => {
57
64
 
58
65
  const fetchData = async () => {
59
66
  try {
60
- const { testData, logs, typeErrors, lintErrors } = await fetchTestData(projectName, testPath, runtime);
61
- setTestData(testData);
62
- setLogs(logs);
63
- setTypeErrors(typeErrors);
64
- setLintErrors(lintErrors);
67
+ // First fetch test data
68
+ const testResponse = await fetchTestData(projectName, testPath, runtime);
69
+ setTestData(testResponse.testData);
70
+ setTestsExist(!!testResponse.testData);
71
+ setLogs(testResponse.logs);
72
+ setTypeErrors(testResponse.typeErrors);
73
+ setLintErrors(testResponse.lintErrors);
74
+
75
+ // Then fetch summary.json
76
+ try {
77
+ const summaryResponse = await fetch(`reports/${projectName}/summary.json`);
78
+ if (!summaryResponse.ok) throw new Error('Failed to fetch summary');
79
+ const allSummaries = await summaryResponse.json();
80
+ const testSummary = allSummaries[testPath];
81
+
82
+ console.log("testSummary", testSummary)
83
+ if (testSummary) {
84
+ setSummary(testSummary);
85
+ setErrorCounts({
86
+ typeErrors: testSummary.typeErrors || 0,
87
+ staticErrors: testSummary.staticErrors || 0,
88
+ runTimeErrors: testSummary.runTimeErrors || 0
89
+ });
90
+ }
91
+ } catch (err) {
92
+ console.error('Failed to load summary:', err);
93
+ }
65
94
  } catch (err) {
66
95
  setError(err instanceof Error ? err.message : 'Unknown error');
96
+ setTestsExist(false);
67
97
  } finally {
68
98
  setLoading(false);
69
99
  }
@@ -83,30 +113,30 @@ export const TestPage = () => {
83
113
  navItems={[
84
114
  {
85
115
  to: `#results`,
86
- label: testData?.givens.some(g => g.whens.some(w => w.error) || g.thens.some(t => t.error))
116
+ label: !testsExist
87
117
  ? '❌ BDD'
88
- : '✅ BDD',
118
+ : testData?.givens.some(g => g.whens.some(w => w.error) || g.thens.some(t => t.error))
119
+ ? '❌ BDD'
120
+ : '✅ BDD',
89
121
  active: route === 'results'
90
122
  },
91
123
  {
92
124
  to: `#logs`,
93
- label: logs?.includes('error') || logs?.includes('fail')
94
- ? '❌ Logs'
95
- : '✅ Logs',
125
+ label: `Runtime logs`,
96
126
  active: route === 'logs'
97
127
  },
98
128
  {
99
129
  to: `#types`,
100
- label: typeErrors
101
- ? `❌ ${typeErrors.split('\n').filter(l => l.includes('error')).length} Type Errors`
102
- : '✅ Type check',
130
+ label: errorCounts.typeErrors > 0
131
+ ? `tsc ( * ${errorCounts.typeErrors})`
132
+ : 'tsc ✅ ',
103
133
  active: route === 'types'
104
134
  },
105
135
  {
106
136
  to: `#lint`,
107
- label: lintErrors
108
- ? `❌ ${lintErrors.split('\n').filter(l => l.includes('error')).length} Lint Errors`
109
- : '✅ Lint',
137
+ label: errorCounts.staticErrors > 0
138
+ ? `eslint ( *${errorCounts.staticErrors}) `
139
+ : 'eslint ✅',
110
140
  active: route === 'lint'
111
141
  },
112
142
 
@@ -132,7 +162,27 @@ export const TestPage = () => {
132
162
 
133
163
  <Tab.Content className="mt-3">
134
164
  <Tab.Pane eventKey="results">
135
- {testData ? (
165
+ {!testsExist ? (
166
+ <Alert variant="danger" className="mt-3">
167
+ <h4>Tests did not run to completion</h4>
168
+ <p>The test results file (tests.json) was not found or could not be loaded.</p>
169
+ <div className="mt-3">
170
+ <Button
171
+ variant="outline-light"
172
+ onClick={() => setRoute('logs')}
173
+ className="me-2"
174
+ >
175
+ View Runtime Logs
176
+ </Button>
177
+ <Button
178
+ variant="outline-light"
179
+ onClick={() => navigate(`/projects/${projectName}#${runtime}`)}
180
+ >
181
+ View Build Logs
182
+ </Button>
183
+ </div>
184
+ </Alert>
185
+ ) : testData ? (
136
186
  <div className="test-results">
137
187
  <div className="mb-3">
138
188
 
package/src/utils/api.ts CHANGED
@@ -16,26 +16,52 @@ export const fetchTestData = async (
16
16
  projectName: string,
17
17
  filepath: string,
18
18
  runTime: string
19
- ) => {
19
+ ): Promise<{
20
+ testData: any | null;
21
+ logs: string;
22
+ typeErrors: string;
23
+ lintErrors: string;
24
+ error: string | null;
25
+ }> => {
20
26
  const basePath = `reports/${projectName}/${filepath
21
27
  .split(".")
22
28
  .slice(0, -1)
23
29
  .join(".")}/${runTime}`;
24
30
 
25
- const [testRes, logsRes, typeRes, lintRes] = await Promise.all([
26
- fetch(`${basePath}/tests.json`),
27
- fetch(`${basePath}/logs.txt`),
28
- fetch(`${basePath}/type_errors.txt`),
29
- fetch(`${basePath}/lint_errors.txt`),
30
- ]);
31
+ try {
32
+ const [testRes, logsRes, typeRes, lintRes] = await Promise.all([
33
+ fetch(`${basePath}/tests.json`),
34
+ fetch(`${basePath}/logs.txt`),
35
+ fetch(`${basePath}/type_errors.txt`),
36
+ fetch(`${basePath}/lint_errors.txt`),
37
+ ]);
31
38
 
32
- return {
33
- // testData: await testRes.json(),
34
- testData: fakeTestJson,
35
- logs: await logsRes.text(),
36
- typeErrors: await typeRes.text(),
37
- lintErrors: await lintRes.text(),
38
- };
39
+ if (!testRes.ok) {
40
+ return {
41
+ testData: null,
42
+ logs: await logsRes.text(),
43
+ typeErrors: await typeRes.text(),
44
+ lintErrors: await lintRes.text(),
45
+ error: "Tests did not complete successfully. Please check the build and runtime logs for errors."
46
+ };
47
+ }
48
+
49
+ return {
50
+ testData: await testRes.json(),
51
+ logs: await logsRes.text(),
52
+ typeErrors: await typeRes.text(),
53
+ lintErrors: await lintRes.text(),
54
+ error: null
55
+ };
56
+ } catch (err) {
57
+ return {
58
+ testData: null,
59
+ logs: "",
60
+ typeErrors: "",
61
+ lintErrors: "",
62
+ error: `Failed to load test data: ${err instanceof Error ? err.message : String(err)}`
63
+ };
64
+ }
39
65
  };
40
66
 
41
67
  export const fetchBuildLogs = async (projectName: string, runtime: string) => {
@@ -45,182 +71,3 @@ export const fetchBuildLogs = async (projectName: string, runtime: string) => {
45
71
  return await res.json();
46
72
  };
47
73
 
48
- const fakeTestJson = {
49
- name: "Testing the Rectangle class",
50
- givens: [
51
- {
52
- key: "test0",
53
- name: "Default",
54
- whens: [
55
- {
56
- name: "setWidth: 4",
57
- error: true,
58
- },
59
- {
60
- name: "setHeight: 19",
61
- error: true,
62
- },
63
- ],
64
- thens: [
65
- {
66
- name: "getWidth: 4",
67
- error: false,
68
- },
69
- {
70
- name: "getHeight: 19",
71
- error: false,
72
- },
73
- ],
74
- error: null,
75
- features: [
76
- "https://api.github.com/repos/adamwong246/testeranto/issues/8",
77
- ],
78
- },
79
- {
80
- key: "test1",
81
- name: "Default",
82
- whens: [
83
- {
84
- name: "setWidth: 4",
85
- error: true,
86
- },
87
- {
88
- name: "setHeight: 5",
89
- error: true,
90
- },
91
- ],
92
- thens: [
93
- {
94
- name: "getWidth: 4",
95
- error: false,
96
- },
97
- {
98
- name: "getHeight: 5",
99
- error: false,
100
- },
101
- {
102
- name: "area: 20",
103
- error: false,
104
- },
105
- {
106
- name: "AreaPlusCircumference: 38",
107
- error: false,
108
- },
109
- ],
110
- error: null,
111
- features: ["Rectangles have width and height."],
112
- },
113
- {
114
- key: "test2",
115
- name: "Default",
116
- whens: [
117
- {
118
- name: "setHeight: 4",
119
- error: true,
120
- },
121
- {
122
- name: "setWidth: 33",
123
- error: true,
124
- },
125
- ],
126
- thens: [
127
- {
128
- name: "area: 132",
129
- error: false,
130
- },
131
- ],
132
- error: null,
133
- features: ["Rectangles have area"],
134
- },
135
- {
136
- key: "test2_1",
137
- name: "Default",
138
- whens: [],
139
- thens: [
140
- {
141
- name: "getWidth: 2",
142
- error: false,
143
- },
144
- {
145
- name: "getHeight: 2",
146
- error: false,
147
- },
148
- ],
149
- error: null,
150
- features: ["Rectangles have default size"],
151
- },
152
- {
153
- key: "test3",
154
- name: "Default",
155
- whens: [
156
- {
157
- name: "setHeight: 5",
158
- error: true,
159
- },
160
- {
161
- name: "setWidth: 5",
162
- error: true,
163
- },
164
- ],
165
- thens: [
166
- {
167
- name: "area: 25",
168
- error: false,
169
- },
170
- ],
171
- error: null,
172
- features: [
173
- "file:///Users/adam/Code/testeranto-starter/src/Rectangle/README.md",
174
- ],
175
- },
176
- {
177
- key: "test4",
178
- name: "Default",
179
- whens: [
180
- {
181
- name: "setHeight: 6",
182
- error: true,
183
- },
184
- {
185
- name: "setWidth: 6",
186
- error: true,
187
- },
188
- ],
189
- thens: [
190
- {
191
- name: "area: 36",
192
- error: false,
193
- },
194
- ],
195
- error: null,
196
- features: ["Rectangles have area"],
197
- },
198
- {
199
- key: "test5",
200
- name: "Default",
201
- whens: [],
202
- thens: [
203
- {
204
- name: "getWidth: 2",
205
- error: false,
206
- },
207
- {
208
- name: "getHeight: 2",
209
- error: false,
210
- },
211
- ],
212
- error: null,
213
- features: ["Rectangles have default size, again"],
214
- },
215
- ],
216
- checks: [],
217
- fails: 0,
218
- features: [
219
- "https://api.github.com/repos/adamwong246/testeranto/issues/8",
220
- "Rectangles have width and height.",
221
- "Rectangles have area",
222
- "Rectangles have default size",
223
- "file:///Users/adam/Code/testeranto-starter/src/Rectangle/README.md",
224
- "Rectangles have default size, again",
225
- ],
226
- };