Skip to main content

max / makenotwork

30.7 KB · 841 lines History Blame Raw
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>audiofiles/ — Alpha Testing Guide</title>
7 <style>
8 @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600&family=Inter:wght@300;400;600;700&family=Recursive:wght@700&display=swap');
9
10 :root {
11 --bg: #ffffff;
12 --bg-cool: #f5f5f5;
13 --bg-deep: #000000;
14 --text: #000000;
15 --text-secondary: #333333;
16 --text-muted: #666666;
17 --accent: #000000;
18 --border: #d0d0d0;
19 --success: #30d158;
20 --on-deep: #ffffff;
21 --red: #ff3b30;
22 --amber: #ff9f0a;
23 }
24
25 * { margin: 0; padding: 0; box-sizing: border-box; }
26
27 @page { size: letter; margin: 0; }
28
29 body {
30 font-family: 'Inter', sans-serif;
31 color: var(--text);
32 background: var(--bg);
33 line-height: 1.6;
34 -webkit-print-color-adjust: exact;
35 print-color-adjust: exact;
36 }
37
38 .page {
39 width: 8.5in;
40 min-height: 11in;
41 margin: 0 auto;
42 padding: 0.6in 0.75in;
43 background: var(--bg);
44 page-break-after: always;
45 position: relative;
46 }
47
48 .page:last-child { page-break-after: auto; }
49
50 .hero {
51 text-align: center;
52 padding: 0.25in 0 0.25in;
53 border-bottom: 2px solid var(--text);
54 margin-bottom: 0.22in;
55 }
56
57 .hero h1 {
58 font-family: 'Recursive', monospace;
59 font-size: 40px;
60 font-weight: 700;
61 font-variation-settings: 'MONO' 1, 'CASL' 0;
62 color: var(--text);
63 margin-bottom: 4px;
64 letter-spacing: -0.5px;
65 }
66
67 .hero .tagline {
68 font-family: 'IBM Plex Mono', monospace;
69 font-size: 14px;
70 color: var(--text-secondary);
71 letter-spacing: 0.3px;
72 }
73
74 .hero .sub {
75 font-size: 12.5px;
76 color: var(--text-muted);
77 margin-top: 6px;
78 }
79
80 h2 {
81 font-family: 'IBM Plex Mono', monospace;
82 font-size: 13px;
83 font-weight: 600;
84 text-transform: uppercase;
85 letter-spacing: 1.5px;
86 color: var(--text);
87 margin-bottom: 10px;
88 padding-bottom: 5px;
89 border-bottom: 1px solid var(--border);
90 }
91
92 h3 {
93 font-family: 'IBM Plex Mono', monospace;
94 font-size: 12px;
95 font-weight: 600;
96 color: var(--text);
97 margin-bottom: 4px;
98 margin-top: 12px;
99 }
100
101 h3:first-child { margin-top: 0; }
102
103 .intro {
104 font-size: 13.5px;
105 line-height: 1.65;
106 margin-bottom: 0.2in;
107 }
108
109 .highlight-box {
110 background: var(--bg-cool);
111 border-left: 3px solid var(--text);
112 padding: 10px 14px;
113 margin-bottom: 0.18in;
114 border-radius: 0 6px 6px 0;
115 }
116
117 .highlight-box p {
118 font-size: 12px;
119 line-height: 1.55;
120 color: var(--text-secondary);
121 }
122
123 .highlight-box strong { color: var(--text); }
124
125 .highlight-box.amber { border-left-color: var(--amber); }
126 .highlight-box.red { border-left-color: var(--red); }
127 .highlight-box.green { border-left-color: var(--success); }
128
129 /* Test checklist */
130
131 .test-group { margin-bottom: 0.18in; }
132
133 .test-group h3 {
134 font-size: 11.5px;
135 margin-top: 10px;
136 margin-bottom: 6px;
137 }
138
139 .checklist {
140 list-style: none;
141 padding: 0;
142 columns: 1;
143 }
144
145 .checklist.two-col { columns: 2; column-gap: 18px; }
146
147 .checklist li {
148 font-size: 11px;
149 line-height: 1.4;
150 color: var(--text-secondary);
151 padding: 2.5px 0 2.5px 20px;
152 position: relative;
153 break-inside: avoid;
154 }
155
156 .checklist li::before {
157 content: '';
158 position: absolute;
159 left: 0;
160 top: 5px;
161 width: 12px;
162 height: 12px;
163 border: 1.5px solid var(--border);
164 border-radius: 2px;
165 background: var(--bg);
166 }
167
168 .checklist li strong { color: var(--text); }
169
170 /* Feature summary grid */
171
172 .feature-grid {
173 display: grid;
174 grid-template-columns: 1fr 1fr;
175 gap: 10px;
176 margin-bottom: 0.18in;
177 }
178
179 .feature-card {
180 background: var(--bg-cool);
181 border: 1px solid var(--border);
182 border-radius: 6px;
183 padding: 10px 12px;
184 }
185
186 .feature-card h3 {
187 margin: 0 0 4px 0;
188 font-size: 11.5px;
189 color: var(--text);
190 }
191
192 .feature-card p {
193 font-size: 10.5px;
194 line-height: 1.4;
195 color: var(--text-secondary);
196 margin: 0;
197 }
198
199 /* Keyboard shortcuts table */
200
201 .shortcuts {
202 display: grid;
203 grid-template-columns: repeat(3, 1fr);
204 gap: 3px 14px;
205 margin-bottom: 0.15in;
206 }
207
208 .shortcut {
209 display: flex;
210 align-items: center;
211 gap: 6px;
212 font-size: 10.5px;
213 color: var(--text-secondary);
214 padding: 1.5px 0;
215 }
216
217 .shortcut kbd {
218 font-family: 'IBM Plex Mono', monospace;
219 font-size: 9.5px;
220 background: var(--bg-deep);
221 border: 1px solid var(--bg-deep);
222 border-radius: 3px;
223 padding: 1px 5px;
224 color: var(--on-deep);
225 min-width: 22px;
226 text-align: center;
227 }
228
229 /* Priority badges */
230
231 .badge {
232 display: inline-block;
233 font-family: 'IBM Plex Mono', monospace;
234 font-size: 8.5px;
235 font-weight: 600;
236 text-transform: uppercase;
237 letter-spacing: 0.5px;
238 padding: 1px 6px;
239 border-radius: 3px;
240 vertical-align: middle;
241 margin-right: 4px;
242 }
243
244 .badge.critical { background: var(--red); color: white; }
245 .badge.important { background: var(--amber); color: white; }
246 .badge.normal { background: var(--bg-deep); color: var(--on-deep); }
247
248 /* Footer */
249
250 .footer {
251 position: absolute;
252 bottom: 0.4in;
253 left: 0.75in;
254 right: 0.75in;
255 display: flex;
256 justify-content: space-between;
257 align-items: center;
258 padding-top: 8px;
259 border-top: 1px solid var(--border);
260 }
261
262 .footer .left, .footer .right {
263 font-family: 'IBM Plex Mono', monospace;
264 font-size: 10px;
265 color: var(--text-muted);
266 }
267
268 .footer-inline {
269 display: flex;
270 justify-content: space-between;
271 align-items: center;
272 padding-top: 8px;
273 border-top: 1px solid var(--border);
274 margin-top: auto;
275 }
276
277 .footer-inline .left, .footer-inline .right {
278 font-family: 'IBM Plex Mono', monospace;
279 font-size: 10px;
280 color: var(--text-muted);
281 }
282
283 @media print { body { background: white; } .page { box-shadow: none; } }
284 @media screen { body { background: #ccc; padding: 20px 0; } .page { box-shadow: 0 2px 20px rgba(0,0,0,0.15); margin-bottom: 20px; } }
285 </style>
286 </head>
287 <body>
288
289 <!-- PAGE 1: Overview + First Launch -->
290 <div class="page">
291
292 <div class="hero">
293 <h1>audiofiles/ testing</h1>
294 <div class="tagline">Alpha testing guide &mdash; features, workflows, and edge cases.</div>
295 <div class="sub">Version 0.3.0. Standalone desktop app. 560 automated tests. This document covers the human side.</div>
296 </div>
297
298 <div class="intro">
299 This guide covers every user-facing feature in audiofiles, organized into testable workflows. Each section has a checklist of things to verify. The goal of alpha testing is to find bugs, rough edges, and missing affordances before the app reaches real users. Test on macOS first (primary platform), then Linux where possible.
300 </div>
301
302 <div class="highlight-box">
303 <p><strong>How to use this document.</strong> Work through each section in order. Check off items as you go. The first three sections (First Launch, Import, Analysis) form the critical path &mdash; every user will hit these. Later sections cover power-user features. Report bugs with steps to reproduce, the theme you were using, and the exact error message if one appeared.</p>
304 </div>
305
306 <h2>Feature Map</h2>
307
308 <div class="feature-grid">
309 <div class="feature-card">
310 <h3>Storage &amp; Import</h3>
311 <p>Content-addressed store (SHA-256). Import WAV, FLAC, MP3, OGG, AIFF. Three strategies: new VFS, merge, flat. Drag-and-drop or CLI. Folder tagging on import.</p>
312 </div>
313 <div class="feature-card">
314 <h3>Virtual File System</h3>
315 <p>Multiple independent VFS roots. Directories, sample links, breadcrumb nav. Rename, move, delete with cascade. Same sample in unlimited hierarchies.</p>
316 </div>
317 <div class="feature-card">
318 <h3>Analysis Pipeline</h3>
319 <p>Loudness (peak/RMS/LUFS), BPM, key, spectral, loop detection, classification (12 categories), waveform, fingerprint. Each stage individually toggleable.</p>
320 </div>
321 <div class="feature-card">
322 <h3>Search &amp; Filter</h3>
323 <p>Text search, BPM range, duration range, key (exact + compatible), classification multi-select, tag prefix. Smart folders save filter presets.</p>
324 </div>
325 <div class="feature-card">
326 <h3>Tags &amp; Suggestions</h3>
327 <p>Hierarchical dot-notation. Auto-suggestions from analysis. Accept/reject per suggestion. Bulk add/remove. Tag on import by folder name.</p>
328 </div>
329 <div class="feature-card">
330 <h3>Export &amp; Devices</h3>
331 <p>14 hardware sampler profiles. Sample rate conversion, bit depth dithering, filename sanitization. Rhai-scripted profiles. Background worker.</p>
332 </div>
333 <div class="feature-card">
334 <h3>Preview &amp; Instrument</h3>
335 <p>Inline audio preview with waveform. Streaming decode for long files. Chromatic + multi-sample MIDI instrument. 8-voice polyphony, ADSR envelopes.</p>
336 </div>
337 <div class="feature-card">
338 <h3>Sync &amp; Themes</h3>
339 <p>Cloud sync via SyncKit (E2E encrypted). 17 bundled themes. Native drag-out to Finder/DAWs. Collections. Similarity + duplicate search.</p>
340 </div>
341 </div>
342
343 <h2>Keyboard Reference</h2>
344
345 <div class="shortcuts">
346 <div class="shortcut"><kbd>j</kbd> / <kbd>&darr;</kbd> Move down</div>
347 <div class="shortcut"><kbd>k</kbd> / <kbd>&uarr;</kbd> Move up</div>
348 <div class="shortcut"><kbd>Enter</kbd> Open / play</div>
349 <div class="shortcut"><kbd>Backspace</kbd> Go up</div>
350 <div class="shortcut"><kbd>Space</kbd> Play / pause</div>
351 <div class="shortcut"><kbd>Delete</kbd> Delete selected</div>
352 <div class="shortcut"><kbd>/</kbd> Focus search</div>
353 <div class="shortcut"><kbd>Cmd+A</kbd> Select all</div>
354 <div class="shortcut"><kbd>Cmd+Z</kbd> Undo</div>
355 <div class="shortcut"><kbd>Cmd+T</kbd> Bulk tag</div>
356 <div class="shortcut"><kbd>F2</kbd> Bulk rename</div>
357 <div class="shortcut"><kbd>F1</kbd> Help overlay</div>
358 <div class="shortcut"><kbd>I</kbd> Instrument panel</div>
359 <div class="shortcut"><kbd>S</kbd> Toggle sidebar</div>
360 <div class="shortcut"><kbd>D</kbd> Toggle detail</div>
361 <div class="shortcut"><kbd>Esc</kbd> Dismiss / clear</div>
362 <div class="shortcut"><kbd>Shift+Click</kbd> Range select</div>
363 <div class="shortcut"><kbd>Cmd+Click</kbd> Toggle select</div>
364 </div>
365
366 <h2>1. First Launch</h2>
367
368 <div class="test-group">
369 <ul class="checklist">
370 <li><span class="badge critical">Critical</span> App opens without errors. Window appears, default "Library" VFS is created.</li>
371 <li><span class="badge critical">Critical</span> Empty state is clear: no samples, no errors, status bar is empty.</li>
372 <li>Sidebar shows "Library" VFS. Detail panel and sidebar are both visible by default.</li>
373 <li>Theme is "audiofiles" (default). All UI elements are legible and properly colored.</li>
374 <li>F1 opens the help overlay with keyboard shortcuts. F1 again or Escape closes it.</li>
375 <li>Window is resizable. Detail panel auto-hides below 700px width.</li>
376 <li>Toggle sidebar (S key), detail panel (D key). Both remember state across navigation.</li>
377 </ul>
378 </div>
379
380 <div class="footer">
381 <div class="left">af/ testing guide &mdash; v0.3.0 alpha</div>
382 <div class="right">page 1 of 5</div>
383 </div>
384
385 </div>
386
387 <!-- PAGE 2: Import + Analysis -->
388 <div class="page">
389
390 <h2>2. Import Workflow</h2>
391
392 <div class="highlight-box amber">
393 <p><strong>Test with varied content.</strong> Use a folder containing WAV, FLAC, MP3, OGG, and AIFF files. Include subfolders, files with spaces and special characters in names, at least one corrupt or empty file, and at least one very large file (&gt;100MB). The more diverse the test material, the better.</p>
394 </div>
395
396 <div class="test-group">
397 <h3>Import Configuration</h3>
398 <ul class="checklist">
399 <li><span class="badge critical">Critical</span> Drop a folder onto the app window. Configure Import screen appears.</li>
400 <li>Three import strategies available: New VFS (default), Merge Into, Flat.</li>
401 <li>New VFS name defaults to the folder name. Editable.</li>
402 <li>Merge Into shows a dropdown of existing VFS roots.</li>
403 <li>Cancel returns to normal browsing without changes.</li>
404 </ul>
405 </div>
406
407 <div class="test-group">
408 <h3>Import Progress</h3>
409 <ul class="checklist">
410 <li><span class="badge critical">Critical</span> Progress bar advances. "Scanning for audio files..." spinner during walk phase.</li>
411 <li>Current filename updates as files are processed.</li>
412 <li>Error count appears in red if files fail (click to expand details).</li>
413 <li>Cancel stops import mid-way. Partially imported files remain valid.</li>
414 <li>Retry button re-opens configure screen with previous source path.</li>
415 </ul>
416 </div>
417
418 <div class="test-group">
419 <h3>Folder Tagging</h3>
420 <ul class="checklist">
421 <li>After import, Tag Folders screen shows top-level subfolders.</li>
422 <li>Each folder has an editable tag input. Comma-separated tags work.</li>
423 <li>"Apply Tags" adds tags to all samples in that folder, then proceeds to analysis.</li>
424 <li>"Skip" proceeds to analysis without tagging.</li>
425 </ul>
426 </div>
427
428 <div class="test-group">
429 <h3>Post-Import Error Summary</h3>
430 <ul class="checklist">
431 <li><span class="badge important">Important</span> If any files failed import or analysis, the Review Errors screen appears.</li>
432 <li>Analysis errors show sample name, error message, and per-row "Remove" button.</li>
433 <li>Import errors show file path and error message (informational, no actions).</li>
434 <li>"Keep All" dismisses errors and returns to browsing.</li>
435 <li>"Remove All Failed" deletes failed samples from the store and returns to browsing.</li>
436 <li>Individual "Remove" buttons delete one failed sample at a time.</li>
437 </ul>
438 </div>
439
440 <div class="test-group">
441 <h3>Edge Cases</h3>
442 <ul class="checklist">
443 <li>Import the same folder twice: duplicates are skipped, count shown in status.</li>
444 <li>Import an empty folder: no samples imported, status reflects this.</li>
445 <li>Import a single file via drag-and-drop: immediate import + analysis, no configure screen.</li>
446 <li>CLI import: <code>audiofiles-app /path/to/folder</code> opens app and starts import.</li>
447 <li>Files with no extension or wrong extension: handled gracefully (error or skip).</li>
448 </ul>
449 </div>
450
451 <h2>3. Analysis</h2>
452
453 <div class="test-group">
454 <h3>Configuration</h3>
455 <ul class="checklist">
456 <li>Analysis config screen shows toggle checkboxes for each stage.</li>
457 <li>All stages enabled by default. Each can be individually disabled.</li>
458 <li>"Analyze" starts the background worker. "Cancel" returns to browsing.</li>
459 </ul>
460 </div>
461
462 <div class="test-group">
463 <h3>Progress &amp; Results</h3>
464 <ul class="checklist">
465 <li><span class="badge critical">Critical</span> Progress bar advances. Current sample name shown.</li>
466 <li>Errors accumulated during analysis show in expandable error list.</li>
467 <li>Cancel stops analysis. Already-analyzed samples keep their results.</li>
468 <li>After analysis, Review Suggestions screen shows auto-generated tags.</li>
469 </ul>
470 </div>
471
472 <div class="test-group">
473 <h3>Tag Suggestions</h3>
474 <ul class="checklist">
475 <li><span class="badge important">Important</span> Each sample shows proposed tags (BPM, key, classification).</li>
476 <li>Tags are pre-accepted. Click to reject individual suggestions.</li>
477 <li>"Apply" commits accepted tags. "Skip" discards all suggestions.</li>
478 <li>Navigate between samples using the review UI.</li>
479 </ul>
480 </div>
481
482 <div class="test-group">
483 <h3>Detail Panel After Analysis</h3>
484 <ul class="checklist">
485 <li>Select an analyzed sample. Detail panel shows: duration, BPM, key, classification badge.</li>
486 <li>Waveform renders correctly (stereo peaks, theme-colored).</li>
487 <li>Sample rate, channels, peak dB, RMS dB, LUFS all populated.</li>
488 <li>Loop detection shows Yes/No.</li>
489 </ul>
490 </div>
491
492 <div class="footer">
493 <div class="left">af/ testing guide &mdash; v0.3.0 alpha</div>
494 <div class="right">page 2 of 5</div>
495 </div>
496
497 </div>
498
499 <!-- PAGE 3: Navigation, Search, Bulk Ops -->
500 <div class="page">
501
502 <h2>4. File List &amp; Navigation</h2>
503
504 <div class="test-group">
505 <ul class="checklist">
506 <li><span class="badge critical">Critical</span> Directories sort before samples. Names sort case-insensitively.</li>
507 <li>Click column headers to sort by Name, BPM, Key, Duration, Classification.</li>
508 <li>Click same header again to reverse direction. Third click resets to Name ascending.</li>
509 <li>Enter a directory (Enter or double-click). Breadcrumb updates. ".." entry at top.</li>
510 <li>Go up via Backspace, Left arrow, or clicking ".." entry.</li>
511 <li>Breadcrumb segments are clickable to jump to ancestors.</li>
512 <li>Shift+Click range select. Cmd+Click toggle select. Cmd+A select all.</li>
513 <li>Selection persists across sort changes. Clears on navigation.</li>
514 </ul>
515 </div>
516
517 <h2>5. Search &amp; Filtering</h2>
518
519 <div class="test-group">
520 <h3>Text Search</h3>
521 <ul class="checklist">
522 <li>Type in search bar or press "/" to focus it. Results update as you type.</li>
523 <li>Escape clears search and restores full listing.</li>
524 <li>Search scope: current folder (default) or global.</li>
525 <li>Search with special characters: quotes, ampersands, Unicode.</li>
526 </ul>
527 </div>
528
529 <div class="test-group">
530 <h3>Filter Panel</h3>
531 <ul class="checklist">
532 <li>Open filter panel (toolbar button). Shows BPM, duration, key, classification, tag filters.</li>
533 <li>BPM range slider: drag min/max. Only samples in range appear.</li>
534 <li>Key filter: select keys, major/minor/both, exact vs compatible mode.</li>
535 <li>Compatible mode includes relative + circle-of-fifths neighbors.</li>
536 <li>Classification checkboxes filter to selected categories.</li>
537 <li>Tag prefix filter: type partial tag, matching samples shown.</li>
538 <li>Multiple filters combine with AND logic.</li>
539 </ul>
540 </div>
541
542 <div class="test-group">
543 <h3>Smart Folders</h3>
544 <ul class="checklist">
545 <li>With a filter active, save as smart folder. Appears in sidebar.</li>
546 <li>Click smart folder to re-activate its filter.</li>
547 <li>Delete smart folder via context menu.</li>
548 <li>Smart folders are per-VFS and persist across sessions.</li>
549 </ul>
550 </div>
551
552 <div class="test-group">
553 <h3>Similarity Search</h3>
554 <ul class="checklist">
555 <li>Right-click sample &rarr; "Find Similar": shows top 50 matches by spectral features.</li>
556 <li>Right-click &rarr; "Find Near-Duplicates": shows matches by peak envelope fingerprint.</li>
557 <li>Status bar shows match count. Clear with toolbar button.</li>
558 </ul>
559 </div>
560
561 <h2>6. Bulk Operations</h2>
562
563 <div class="test-group">
564 <h3>Bulk Tag (Cmd+T)</h3>
565 <ul class="checklist">
566 <li>Select 2+ samples. Cmd+T opens tag modal. Add or Remove mode toggle.</li>
567 <li>Enter a tag (dot-notation). "Apply" adds/removes to all selected.</li>
568 <li>Cmd+Z undoes the operation.</li>
569 <li>Empty tag input is a no-op (no crash, no undo entry).</li>
570 </ul>
571 </div>
572
573 <div class="test-group">
574 <h3>Bulk Rename (F2)</h3>
575 <ul class="checklist">
576 <li>Select 2+ samples. F2 opens rename modal. Pattern input with tokens.</li>
577 <li>Tokens: <code>{name}</code>, <code>{bpm}</code>, <code>{key}</code>, <code>{class}</code>, <code>{duration}</code>, <code>{n}</code>/<code>{nn}</code>/<code>{nnn}</code>.</li>
578 <li>Live preview shows old &rarr; new names. Validation errors appear inline.</li>
579 <li>Duplicate names auto-deduplicated with "(2)" suffix.</li>
580 <li>Invalid pattern (unknown token) shows error, prevents apply.</li>
581 <li>Cmd+Z undoes the rename.</li>
582 </ul>
583 </div>
584
585 <div class="test-group">
586 <h3>Bulk Move &amp; Delete</h3>
587 <ul class="checklist">
588 <li>Select items, open move modal. Choose target directory from dropdown.</li>
589 <li>Execute move. Items disappear from current view. Cmd+Z undoes.</li>
590 <li>Delete key on selection shows confirmation dialog. "Delete" executes, Cmd+Z undoes.</li>
591 <li>Multi-select delete: all selected items removed. Tags preserved in undo.</li>
592 <li>Undo stack maxes at 50 operations.</li>
593 </ul>
594 </div>
595
596 <h2>7. VFS Management</h2>
597
598 <div class="test-group">
599 <ul class="checklist">
600 <li>Create new VFS via sidebar. Name input modal. Appears in sidebar list.</li>
601 <li>Switch VFS by clicking its name. Navigation resets to root.</li>
602 <li>Rename VFS via context menu. Name updates in sidebar.</li>
603 <li>Delete VFS via context menu (only if &gt;1 exists). Confirmation dialog.</li>
604 <li>Create directory via toolbar button. Rename via context menu.</li>
605 <li>Delete directory cascades all children (confirmation required).</li>
606 </ul>
607 </div>
608
609 <div class="footer">
610 <div class="left">af/ testing guide &mdash; v0.3.0 alpha</div>
611 <div class="right">page 3 of 5</div>
612 </div>
613
614 </div>
615
616 <!-- PAGE 4: Preview, Instrument, Export, Themes -->
617 <div class="page">
618
619 <h2>8. Audio Preview</h2>
620
621 <div class="test-group">
622 <ul class="checklist">
623 <li><span class="badge critical">Critical</span> Select sample and press Enter or Space. Audio plays through system output.</li>
624 <li>Waveform cursor tracks playback position in detail panel.</li>
625 <li>Click waveform to seek to position.</li>
626 <li>Space pauses and resumes. Selecting another sample switches preview.</li>
627 <li>Long files (&gt;30s) use streaming decode: playback starts within ~0.5s.</li>
628 <li>Short files decode fully before playback (instant start).</li>
629 <li>All five formats play correctly: WAV, FLAC, MP3, OGG, AIFF.</li>
630 <li>Mono files play as centered stereo. Multi-channel downmixes to stereo.</li>
631 <li>Status bar shows "Playing: filename" during playback.</li>
632 </ul>
633 </div>
634
635 <h2>9. MIDI Instrument Mode</h2>
636
637 <div class="test-group">
638 <h3>Chromatic Mode</h3>
639 <ul class="checklist">
640 <li>Right-click sample &rarr; "Load to Instrument". Instrument panel opens at bottom.</li>
641 <li>Press I to toggle panel visibility.</li>
642 <li>Play notes via on-screen piano or MIDI keyboard.</li>
643 <li>Root note auto-detected from key analysis (defaults to C3 if unknown).</li>
644 <li>Pitch shifts correctly across the keyboard range.</li>
645 <li>8-voice polyphony: play more than 8 notes, oldest stolen.</li>
646 </ul>
647 </div>
648
649 <div class="test-group">
650 <h3>Multi-Sample Mode</h3>
651 <ul class="checklist">
652 <li>Add multiple zones with different key ranges.</li>
653 <li>Zone bars visible on the piano keyboard display.</li>
654 <li>Remove zone button removes the zone and kills its active voices.</li>
655 <li>ADSR envelope: audible attack, decay, sustain, release on each voice.</li>
656 </ul>
657 </div>
658
659 <h2>10. Export</h2>
660
661 <div class="test-group">
662 <h3>Configuration</h3>
663 <ul class="checklist">
664 <li><span class="badge critical">Critical</span> Start export flow. Config screen shows item count, format options, destination.</li>
665 <li>Device profile picker: 14 profiles available. Selecting one adjusts format/rate/depth.</li>
666 <li>Manual mode: choose format (WAV/AIFF/Original), sample rate, bit depth, channels.</li>
667 <li>Flatten toggle: export without directory structure.</li>
668 <li>Metadata sidecar toggle: writes .audiofiles.json per sample.</li>
669 <li>Destination picker: defaults to ~/Downloads/audiofiles Export.</li>
670 </ul>
671 </div>
672
673 <div class="test-group">
674 <h3>Export Progress &amp; Completion</h3>
675 <ul class="checklist">
676 <li>Progress bar advances. Current filename shown. Cancel stops mid-export.</li>
677 <li>Completion screen shows total exported and any errors.</li>
678 <li>Exported files are at the correct sample rate, bit depth, and format.</li>
679 <li>Filenames sanitized per device profile rules (length, case, separators).</li>
680 <li>Export to read-only destination: error shown, not a crash.</li>
681 </ul>
682 </div>
683
684 <div class="test-group">
685 <h3>Device Profile Spot Checks</h3>
686 <ul class="checklist two-col">
687 <li><strong>SP-404 MKII</strong>: WAV, 48kHz, 16-bit, stereo</li>
688 <li><strong>Digitakt</strong>: WAV, 48kHz, 16-bit, mono</li>
689 <li><strong>MPC</strong>: WAV, 44.1kHz, 16-bit, stereo</li>
690 <li><strong>OP-1</strong>: AIFF, 44.1kHz, 16-bit, stereo</li>
691 <li><strong>M8</strong>: WAV, 44.1kHz, 16-bit, mono</li>
692 <li><strong>Deluge</strong>: WAV, 44.1kHz, 16/24-bit, stereo</li>
693 </ul>
694 </div>
695
696 <h2>11. Themes</h2>
697
698 <div class="test-group">
699 <ul class="checklist">
700 <li>Theme picker in toolbar. All 17 themes selectable.</li>
701 <li>Switching theme updates all colors immediately. No leftover artifacts.</li>
702 <li>Theme preference persists across app restarts.</li>
703 <li>Waveform colors follow theme. Classification badges follow theme.</li>
704 <li>Progress bars, buttons, modals all correctly themed.</li>
705 <li>Light themes (ayu-light, flatwhite, gruvbox-light, rosepine-dawn, catppuccin-latte) have readable text.</li>
706 <li>High-contrast theme meets accessibility requirements.</li>
707 </ul>
708 </div>
709
710 <h2>12. Collections</h2>
711
712 <div class="test-group">
713 <ul class="checklist">
714 <li>Create collection via sidebar. Name input. Appears in sidebar with (0) count.</li>
715 <li>Right-click sample &rarr; "Add to Collection". Count updates.</li>
716 <li>Click collection name to view members. File list shows only those samples.</li>
717 <li>Remove sample from collection. Deactivate collection view to return to normal.</li>
718 <li>Rename and delete collections via context menu.</li>
719 <li>A sample can belong to multiple collections simultaneously.</li>
720 </ul>
721 </div>
722
723 <div class="footer">
724 <div class="left">af/ testing guide &mdash; v0.3.0 alpha</div>
725 <div class="right">page 4 of 5</div>
726 </div>
727
728 </div>
729
730 <!-- PAGE 5: Sync, Drag-out, Edge Cases, Stress -->
731 <div class="page">
732
733 <h2>13. Drag-Out (macOS)</h2>
734
735 <div class="test-group">
736 <ul class="checklist">
737 <li><span class="badge critical">Critical</span> Drag a sample from the file list to the Desktop. File appears with correct name.</li>
738 <li>Drag to a DAW (REAPER, Ableton, Logic). Sample loads in the DAW.</li>
739 <li>Multi-file drag: select multiple, drag. All files transferred.</li>
740 <li>Drag-out cooldown: rapid successive drags do not cause duplicate transfers.</li>
741 <li>Drag a file that has been deleted from the store: handled gracefully.</li>
742 </ul>
743 </div>
744
745 <h2>14. Cloud Sync</h2>
746
747 <div class="test-group">
748 <ul class="checklist">
749 <li>Open sync panel (toolbar icon). Shows "Disconnected" state.</li>
750 <li>Auth flow: enter code, opens browser for Makenot.work login.</li>
751 <li>After auth, encryption setup: enter passphrase. Keys derived and stored.</li>
752 <li>Sync Now: pushes metadata. Status updates to "Last synced: ..."</li>
753 <li>Auto-sync toggle with interval picker (5m, 15m, 30m, 1h).</li>
754 <li>Disconnect: clears credentials. Returns to Disconnected state.</li>
755 <li>Per-VFS sync toggle: metadata always syncs, audio blobs opt-in.</li>
756 <li>Wrong passphrase: clear error message, not a crash.</li>
757 </ul>
758 </div>
759
760 <h2>15. Edge Cases &amp; Stress</h2>
761
762 <div class="test-group">
763 <h3>Data Integrity</h3>
764 <ul class="checklist">
765 <li><span class="badge critical">Critical</span> Close and reopen the app. All data persists: VFS, tags, analysis, collections.</li>
766 <li>Import the same folder twice. No duplicate samples created in the store.</li>
767 <li>Delete a VFS. Samples remain in the store (still accessible from other VFS roots).</li>
768 <li>Delete the last reference to a sample. Store entry remains (content-addressed, never auto-deleted).</li>
769 </ul>
770 </div>
771
772 <div class="test-group">
773 <h3>Error Handling</h3>
774 <ul class="checklist">
775 <li>Import a folder with zero audio files: "No samples imported" message, no crash.</li>
776 <li>Import a corrupt WAV: import error captured, other files import normally.</li>
777 <li>Analyze a zero-length audio file: analysis error, sample still in store.</li>
778 <li>Analyze a file with unusual sample rate (8kHz, 192kHz): no crash.</li>
779 <li>Very short audio (&lt;0.1s): analysis completes, BPM may be absent.</li>
780 <li>Very long audio (&gt;10 min): streaming preview works, analysis completes.</li>
781 </ul>
782 </div>
783
784 <div class="test-group">
785 <h3>Performance</h3>
786 <ul class="checklist">
787 <li>Import a large library (1000+ files). Progress bar stays responsive.</li>
788 <li>Navigate a VFS with 500+ items in one directory. Scroll is smooth.</li>
789 <li>Run analysis on 100+ samples. Cancel mid-way. No orphaned workers.</li>
790 <li>Similarity search on a library of 500+ analyzed samples. Results appear in &lt;2s.</li>
791 <li>Theme switch with many items visible: no frame drops.</li>
792 </ul>
793 </div>
794
795 <div class="test-group">
796 <h3>Keyboard &amp; Focus</h3>
797 <ul class="checklist">
798 <li>All keyboard shortcuts work when file list has focus.</li>
799 <li>Shortcuts disabled when a text field has focus (except Escape).</li>
800 <li>Tab order through modals is logical.</li>
801 <li>Escape dismisses in priority: sync panel &rarr; bulk modal &rarr; confirm &rarr; help &rarr; search.</li>
802 </ul>
803 </div>
804
805 <div class="test-group">
806 <h3>Multi-Select Interactions</h3>
807 <ul class="checklist">
808 <li>Shift+Click from item 2 to item 8: items 2&ndash;8 selected.</li>
809 <li>Cmd+Click to deselect one item from a range: only that item deselected.</li>
810 <li>Shift+Down/Up extends selection one row at a time.</li>
811 <li>Select all (Cmd+A), then bulk tag, bulk rename, bulk move, bulk delete: all work.</li>
812 <li>Select ".." parent entry: excluded from bulk operations.</li>
813 </ul>
814 </div>
815
816 <h2>16. OTA Updates</h2>
817
818 <div class="test-group">
819 <ul class="checklist">
820 <li>On launch, update check runs in background (no UI freeze).</li>
821 <li>If update available: consent dialog with "Download" and "Not Now".</li>
822 <li>"Download" opens browser to download page.</li>
823 <li>"Not Now" dismisses. No repeated prompting in same session.</li>
824 <li>If no update available: no dialog, no indication. Silent.</li>
825 </ul>
826 </div>
827
828 <div class="highlight-box green">
829 <p><strong>When you find a bug.</strong> Note: (1) What you did. (2) What you expected. (3) What actually happened. (4) Which theme was active. (5) The exact error message or status text. (6) Whether the app crashed or recovered. File size and format of the involved sample if relevant.</p>
830 </div>
831
832 <div class="footer-inline">
833 <div class="left">af/ testing guide &mdash; v0.3.0 alpha</div>
834 <div class="right">page 5 of 5</div>
835 </div>
836
837 </div>
838
839 </body>
840 </html>
841