| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 290 |
<div class="page"> |
| 291 |
|
| 292 |
<div class="hero"> |
| 293 |
<h1>audiofiles/ testing</h1> |
| 294 |
<div class="tagline">Alpha testing guide — 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 — 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 & 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 & 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 & 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 & 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 & 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 & 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>↓</kbd> Move down</div> |
| 347 |
<div class="shortcut"><kbd>k</kbd> / <kbd>↑</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 — v0.3.0 alpha</div> |
| 382 |
<div class="right">page 1 of 5</div> |
| 383 |
</div> |
| 384 |
|
| 385 |
</div> |
| 386 |
|
| 387 |
|
| 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 (>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 & 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 — v0.3.0 alpha</div> |
| 494 |
<div class="right">page 2 of 5</div> |
| 495 |
</div> |
| 496 |
|
| 497 |
</div> |
| 498 |
|
| 499 |
|
| 500 |
<div class="page"> |
| 501 |
|
| 502 |
<h2>4. File List & 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 & 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 → "Find Similar": shows top 50 matches by spectral features.</li> |
| 556 |
<li>Right-click → "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 → 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 & 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 >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 — v0.3.0 alpha</div> |
| 611 |
<div class="right">page 3 of 5</div> |
| 612 |
</div> |
| 613 |
|
| 614 |
</div> |
| 615 |
|
| 616 |
|
| 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 (>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 → "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 & 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 → "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 — v0.3.0 alpha</div> |
| 725 |
<div class="right">page 4 of 5</div> |
| 726 |
</div> |
| 727 |
|
| 728 |
</div> |
| 729 |
|
| 730 |
|
| 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 & 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 (<0.1s): analysis completes, BPM may be absent.</li> |
| 780 |
<li>Very long audio (>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 <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 & 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 → bulk modal → confirm → help → 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–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 — 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 |
|