testeranto 0.159.0 → 0.161.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/common/src/PM/PM_WithEslintAndTsc.js +8 -1
- package/dist/common/src/lib/baseBuilder.test/baseBuilder.test.implementation.js +13 -1
- package/dist/common/src/lib/baseBuilder.test/baseBuilder.test.mock.js +4 -1
- package/dist/common/src/lib/baseBuilder.test/baseBuilder.test.specification.js +6 -1
- package/dist/common/src/lib/classBuilder.test/classBuilder.test.implementation.js +9 -8
- package/dist/common/tsconfig.common.tsbuildinfo +1 -1
- package/dist/module/src/PM/PM_WithEslintAndTsc.js +8 -1
- package/dist/module/src/ProjectPage.js +128 -21
- package/dist/module/src/ProjectsPage.js +15 -9
- package/dist/module/src/TestPage.js +13 -1
- package/dist/module/src/lib/baseBuilder.test/baseBuilder.test.implementation.js +13 -1
- package/dist/module/src/lib/baseBuilder.test/baseBuilder.test.mock.js +4 -1
- package/dist/module/src/lib/baseBuilder.test/baseBuilder.test.specification.js +6 -1
- package/dist/module/src/lib/classBuilder.test/classBuilder.test.implementation.js +9 -8
- package/dist/module/tsconfig.module.tsbuildinfo +1 -1
- package/dist/prebuild/App.js +814 -376
- package/dist/prebuild/run.mjs +8 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/notify.sh +47 -0
- package/package.json +1 -1
- package/src/PM/PM_WithEslintAndTsc.ts +8 -1
- package/src/ProjectPage.tsx +204 -38
- package/src/ProjectsPage.tsx +23 -19
- package/src/TestPage.tsx +12 -1
- package/src/lib/baseBuilder.test/baseBuilder.test.implementation.ts +15 -9
- package/src/lib/baseBuilder.test/baseBuilder.test.mock.ts +4 -1
- package/src/lib/baseBuilder.test/baseBuilder.test.specification.ts +6 -1
- package/src/lib/classBuilder.test/classBuilder.test.implementation.ts +8 -5
- package/testeranto/App.js +814 -376
- package/testeranto/bundles/node/allTests/metafile.json +15 -10
- package/testeranto/bundles/node/allTests/src/lib/baseBuilder.test/baseBuilder.test.node.mjs +22 -5
- package/testeranto/bundles/node/allTests/src/lib/classBuilder.test/classBuilder.test.mjs +7 -7
- package/testeranto/bundles/pure/allTests/metafile.json +7 -7
- package/testeranto/bundles/pure/allTests/src/lib/baseBuilder.test/baseBuilder.test.pure.mjs +22 -5
- package/testeranto/bundles/web/allTests/metafile.json +7 -7
- package/testeranto/bundles/web/allTests/src/lib/baseBuilder.test/baseBuilder.test.web.mjs +22 -5
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/lint_errors.txt +4 -4
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/message.txt +2 -1
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/prompt.txt +5 -0
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/type_errors.txt +22 -19
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.pure/pure/lint_errors.txt +4 -4
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.pure/pure/message.txt +2 -1
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.pure/pure/prompt.txt +5 -0
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.pure/pure/type_errors.txt +22 -19
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/lint_errors.txt +4 -4
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/logs.txt +1 -9
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/message.txt +2 -1
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/prompt.txt +5 -0
- package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/type_errors.txt +22 -19
- package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/bdd_errors.txt +1 -0
- package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/logs.txt +85 -23
- package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/message.txt +2 -1
- package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/prompt.txt +5 -0
- package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/tests.json +24 -0
- package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/type_errors.txt +13 -9
- package/testeranto/reports/allTests/summary.json +5 -5
- package/dist/module/src/BuildLogsPage.js +0 -99
- package/dist/module/src/Project.js +0 -332
- package/src/BuildLogsPage.tsx +0 -108
- package/src/Project.tsx +0 -375
package/notify.sh
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/bin/zsh
|
|
2
|
+
|
|
3
|
+
# NOTIFICATION SYSTEM DOCUMENTATION
|
|
4
|
+
# ================================
|
|
5
|
+
# This script plays system sounds for CI/CD notifications. The AI assistant uses it to:
|
|
6
|
+
# 1. Alert when human input is needed
|
|
7
|
+
# 2. Signal completion of tasks
|
|
8
|
+
# 3. Indicate errors/warnings
|
|
9
|
+
|
|
10
|
+
# USAGE:
|
|
11
|
+
# ./notify.sh [sound] [volume]
|
|
12
|
+
# sound: Any from the list below (default: Ping)
|
|
13
|
+
# volume: 0-1 (default: 1)
|
|
14
|
+
|
|
15
|
+
# AVAILABLE SOUNDS:
|
|
16
|
+
# Basso - Low pitch error sound (use for critical failures)
|
|
17
|
+
# Blow - Quick negative sound
|
|
18
|
+
# Bottle - Light glass ping
|
|
19
|
+
# Frog - Unique attention-grabber
|
|
20
|
+
# Funk - Positive completion sound
|
|
21
|
+
# Glass - Clean success notification
|
|
22
|
+
# Hero - Triumphant completion
|
|
23
|
+
# Morse - For process-related events
|
|
24
|
+
# Ping - Default neutral notification
|
|
25
|
+
# Pop - Light positive sound
|
|
26
|
+
# Purr - Subtle background notification
|
|
27
|
+
# Sosumi - Urgent alert sound
|
|
28
|
+
# Submarine- Deep warning sound
|
|
29
|
+
# Tink - High-pitched attention sound
|
|
30
|
+
|
|
31
|
+
# STANDARD USAGE PATTERNS:
|
|
32
|
+
# [ACTION NEEDED] -> ./notify.sh Sosumi 0.8
|
|
33
|
+
# [COMPLETED] -> ./notify.sh Glass 0.5
|
|
34
|
+
# [ERROR] -> ./notify.sh Basso 1
|
|
35
|
+
# [WARNING] -> ./notify.sh Tink 0.6
|
|
36
|
+
# [WORKING] -> ./notify.sh Morse 0.3
|
|
37
|
+
|
|
38
|
+
SOUND=${1:-Ping}
|
|
39
|
+
VOLUME=${2:-1} # Range: 0 (silent) to 1 (full volume)
|
|
40
|
+
|
|
41
|
+
# Play the specified system sound
|
|
42
|
+
afplay -v $VOLUME /System/Library/Sounds/$SOUND.aiff
|
|
43
|
+
|
|
44
|
+
# Exit codes:
|
|
45
|
+
# 0 - Success
|
|
46
|
+
# 1 - Invalid sound specified
|
|
47
|
+
# 2 - Volume out of range
|
package/package.json
CHANGED
|
@@ -210,6 +210,11 @@ ${addableFiles
|
|
|
210
210
|
})
|
|
211
211
|
.join("\n")}
|
|
212
212
|
|
|
213
|
+
/read node_modules/testeranto/docs/index.md
|
|
214
|
+
/read node_modules/testeranto/docs/style.md
|
|
215
|
+
/read node_modules/testeranto/docs/testing.ai.txt
|
|
216
|
+
/read node_modules/testeranto/src/CoreTypes.ts
|
|
217
|
+
|
|
213
218
|
/read ${testPaths}
|
|
214
219
|
/read ${logPath}
|
|
215
220
|
/read ${typePath}
|
|
@@ -219,7 +224,9 @@ ${addableFiles
|
|
|
219
224
|
|
|
220
225
|
fs.writeFileSync(
|
|
221
226
|
messagePath,
|
|
222
|
-
`
|
|
227
|
+
`
|
|
228
|
+
Fix the failing tests described in ${testPaths} and ${logPath}. Focus on the bdd tests before all other concerns. You may add any debugging you think is necessary.
|
|
229
|
+
`
|
|
223
230
|
);
|
|
224
231
|
|
|
225
232
|
this.summary[
|
package/src/ProjectPage.tsx
CHANGED
|
@@ -1,5 +1,185 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { Tab } from 'react-bootstrap';
|
|
3
|
+
import { Card, ListGroup, Badge } from 'react-bootstrap';
|
|
4
|
+
|
|
5
|
+
const BuildLogViewer = ({ logs, runtime }: { logs: any, runtime: string }) => {
|
|
6
|
+
if (!logs) return <Alert variant="info">Loading {runtime.toLowerCase()} build logs...</Alert>;
|
|
7
|
+
|
|
8
|
+
const hasErrors = logs.errors?.length > 0;
|
|
9
|
+
const hasWarnings = logs.warnings?.length > 0;
|
|
10
|
+
const [activeTab, setActiveTab] = useState('summary');
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div>
|
|
14
|
+
<Tab.Container activeKey={activeTab} onSelect={(k) => setActiveTab(k || 'summary')}>
|
|
15
|
+
<Nav variant="tabs" className="mb-3">
|
|
16
|
+
<Nav.Item>
|
|
17
|
+
<Nav.Link eventKey="summary">
|
|
18
|
+
Build Summary
|
|
19
|
+
</Nav.Link>
|
|
20
|
+
</Nav.Item>
|
|
21
|
+
<Nav.Item>
|
|
22
|
+
<Nav.Link eventKey="warnings">
|
|
23
|
+
{hasWarnings ? `⚠️ Warnings (${logs.warnings.length})` : 'Warnings'}
|
|
24
|
+
</Nav.Link>
|
|
25
|
+
</Nav.Item>
|
|
26
|
+
<Nav.Item>
|
|
27
|
+
<Nav.Link eventKey="errors">
|
|
28
|
+
{hasErrors ? `❌ Errors (${logs.errors.length})` : 'Errors'}
|
|
29
|
+
</Nav.Link>
|
|
30
|
+
</Nav.Item>
|
|
31
|
+
</Nav>
|
|
32
|
+
|
|
33
|
+
<Tab.Content>
|
|
34
|
+
<Tab.Pane eventKey="summary">
|
|
35
|
+
<Card>
|
|
36
|
+
<Card.Header className="d-flex justify-content-between align-items-center">
|
|
37
|
+
<h5>Build Summary</h5>
|
|
38
|
+
<div>
|
|
39
|
+
{hasErrors && (
|
|
40
|
+
<Badge bg="danger" className="me-2">
|
|
41
|
+
{logs.errors.length} Error{logs.errors.length !== 1 ? 's' : ''}
|
|
42
|
+
</Badge>
|
|
43
|
+
)}
|
|
44
|
+
{hasWarnings && (
|
|
45
|
+
<Badge bg="warning" text="dark">
|
|
46
|
+
{logs.warnings.length} Warning{logs.warnings.length !== 1 ? 's' : ''}
|
|
47
|
+
</Badge>
|
|
48
|
+
)}
|
|
49
|
+
{!hasErrors && !hasWarnings && (
|
|
50
|
+
<Badge bg="success">Build Successful</Badge>
|
|
51
|
+
)}
|
|
52
|
+
</div>
|
|
53
|
+
</Card.Header>
|
|
54
|
+
<Card.Body>
|
|
55
|
+
<div className="mb-3">
|
|
56
|
+
<h6>Input Files ({Object.keys(logs.metafile?.inputs || {}).length})</h6>
|
|
57
|
+
<ListGroup className="max-h-200 overflow-auto">
|
|
58
|
+
{Object.keys(logs.metafile?.inputs || {}).map((file) => (
|
|
59
|
+
<ListGroup.Item key={file} className="py-2">
|
|
60
|
+
<code>{file}</code>
|
|
61
|
+
<div className="text-muted small">
|
|
62
|
+
{logs.metafile.inputs[file].bytes} bytes
|
|
63
|
+
</div>
|
|
64
|
+
</ListGroup.Item>
|
|
65
|
+
))}
|
|
66
|
+
</ListGroup>
|
|
67
|
+
</div>
|
|
68
|
+
<div>
|
|
69
|
+
<h6>Output Files ({Object.keys(logs.metafile?.outputs || {}).length})</h6>
|
|
70
|
+
<ListGroup className="max-h-200 overflow-auto">
|
|
71
|
+
{Object.keys(logs.metafile?.outputs || {}).map((file) => (
|
|
72
|
+
<ListGroup.Item key={file} className="py-2">
|
|
73
|
+
<code>{file}</code>
|
|
74
|
+
<div className="text-muted small">
|
|
75
|
+
{logs.metafile.outputs[file].bytes} bytes
|
|
76
|
+
{logs.metafile.outputs[file].entryPoint && (
|
|
77
|
+
<span className="ms-2 badge bg-info">Entry Point</span>
|
|
78
|
+
)}
|
|
79
|
+
</div>
|
|
80
|
+
</ListGroup.Item>
|
|
81
|
+
))}
|
|
82
|
+
</ListGroup>
|
|
83
|
+
</div>
|
|
84
|
+
</Card.Body>
|
|
85
|
+
</Card>
|
|
86
|
+
|
|
87
|
+
</Tab.Pane>
|
|
88
|
+
<Tab.Pane eventKey="warnings">
|
|
89
|
+
{hasWarnings ? (
|
|
90
|
+
<Card className="border-warning">
|
|
91
|
+
<Card.Header className="bg-warning text-white d-flex justify-content-between align-items-center">
|
|
92
|
+
<span>Build Warnings ({logs.warnings.length})</span>
|
|
93
|
+
<Badge bg="light" text="dark">
|
|
94
|
+
{new Date().toLocaleString()}
|
|
95
|
+
</Badge>
|
|
96
|
+
</Card.Header>
|
|
97
|
+
<Card.Body className="p-0">
|
|
98
|
+
<ListGroup variant="flush">
|
|
99
|
+
{logs.warnings.map((warn: any, i: number) => (
|
|
100
|
+
<ListGroup.Item key={i} className="text-warning">
|
|
101
|
+
<div className="d-flex justify-content-between">
|
|
102
|
+
<strong>
|
|
103
|
+
{warn.location?.file || 'Unknown file'}
|
|
104
|
+
{warn.location?.line && `:${warn.location.line}`}
|
|
105
|
+
</strong>
|
|
106
|
+
<small className="text-muted">
|
|
107
|
+
{warn.pluginName ? `[${warn.pluginName}]` : ''}
|
|
108
|
+
</small>
|
|
109
|
+
</div>
|
|
110
|
+
<div className="mt-1">
|
|
111
|
+
<pre className="mb-0 p-2 bg-light rounded">
|
|
112
|
+
{warn.text || warn.message || JSON.stringify(warn)}
|
|
113
|
+
</pre>
|
|
114
|
+
</div>
|
|
115
|
+
{warn.detail && (
|
|
116
|
+
<div className="mt-1 small text-muted">
|
|
117
|
+
<pre className="mb-0 p-2 bg-light rounded">
|
|
118
|
+
{warn.detail}
|
|
119
|
+
</pre>
|
|
120
|
+
</div>
|
|
121
|
+
)}
|
|
122
|
+
</ListGroup.Item>
|
|
123
|
+
))}
|
|
124
|
+
</ListGroup>
|
|
125
|
+
</Card.Body>
|
|
126
|
+
</Card>
|
|
127
|
+
) : (
|
|
128
|
+
<Alert variant="info">No warnings found</Alert>
|
|
129
|
+
)}
|
|
130
|
+
</Tab.Pane>
|
|
131
|
+
<Tab.Pane eventKey="errors">
|
|
132
|
+
{hasErrors ? (
|
|
133
|
+
<Card className="border-danger">
|
|
134
|
+
<Card.Header className="bg-danger text-white d-flex justify-content-between align-items-center">
|
|
135
|
+
<span>Build Errors ({logs.errors.length})</span>
|
|
136
|
+
<Badge bg="light" text="dark">
|
|
137
|
+
{new Date().toLocaleString()}
|
|
138
|
+
</Badge>
|
|
139
|
+
</Card.Header>
|
|
140
|
+
<Card.Body className="p-0">
|
|
141
|
+
<ListGroup variant="flush">
|
|
142
|
+
{logs.errors.map((err: any, i: number) => (
|
|
143
|
+
<ListGroup.Item key={i} className="text-danger">
|
|
144
|
+
<div className="d-flex justify-content-between">
|
|
145
|
+
<strong>
|
|
146
|
+
{err.location?.file || 'Unknown file'}
|
|
147
|
+
{err.location?.line && `:${err.location.line}`}
|
|
148
|
+
</strong>
|
|
149
|
+
<small className="text-muted">
|
|
150
|
+
{err.pluginName ? `[${err.pluginName}]` : ''}
|
|
151
|
+
</small>
|
|
152
|
+
</div>
|
|
153
|
+
<div className="mt-1">
|
|
154
|
+
<pre className="mb-0 p-2 bg-light rounded">
|
|
155
|
+
{err.text || err.message || JSON.stringify(err)}
|
|
156
|
+
</pre>
|
|
157
|
+
</div>
|
|
158
|
+
{err.detail && (
|
|
159
|
+
<div className="mt-1 small text-muted">
|
|
160
|
+
<pre className="mb-0 p-2 bg-light rounded">
|
|
161
|
+
{err.detail}
|
|
162
|
+
</pre>
|
|
163
|
+
</div>
|
|
164
|
+
)}
|
|
165
|
+
</ListGroup.Item>
|
|
166
|
+
))}
|
|
167
|
+
</ListGroup>
|
|
168
|
+
</Card.Body>
|
|
169
|
+
</Card>
|
|
170
|
+
) : (
|
|
171
|
+
<Alert variant="success">
|
|
172
|
+
<h5>No Errors Found</h5>
|
|
173
|
+
<p className="mb-0">The build completed without any errors.</p>
|
|
174
|
+
</Alert>
|
|
175
|
+
)}
|
|
176
|
+
</Tab.Pane>
|
|
177
|
+
</Tab.Content>
|
|
178
|
+
</Tab.Container>
|
|
179
|
+
</div>
|
|
180
|
+
);
|
|
181
|
+
};
|
|
182
|
+
import { Navbar, Nav, Tab, Container, Alert, Badge, Table, Button, Card } from 'react-bootstrap';
|
|
3
183
|
import { useParams, useNavigate, useLocation, Link } from 'react-router-dom';
|
|
4
184
|
|
|
5
185
|
import { ISummary } from './Types';
|
|
@@ -95,24 +275,37 @@ export const ProjectPage = () => {
|
|
|
95
275
|
title={projectName}
|
|
96
276
|
backLink="/"
|
|
97
277
|
navItems={[
|
|
98
|
-
{
|
|
278
|
+
{
|
|
279
|
+
to: `#tests`,
|
|
280
|
+
label: Object.values(summary).some(t => t.runTimeErrors > 0) ? '❌ Tests' :
|
|
281
|
+
Object.values(summary).some(t => t.typeErrors > 0 || t.staticErrors > 0) ? '⚠️ Tests' : '✅ Tests',
|
|
282
|
+
active: route === 'tests',
|
|
283
|
+
className: Object.values(summary).some(t => t.runTimeErrors > 0) ? 'text-danger fw-bold' :
|
|
284
|
+
Object.values(summary).some(t => t.typeErrors > 0 || t.staticErrors > 0) ? 'text-warning fw-bold' : ''
|
|
285
|
+
},
|
|
99
286
|
{
|
|
100
287
|
to: `#node`,
|
|
101
|
-
label: nodeLogs?.errors?.length ? '❌ Node Build' :
|
|
288
|
+
label: nodeLogs?.errors?.length ? '❌ Node Build' :
|
|
289
|
+
nodeLogs?.warnings?.length ? '⚠️ Node Build' : 'Node Build',
|
|
102
290
|
active: route === 'node',
|
|
103
|
-
className: nodeLogs?.errors?.length ? 'text-danger fw-bold' :
|
|
291
|
+
className: nodeLogs?.errors?.length ? 'text-danger fw-bold' :
|
|
292
|
+
nodeLogs?.warnings?.length ? 'text-warning fw-bold' : ''
|
|
104
293
|
},
|
|
105
294
|
{
|
|
106
295
|
to: `#web`,
|
|
107
|
-
label: webLogs?.errors?.length ? '❌ Web Build' :
|
|
296
|
+
label: webLogs?.errors?.length ? '❌ Web Build' :
|
|
297
|
+
webLogs?.warnings?.length ? '⚠️ Web Build' : 'Web Build',
|
|
108
298
|
active: route === 'web',
|
|
109
|
-
className: webLogs?.errors?.length ? 'text-danger fw-bold' :
|
|
299
|
+
className: webLogs?.errors?.length ? 'text-danger fw-bold' :
|
|
300
|
+
webLogs?.warnings?.length ? 'text-warning fw-bold' : ''
|
|
110
301
|
},
|
|
111
302
|
{
|
|
112
303
|
to: `#pure`,
|
|
113
|
-
label: pureLogs?.errors?.length ? '❌ Pure Build' :
|
|
304
|
+
label: pureLogs?.errors?.length ? '❌ Pure Build' :
|
|
305
|
+
pureLogs?.warnings?.length ? '⚠️ Pure Build' : 'Pure Build',
|
|
114
306
|
active: route === 'pure',
|
|
115
|
-
className: pureLogs?.errors?.length ? 'text-danger fw-bold' :
|
|
307
|
+
className: pureLogs?.errors?.length ? 'text-danger fw-bold' :
|
|
308
|
+
pureLogs?.warnings?.length ? 'text-warning fw-bold' : ''
|
|
116
309
|
},
|
|
117
310
|
]}
|
|
118
311
|
/>
|
|
@@ -129,7 +322,6 @@ export const ProjectPage = () => {
|
|
|
129
322
|
<thead>
|
|
130
323
|
<tr>
|
|
131
324
|
<th>Test</th>
|
|
132
|
-
<th>Build logs</th>
|
|
133
325
|
<th>BDD Errors</th>
|
|
134
326
|
<th>Type Errors</th>
|
|
135
327
|
<th>Lint Errors</th>
|
|
@@ -147,11 +339,6 @@ export const ProjectPage = () => {
|
|
|
147
339
|
{testName}
|
|
148
340
|
</a>
|
|
149
341
|
</td>
|
|
150
|
-
<td>
|
|
151
|
-
<a href={`#/projects/${projectName}#${runTime}`}>
|
|
152
|
-
{runTime} {testData.runTimeErrors === 0 ? '✅' : '❌'}
|
|
153
|
-
</a>
|
|
154
|
-
</td>
|
|
155
342
|
<td>
|
|
156
343
|
<a href={`#/projects/${projectName}/tests/${encodeURIComponent(testName)}/${runTime}#results`}>
|
|
157
344
|
{testData.runTimeErrors === 0 ? '✅ Passed' :
|
|
@@ -176,34 +363,13 @@ export const ProjectPage = () => {
|
|
|
176
363
|
</Table>
|
|
177
364
|
</Tab.Pane>
|
|
178
365
|
<Tab.Pane eventKey="node">
|
|
179
|
-
<
|
|
180
|
-
{nodeLogs.errors.map((err, i) => (
|
|
181
|
-
<li key={i}>{err.text || err.message || JSON.stringify(err)}</li>
|
|
182
|
-
))}
|
|
183
|
-
</ul>
|
|
184
|
-
<pre className="bg-dark text-white p-3">
|
|
185
|
-
{nodeLogs ? JSON.stringify(nodeLogs, null, 2) : 'Loading node build logs...'}
|
|
186
|
-
</pre>
|
|
366
|
+
<BuildLogViewer logs={nodeLogs} runtime="Node" />
|
|
187
367
|
</Tab.Pane>
|
|
188
368
|
<Tab.Pane eventKey="web">
|
|
189
|
-
<
|
|
190
|
-
{webLogs.errors.map((err, i) => (
|
|
191
|
-
<li key={i}>{err.text || err.message || JSON.stringify(err)}</li>
|
|
192
|
-
))}
|
|
193
|
-
</ul>
|
|
194
|
-
<pre className="bg-dark text-white p-3">
|
|
195
|
-
{webLogs ? JSON.stringify(webLogs, null, 2) : 'Loading web build logs...'}
|
|
196
|
-
</pre>
|
|
369
|
+
<BuildLogViewer logs={webLogs} runtime="Web" />
|
|
197
370
|
</Tab.Pane>
|
|
198
371
|
<Tab.Pane eventKey="pure">
|
|
199
|
-
<
|
|
200
|
-
{pureLogs.errors.map((err, i) => (
|
|
201
|
-
<li key={i}>{err.text || err.message || JSON.stringify(err)}</li>
|
|
202
|
-
))}
|
|
203
|
-
</ul>
|
|
204
|
-
<pre className="bg-dark text-white p-3">
|
|
205
|
-
{pureLogs ? JSON.stringify(pureLogs, null, 2) : 'Loading pure build logs...'}
|
|
206
|
-
</pre>
|
|
372
|
+
<BuildLogViewer logs={pureLogs} runtime="Pure" />
|
|
207
373
|
</Tab.Pane>
|
|
208
374
|
</Tab.Content>
|
|
209
375
|
</Tab.Container>
|
package/src/ProjectsPage.tsx
CHANGED
|
@@ -54,9 +54,9 @@ export const ProjectsPage = () => {
|
|
|
54
54
|
return {
|
|
55
55
|
name,
|
|
56
56
|
testCount: Object.keys(summary).length,
|
|
57
|
-
nodeStatus: nodeData.errors?.length ? 'failed' : 'success',
|
|
58
|
-
webStatus: webData.errors?.length ? 'failed' : 'success',
|
|
59
|
-
pureStatus: pureData.errors?.length ? 'failed' : 'success',
|
|
57
|
+
nodeStatus: nodeData.errors?.length ? 'failed' : nodeData.warnings?.length ? 'warning' : 'success',
|
|
58
|
+
webStatus: webData.errors?.length ? 'failed' : webData.warnings?.length ? 'warning' : 'success',
|
|
59
|
+
pureStatus: pureData.errors?.length ? 'failed' : pureData.warnings?.length ? 'warning' : 'success',
|
|
60
60
|
config: Object.keys(configData).length,
|
|
61
61
|
};
|
|
62
62
|
})
|
|
@@ -77,6 +77,7 @@ export const ProjectsPage = () => {
|
|
|
77
77
|
switch (status) {
|
|
78
78
|
case 'success': return '✅';
|
|
79
79
|
case 'failed': return '❌';
|
|
80
|
+
case 'warning': return '⚠️';
|
|
80
81
|
default: return '❓';
|
|
81
82
|
}
|
|
82
83
|
};
|
|
@@ -112,11 +113,17 @@ export const ProjectsPage = () => {
|
|
|
112
113
|
<div style={{ maxHeight: '200px', overflowY: 'auto' }}>
|
|
113
114
|
{summaries[project.name] ? (
|
|
114
115
|
Object.keys(summaries[project.name]).map(testName => {
|
|
116
|
+
const testData = summaries[project.name][testName];
|
|
115
117
|
const runTime = configs[project.name].tests.find((t) => t[0] === testName)[1];
|
|
118
|
+
const hasRuntimeErrors = testData.runTimeErrors > 0;
|
|
119
|
+
const hasStaticErrors = testData.typeErrors > 0 || testData.staticErrors > 0;
|
|
116
120
|
|
|
117
121
|
return (
|
|
118
122
|
<div key={testName}>
|
|
119
|
-
<a
|
|
123
|
+
<a
|
|
124
|
+
href={`#/projects/${project.name}/tests/${encodeURIComponent(testName)}/${runTime}`}
|
|
125
|
+
>
|
|
126
|
+
{hasRuntimeErrors ? '❌ ' : hasStaticErrors ? '⚠️ ' : ''}
|
|
120
127
|
{testName.split('/').pop()}
|
|
121
128
|
</a>
|
|
122
129
|
</div>
|
|
@@ -128,27 +135,24 @@ export const ProjectsPage = () => {
|
|
|
128
135
|
</div>
|
|
129
136
|
</td>
|
|
130
137
|
<td>
|
|
131
|
-
<a
|
|
132
|
-
{
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
)}
|
|
138
|
+
<a
|
|
139
|
+
href={`#/projects/${project.name}#node`}
|
|
140
|
+
>
|
|
141
|
+
{getStatusIcon(project.nodeStatus)} Node build logs
|
|
136
142
|
</a>
|
|
137
143
|
</td>
|
|
138
144
|
<td>
|
|
139
|
-
<a
|
|
140
|
-
{
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
)}
|
|
145
|
+
<a
|
|
146
|
+
href={`#/projects/${project.name}#web`}
|
|
147
|
+
>
|
|
148
|
+
{getStatusIcon(project.webStatus)} Web build logs
|
|
144
149
|
</a>
|
|
145
150
|
</td>
|
|
146
151
|
<td>
|
|
147
|
-
<a
|
|
148
|
-
{
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
)}
|
|
152
|
+
<a
|
|
153
|
+
href={`#/projects/${project.name}#pure`}
|
|
154
|
+
>
|
|
155
|
+
{getStatusIcon(project.pureStatus)} Pure build logs
|
|
152
156
|
</a>
|
|
153
157
|
</td>
|
|
154
158
|
</tr>
|
package/src/TestPage.tsx
CHANGED
|
@@ -144,7 +144,18 @@ export const TestPage = () => {
|
|
|
144
144
|
rightContent={
|
|
145
145
|
<Button
|
|
146
146
|
variant="info"
|
|
147
|
-
onClick={() =>
|
|
147
|
+
onClick={async () => {
|
|
148
|
+
try {
|
|
149
|
+
const promptPath = `testeranto/reports/${projectName}/${testPath.split('.').slice(0, -1).join('.')}/${runtime}/prompt.txt`;
|
|
150
|
+
const messagePath = `testeranto/reports/${projectName}/${testPath.split('.').slice(0, -1).join('.')}/${runtime}/message.txt`;
|
|
151
|
+
const command = `aider --load ${promptPath} --message-file ${messagePath}`;
|
|
152
|
+
await navigator.clipboard.writeText(command);
|
|
153
|
+
alert("Copied aider command to clipboard!");
|
|
154
|
+
} catch (err) {
|
|
155
|
+
alert("Failed to copy command to clipboard");
|
|
156
|
+
console.error("Copy failed:", err);
|
|
157
|
+
}
|
|
158
|
+
}}
|
|
148
159
|
className="ms-2"
|
|
149
160
|
>
|
|
150
161
|
🤖
|
|
@@ -15,16 +15,22 @@ export const implementation: ITestImplementation<I, O, {}> = {
|
|
|
15
15
|
|
|
16
16
|
givens: {
|
|
17
17
|
Default: () => {
|
|
18
|
-
|
|
19
|
-
{},
|
|
20
|
-
{},
|
|
21
|
-
{},
|
|
22
|
-
{},
|
|
23
|
-
{},
|
|
24
|
-
{},
|
|
25
|
-
|
|
26
|
-
() => []
|
|
18
|
+
const builder = new MockBaseBuilder(
|
|
19
|
+
{}, // input
|
|
20
|
+
{}, // suitesOverrides
|
|
21
|
+
{}, // givenOverrides
|
|
22
|
+
{}, // whenOverrides
|
|
23
|
+
{}, // thenOverrides
|
|
24
|
+
{ ports: [0] }, // testResourceRequirement
|
|
25
|
+
() => [] // testSpecification
|
|
27
26
|
);
|
|
27
|
+
|
|
28
|
+
// Initialize required arrays
|
|
29
|
+
builder.artifacts = [];
|
|
30
|
+
builder.testJobs = [];
|
|
31
|
+
builder.specs = [];
|
|
32
|
+
|
|
33
|
+
return builder;
|
|
28
34
|
},
|
|
29
35
|
WithCustomInput: (input: any) => {
|
|
30
36
|
return new MockBaseBuilder(
|
|
@@ -40,9 +40,12 @@ export class MockBaseBuilder<
|
|
|
40
40
|
givenOverrides: Record<keyof GivenExtensions, IGivenKlasser<I>> = {} as any,
|
|
41
41
|
whenOverrides: Record<keyof WhenExtensions, IWhenKlasser<I>> = {} as any,
|
|
42
42
|
thenOverrides: Record<keyof ThenExtensions, IThenKlasser<I>> = {} as any,
|
|
43
|
-
testResourceRequirement: ITTestResourceRequest = { ports: [] },
|
|
43
|
+
testResourceRequirement: ITTestResourceRequest = { ports: [0] },
|
|
44
44
|
testSpecification: ITestSpecification<I, O> = () => []
|
|
45
45
|
) {
|
|
46
|
+
// Initialize required arrays
|
|
47
|
+
this.artifacts = [];
|
|
48
|
+
this.testJobs = [];
|
|
46
49
|
super(
|
|
47
50
|
input,
|
|
48
51
|
suitesOverrides,
|
|
@@ -15,7 +15,12 @@ export const specification: ITestSpecification<I, O> = (
|
|
|
15
15
|
testInitialization: Given.Default(
|
|
16
16
|
["BaseBuilder should initialize correctly"],
|
|
17
17
|
[],
|
|
18
|
-
[
|
|
18
|
+
[
|
|
19
|
+
Then.initializedProperly(),
|
|
20
|
+
Then.artifactsTracked(),
|
|
21
|
+
Then.jobsCreated(),
|
|
22
|
+
Then.specsGenerated()
|
|
23
|
+
]
|
|
19
24
|
),
|
|
20
25
|
testSpecsGeneration: Given.Default(
|
|
21
26
|
["BaseBuilder should generate specs from test specification"],
|
|
@@ -4,6 +4,7 @@ import { PassThrough } from "stream";
|
|
|
4
4
|
|
|
5
5
|
import { ITestImplementation, ITestSpecification } from "../../CoreTypes";
|
|
6
6
|
import mock from "./mock";
|
|
7
|
+
import { TestClassBuilder } from "../classBuilder";
|
|
7
8
|
|
|
8
9
|
import { I, O, M } from "./classBuilder.test.types";
|
|
9
10
|
|
|
@@ -19,18 +20,19 @@ export const implementation: ITestImplementation<I, O, M> = {
|
|
|
19
20
|
|
|
20
21
|
givens: {
|
|
21
22
|
Default: () => {
|
|
22
|
-
|
|
23
|
+
console.log('Creating default test builder instance');
|
|
24
|
+
const builder = new mock(
|
|
23
25
|
implementation, // Use the current implementation
|
|
24
26
|
specification, // Use the current specification
|
|
25
27
|
{}, // Default input
|
|
26
28
|
MockSuite,
|
|
27
|
-
// class {}, // suiteKlasser
|
|
28
29
|
class {}, // givenKlasser
|
|
29
30
|
class {}, // whenKlasser
|
|
30
31
|
class {}, // thenKlasser
|
|
31
|
-
class {}, // checkKlasser
|
|
32
32
|
{ ports: [] } // Default resource requirements
|
|
33
33
|
);
|
|
34
|
+
console.log('Builder created:', builder);
|
|
35
|
+
return builder;
|
|
34
36
|
},
|
|
35
37
|
WithCustomInput: (input: any) => {
|
|
36
38
|
return new mock(
|
|
@@ -110,8 +112,9 @@ export const implementation: ITestImplementation<I, O, M> = {
|
|
|
110
112
|
|
|
111
113
|
thens: {
|
|
112
114
|
initializedProperly: () => (builder: any) => {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
+
console.log('Checking builder initialization:', builder);
|
|
116
|
+
if (!(builder instanceof mock)) {
|
|
117
|
+
throw new Error(`Builder was not properly initialized. Expected mock instance but got ${builder?.constructor?.name}`);
|
|
115
118
|
}
|
|
116
119
|
return builder;
|
|
117
120
|
},
|