cyclecad 3.2.1 → 3.5.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/CLAUDE.md +155 -1
- package/DOCKER-SETUP-VERIFICATION.md +399 -0
- package/DOCKER-TESTING.md +463 -0
- package/FUSION360_MODULES.md +478 -0
- package/FUSION_MODULES_README.md +352 -0
- package/INTEGRATION_SNIPPETS.md +608 -0
- package/KILLER-FEATURES-DELIVERY.md +469 -0
- package/MODULES_SUMMARY.txt +337 -0
- package/QUICK_REFERENCE.txt +298 -0
- package/README-DOCKER-TESTING.txt +438 -0
- package/app/index.html +23 -10
- package/app/js/fusion-help.json +1808 -0
- package/app/js/help-module-v3.js +1096 -0
- package/app/js/killer-features-help.json +395 -0
- package/app/js/killer-features.js +1508 -0
- package/app/js/modules/fusion-assembly.js +842 -0
- package/app/js/modules/fusion-cam.js +785 -0
- package/app/js/modules/fusion-data.js +814 -0
- package/app/js/modules/fusion-drawing.js +844 -0
- package/app/js/modules/fusion-inspection.js +756 -0
- package/app/js/modules/fusion-render.js +774 -0
- package/app/js/modules/fusion-simulation.js +986 -0
- package/app/js/modules/fusion-sketch.js +1044 -0
- package/app/js/modules/fusion-solid.js +1095 -0
- package/app/js/modules/fusion-surface.js +949 -0
- package/app/tests/FUSION_TEST_SUITE.md +266 -0
- package/app/tests/README.md +77 -0
- package/app/tests/TESTING-CHECKLIST.md +177 -0
- package/app/tests/TEST_SUITE_SUMMARY.txt +236 -0
- package/app/tests/brep-live-test.html +848 -0
- package/app/tests/docker-integration-test.html +811 -0
- package/app/tests/fusion-all-tests.html +670 -0
- package/app/tests/fusion-assembly-tests.html +461 -0
- package/app/tests/fusion-cam-tests.html +421 -0
- package/app/tests/fusion-simulation-tests.html +421 -0
- package/app/tests/fusion-sketch-tests.html +613 -0
- package/app/tests/fusion-solid-tests.html +529 -0
- package/app/tests/index.html +453 -0
- package/app/tests/killer-features-test.html +509 -0
- package/app/tests/run-tests.html +874 -0
- package/app/tests/step-import-live-test.html +1115 -0
- package/app/tests/test-agent-v3.html +93 -696
- package/architecture-dashboard.html +1970 -0
- package/docs/API-REFERENCE.md +1423 -0
- package/docs/BREP-LIVE-TEST-GUIDE.md +453 -0
- package/docs/DEVELOPER-GUIDE-v3.md +795 -0
- package/docs/DOCKER-QUICK-TEST.md +376 -0
- package/docs/FUSION-FEATURES-GUIDE.md +2513 -0
- package/docs/FUSION-TUTORIAL.md +1203 -0
- package/docs/INFRASTRUCTURE-GUIDE-INDEX.md +327 -0
- package/docs/KEYBOARD-SHORTCUTS.md +402 -0
- package/docs/KILLER-FEATURES-INTEGRATION.md +412 -0
- package/docs/KILLER-FEATURES-SUMMARY.md +424 -0
- package/docs/KILLER-FEATURES-TUTORIAL.md +784 -0
- package/docs/KILLER-FEATURES.md +562 -0
- package/docs/QUICK-REFERENCE.md +282 -0
- package/docs/README-v3-DOCS.md +274 -0
- package/docs/TUTORIAL-v3.md +1190 -0
- package/docs/architecture-dashboard.html +1970 -0
- package/docs/architecture-v3.html +1038 -0
- package/linkedin-post-v3.md +58 -0
- package/package.json +1 -1
- package/scripts/dev-setup.sh +338 -0
- package/scripts/docker-health-check.sh +159 -0
- package/scripts/integration-test.sh +311 -0
- package/scripts/test-docker.sh +515 -0
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>cycleCAD CAM Tests</title>
|
|
7
|
+
<style>
|
|
8
|
+
* {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
body {
|
|
15
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
|
|
16
|
+
background: #0f172a;
|
|
17
|
+
color: #e2e8f0;
|
|
18
|
+
display: flex;
|
|
19
|
+
height: 100vh;
|
|
20
|
+
gap: 1px;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.app-container {
|
|
24
|
+
flex: 0 0 70%;
|
|
25
|
+
background: #1a202c;
|
|
26
|
+
border: 1px solid #2d3748;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
iframe {
|
|
30
|
+
width: 100%;
|
|
31
|
+
height: 100%;
|
|
32
|
+
border: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.test-panel {
|
|
36
|
+
flex: 0 0 30%;
|
|
37
|
+
display: flex;
|
|
38
|
+
flex-direction: column;
|
|
39
|
+
background: #1a202c;
|
|
40
|
+
border-left: 1px solid #2d3748;
|
|
41
|
+
overflow: hidden;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.test-header {
|
|
45
|
+
padding: 16px;
|
|
46
|
+
border-bottom: 1px solid #2d3748;
|
|
47
|
+
background: #0f172a;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.test-title {
|
|
51
|
+
font-size: 18px;
|
|
52
|
+
font-weight: 600;
|
|
53
|
+
margin-bottom: 12px;
|
|
54
|
+
color: #38bdf8;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.test-stats {
|
|
58
|
+
display: grid;
|
|
59
|
+
grid-template-columns: 1fr 1fr 1fr;
|
|
60
|
+
gap: 8px;
|
|
61
|
+
font-size: 12px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.stat-box {
|
|
65
|
+
padding: 8px;
|
|
66
|
+
background: #1e293b;
|
|
67
|
+
border-radius: 4px;
|
|
68
|
+
border-left: 2px solid #64748b;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.stat-box.pass {
|
|
72
|
+
border-left-color: #10b981;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.stat-box.fail {
|
|
76
|
+
border-left-color: #ef4444;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.stat-box.skip {
|
|
80
|
+
border-left-color: #f59e0b;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.stat-label {
|
|
84
|
+
font-size: 11px;
|
|
85
|
+
color: #94a3b8;
|
|
86
|
+
margin-bottom: 2px;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.stat-value {
|
|
90
|
+
font-size: 18px;
|
|
91
|
+
font-weight: 600;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.test-controls {
|
|
95
|
+
display: flex;
|
|
96
|
+
gap: 8px;
|
|
97
|
+
padding: 12px;
|
|
98
|
+
border-bottom: 1px solid #2d3748;
|
|
99
|
+
flex-wrap: wrap;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
button {
|
|
103
|
+
padding: 8px 12px;
|
|
104
|
+
background: #0ea5e9;
|
|
105
|
+
color: white;
|
|
106
|
+
border: none;
|
|
107
|
+
border-radius: 4px;
|
|
108
|
+
cursor: pointer;
|
|
109
|
+
font-size: 12px;
|
|
110
|
+
font-weight: 500;
|
|
111
|
+
transition: background 0.2s;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
button:hover {
|
|
115
|
+
background: #0284c7;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
button.secondary {
|
|
119
|
+
background: #475569;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
button.secondary:hover {
|
|
123
|
+
background: #64748b;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.test-log {
|
|
127
|
+
flex: 1;
|
|
128
|
+
overflow-y: auto;
|
|
129
|
+
padding: 12px;
|
|
130
|
+
font-size: 12px;
|
|
131
|
+
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.test-log-entry {
|
|
135
|
+
margin-bottom: 8px;
|
|
136
|
+
padding: 8px;
|
|
137
|
+
background: #0f172a;
|
|
138
|
+
border-left: 3px solid #64748b;
|
|
139
|
+
border-radius: 2px;
|
|
140
|
+
line-height: 1.5;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.test-log-entry.pass {
|
|
144
|
+
border-left-color: #10b981;
|
|
145
|
+
background: rgba(16, 185, 129, 0.05);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.test-log-entry.fail {
|
|
149
|
+
border-left-color: #ef4444;
|
|
150
|
+
background: rgba(239, 68, 68, 0.05);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.test-log-entry.skip {
|
|
154
|
+
border-left-color: #f59e0b;
|
|
155
|
+
background: rgba(245, 158, 11, 0.05);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.test-log-entry.info {
|
|
159
|
+
border-left-color: #3b82f6;
|
|
160
|
+
background: rgba(59, 130, 246, 0.05);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.log-label {
|
|
164
|
+
font-weight: 600;
|
|
165
|
+
color: #38bdf8;
|
|
166
|
+
margin-right: 8px;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.log-message {
|
|
170
|
+
color: #cbd5e1;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.test-footer {
|
|
174
|
+
padding: 12px;
|
|
175
|
+
border-top: 1px solid #2d3748;
|
|
176
|
+
background: #0f172a;
|
|
177
|
+
font-size: 12px;
|
|
178
|
+
color: #94a3b8;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.progress-bar {
|
|
182
|
+
width: 100%;
|
|
183
|
+
height: 4px;
|
|
184
|
+
background: #1e293b;
|
|
185
|
+
border-radius: 2px;
|
|
186
|
+
overflow: hidden;
|
|
187
|
+
margin-top: 8px;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.progress-fill {
|
|
191
|
+
height: 100%;
|
|
192
|
+
background: linear-gradient(90deg, #10b981, #38bdf8, #f59e0b);
|
|
193
|
+
width: 0%;
|
|
194
|
+
transition: width 0.3s;
|
|
195
|
+
}
|
|
196
|
+
</style>
|
|
197
|
+
</head>
|
|
198
|
+
<body>
|
|
199
|
+
<div class="app-container">
|
|
200
|
+
<iframe id="appFrame" src="../index.html"></iframe>
|
|
201
|
+
</div>
|
|
202
|
+
|
|
203
|
+
<div class="test-panel">
|
|
204
|
+
<div class="test-header">
|
|
205
|
+
<div class="test-title">CAM Tests</div>
|
|
206
|
+
<div class="test-stats">
|
|
207
|
+
<div class="stat-box pass">
|
|
208
|
+
<div class="stat-label">PASS</div>
|
|
209
|
+
<div class="stat-value" id="passCount">0</div>
|
|
210
|
+
</div>
|
|
211
|
+
<div class="stat-box fail">
|
|
212
|
+
<div class="stat-label">FAIL</div>
|
|
213
|
+
<div class="stat-value" id="failCount">0</div>
|
|
214
|
+
</div>
|
|
215
|
+
<div class="stat-box skip">
|
|
216
|
+
<div class="stat-label">SKIP</div>
|
|
217
|
+
<div class="stat-value" id="skipCount">0</div>
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
<div class="progress-bar">
|
|
221
|
+
<div class="progress-fill" id="progressFill"></div>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
|
|
225
|
+
<div class="test-controls">
|
|
226
|
+
<button onclick="runAllTests()">Run All Tests</button>
|
|
227
|
+
<button class="secondary" onclick="runCategory('setup')">Setup</button>
|
|
228
|
+
<button class="secondary" onclick="runCategory('operations')">Operations</button>
|
|
229
|
+
<button class="secondary" onclick="runCategory('toolpath')">Toolpath</button>
|
|
230
|
+
</div>
|
|
231
|
+
|
|
232
|
+
<div class="test-log" id="testLog"></div>
|
|
233
|
+
|
|
234
|
+
<div class="test-footer">
|
|
235
|
+
<div id="testStatus">Ready to test</div>
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
|
|
239
|
+
<script>
|
|
240
|
+
const tests = {
|
|
241
|
+
setup: [
|
|
242
|
+
{ name: 'Create Setup', fn: testCreateSetup },
|
|
243
|
+
{ name: 'Stock Setup', fn: testStockSetup },
|
|
244
|
+
{ name: 'Coordinate System', fn: testCoordinateSystem },
|
|
245
|
+
{ name: 'Post Configuration', fn: testPostConfiguration },
|
|
246
|
+
],
|
|
247
|
+
operations: [
|
|
248
|
+
{ name: 'Facing Operation', fn: testFacingOperation },
|
|
249
|
+
{ name: 'Pocket Operation', fn: testPocketOperation },
|
|
250
|
+
{ name: 'Contour Operation', fn: testContourOperation },
|
|
251
|
+
{ name: 'Drilling Operation', fn: testDrillingOperation },
|
|
252
|
+
{ name: '2D Adaptive', fn: test2DAdaptive },
|
|
253
|
+
{ name: '3D Adaptive', fn: test3DAdaptive },
|
|
254
|
+
{ name: 'Turning Operation', fn: testTurningOperation },
|
|
255
|
+
],
|
|
256
|
+
toolpath: [
|
|
257
|
+
{ name: 'Tool Library', fn: testToolLibrary },
|
|
258
|
+
{ name: 'Tool Selection', fn: testToolSelection },
|
|
259
|
+
{ name: 'Feed & Speed Calc', fn: testFeedSpeedCalc },
|
|
260
|
+
{ name: 'Toolpath Simulation', fn: testToolpathSimulation },
|
|
261
|
+
{ name: 'G-code Generation', fn: testGCodeGeneration },
|
|
262
|
+
{ name: 'Setup Sheet', fn: testSetupSheet },
|
|
263
|
+
],
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
let stats = { pass: 0, fail: 0, skip: 0, total: 0 };
|
|
267
|
+
let appFrame;
|
|
268
|
+
let appWindow;
|
|
269
|
+
|
|
270
|
+
async function init() {
|
|
271
|
+
appFrame = document.getElementById('appFrame');
|
|
272
|
+
await new Promise(resolve => {
|
|
273
|
+
appFrame.onload = resolve;
|
|
274
|
+
});
|
|
275
|
+
appWindow = appFrame.contentWindow;
|
|
276
|
+
addLog('info', 'App loaded', 'CAM tests ready');
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
async function runAllTests() {
|
|
280
|
+
resetStats();
|
|
281
|
+
for (const category in tests) {
|
|
282
|
+
await runCategory(category);
|
|
283
|
+
}
|
|
284
|
+
addLog('info', 'Completed', `${stats.pass} passed, ${stats.fail} failed, ${stats.skip} skipped`);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
async function runCategory(categoryName) {
|
|
288
|
+
resetStats();
|
|
289
|
+
const categoryTests = tests[categoryName] || [];
|
|
290
|
+
|
|
291
|
+
for (const test of categoryTests) {
|
|
292
|
+
try {
|
|
293
|
+
const result = await test.fn();
|
|
294
|
+
recordResult(test.name, result);
|
|
295
|
+
await delay(300);
|
|
296
|
+
} catch (error) {
|
|
297
|
+
recordResult(test.name, { pass: false, error: error.message });
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
updateProgress();
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function recordResult(testName, result) {
|
|
305
|
+
stats.total++;
|
|
306
|
+
if (result.skip) {
|
|
307
|
+
stats.skip++;
|
|
308
|
+
addLog('skip', testName, 'Skipped');
|
|
309
|
+
} else if (result.pass) {
|
|
310
|
+
stats.pass++;
|
|
311
|
+
addLog('pass', testName, 'Passed');
|
|
312
|
+
} else {
|
|
313
|
+
stats.fail++;
|
|
314
|
+
addLog('fail', testName, result.error || 'Failed');
|
|
315
|
+
}
|
|
316
|
+
updateStats();
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
function updateStats() {
|
|
320
|
+
document.getElementById('passCount').textContent = stats.pass;
|
|
321
|
+
document.getElementById('failCount').textContent = stats.fail;
|
|
322
|
+
document.getElementById('skipCount').textContent = stats.skip;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function updateProgress() {
|
|
326
|
+
const percent = stats.total > 0 ? (stats.pass / stats.total) * 100 : 0;
|
|
327
|
+
document.getElementById('progressFill').style.width = percent + '%';
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function resetStats() {
|
|
331
|
+
stats = { pass: 0, fail: 0, skip: 0, total: 0 };
|
|
332
|
+
document.getElementById('testLog').innerHTML = '';
|
|
333
|
+
updateStats();
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function addLog(level, label, message) {
|
|
337
|
+
const log = document.getElementById('testLog');
|
|
338
|
+
const entry = document.createElement('div');
|
|
339
|
+
entry.className = `test-log-entry ${level}`;
|
|
340
|
+
entry.innerHTML = `<span class="log-label">${label}</span><span class="log-message">${message}</span>`;
|
|
341
|
+
log.appendChild(entry);
|
|
342
|
+
log.scrollTop = log.scrollHeight;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function delay(ms) {
|
|
346
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Test implementations
|
|
350
|
+
async function testCreateSetup() {
|
|
351
|
+
return { skip: true };
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
async function testStockSetup() {
|
|
355
|
+
return { skip: true };
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
async function testCoordinateSystem() {
|
|
359
|
+
return { skip: true };
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
async function testPostConfiguration() {
|
|
363
|
+
return { skip: true };
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
async function testFacingOperation() {
|
|
367
|
+
return { skip: true };
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
async function testPocketOperation() {
|
|
371
|
+
return { skip: true };
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
async function testContourOperation() {
|
|
375
|
+
return { skip: true };
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
async function testDrillingOperation() {
|
|
379
|
+
return { skip: true };
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
async function test2DAdaptive() {
|
|
383
|
+
return { skip: true };
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
async function test3DAdaptive() {
|
|
387
|
+
return { skip: true };
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
async function testTurningOperation() {
|
|
391
|
+
return { skip: true };
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
async function testToolLibrary() {
|
|
395
|
+
return { skip: true };
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
async function testToolSelection() {
|
|
399
|
+
return { skip: true };
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
async function testFeedSpeedCalc() {
|
|
403
|
+
return { skip: true };
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
async function testToolpathSimulation() {
|
|
407
|
+
return { skip: true };
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
async function testGCodeGeneration() {
|
|
411
|
+
return { skip: true };
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
async function testSetupSheet() {
|
|
415
|
+
return { skip: true };
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
window.addEventListener('DOMContentLoaded', init);
|
|
419
|
+
</script>
|
|
420
|
+
</body>
|
|
421
|
+
</html>
|