cyclecad 3.2.0 → 3.4.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/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 Simulation 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">Simulation 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('stress')">Stress</button>
|
|
228
|
+
<button class="secondary" onclick="runCategory('thermal')">Thermal</button>
|
|
229
|
+
<button class="secondary" onclick="runCategory('other')">Other</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
|
+
stress: [
|
|
242
|
+
{ name: 'Create Study', fn: testCreateStudy },
|
|
243
|
+
{ name: 'Apply Load', fn: testApplyLoad },
|
|
244
|
+
{ name: 'Apply Constraint', fn: testApplyConstraint },
|
|
245
|
+
{ name: 'Mesh', fn: testMesh },
|
|
246
|
+
{ name: 'Solve', fn: testSolve },
|
|
247
|
+
{ name: 'Stress Results', fn: testStressResults },
|
|
248
|
+
{ name: 'Strain Results', fn: testStrainResults },
|
|
249
|
+
],
|
|
250
|
+
thermal: [
|
|
251
|
+
{ name: 'Thermal Study', fn: testThermalStudy },
|
|
252
|
+
{ name: 'Initial Temperature', fn: testInitialTemperature },
|
|
253
|
+
{ name: 'Thermal Load', fn: testThermalLoad },
|
|
254
|
+
{ name: 'Thermal Constraint', fn: testThermalConstraint },
|
|
255
|
+
{ name: 'Thermal Mesh', fn: testThermalMesh },
|
|
256
|
+
{ name: 'Thermal Results', fn: testThermalResults },
|
|
257
|
+
],
|
|
258
|
+
other: [
|
|
259
|
+
{ name: 'Modal Frequency', fn: testModalFrequency },
|
|
260
|
+
{ name: 'Buckling Analysis', fn: testBucklingAnalysis },
|
|
261
|
+
{ name: 'Shape Optimization', fn: testShapeOptimization },
|
|
262
|
+
{ name: 'Fatigue Analysis', fn: testFatigueAnalysis },
|
|
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', 'Simulation 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 testCreateStudy() {
|
|
351
|
+
return { skip: true };
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
async function testApplyLoad() {
|
|
355
|
+
return { skip: true };
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
async function testApplyConstraint() {
|
|
359
|
+
return { skip: true };
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
async function testMesh() {
|
|
363
|
+
return { skip: true };
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
async function testSolve() {
|
|
367
|
+
return { skip: true };
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
async function testStressResults() {
|
|
371
|
+
return { skip: true };
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
async function testStrainResults() {
|
|
375
|
+
return { skip: true };
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
async function testThermalStudy() {
|
|
379
|
+
return { skip: true };
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
async function testInitialTemperature() {
|
|
383
|
+
return { skip: true };
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
async function testThermalLoad() {
|
|
387
|
+
return { skip: true };
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
async function testThermalConstraint() {
|
|
391
|
+
return { skip: true };
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
async function testThermalMesh() {
|
|
395
|
+
return { skip: true };
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
async function testThermalResults() {
|
|
399
|
+
return { skip: true };
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
async function testModalFrequency() {
|
|
403
|
+
return { skip: true };
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
async function testBucklingAnalysis() {
|
|
407
|
+
return { skip: true };
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
async function testShapeOptimization() {
|
|
411
|
+
return { skip: true };
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
async function testFatigueAnalysis() {
|
|
415
|
+
return { skip: true };
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
window.addEventListener('DOMContentLoaded', init);
|
|
419
|
+
</script>
|
|
420
|
+
</body>
|
|
421
|
+
</html>
|