tts-voice-creator-clone-and.../architecture/qa.md
mARTin-B78 1fd79866f8 chore(qa): central npm run qa command with optional SonarQube stage
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 18:36:48 +02:00

3.2 KiB

QA: npm run qa

Developer-facing. Single entry point: scripts/qa.mjs (Node, no dependencies). Every stage is timed; a summary table is printed and the exit code is non-zero if any stage FAILs. SKIPPED never fails the run. Nothing is ever installed automatically.

npm run qa -- --fast        # everything except Playwright
npm run qa                  # full, incl. Playwright (desktop + iphone)
npm run qa -- --only e2e --grep voice-provenance
npm run qa -- --sonar       # add the SonarQube stage
npm run qa -- --list

Stages

id what skipped when
format formatter check always for now (no formatter configured)
lint node --check over tracked static/js, scripts, tests mjs; npm run check:frontend; python compileall; ruff if installed ruff missing -> noted only
types type check no type checker configured
pyunit unittest discover -s tests -p 'test_*.py' with a temp HOME/CONFIG_DIR (avoids the /home/app permission error, never touches live data) never
nodeunit npm run test:unit never
e2e Playwright, projects desktop + iphone; --grep supported --fast
a11y axe-core specs axe-core not installed (recommend npm i -D @axe-core/playwright, add tests/a11y.spec.js)
security npm audit --audit-level=high, pip-audit (if installed + requirements.txt), secret scan (gitleaks if present, else built-in regexes over tracked files) audits: network failure -> SKIPPED, not FAIL
build npm run minify, fails if static/dist/main.min.js changed (stale bundle; commit the regenerated file) never
perf DOM budget is tests/constrained.spec.js, runs inside e2e always (no separate stage)
sonar sonar-scanner with sonar-project.properties no --sonar, or SONAR_HOST_URL/SONAR_TOKEN unset, or scanner missing

Test isolation

Playwright baseURL defaults to the live container (http://localhost:7890, override with BASE_URL). The specs mock every /api/** route (the live server only serves static files and the page), so no live data is written; use a throwaway instance via BASE_URL when in doubt. --fast never touches it. The secret scan prints only file:line pattern-name, never the match.

SonarQube / secrets

SONAR_HOST_URL and SONAR_TOKEN are read from the environment only (shell or CI secrets). They are never written to files, argv or output (the scanner reads the token itself; output is redacted). The quality gate is awaited via -Dsonar.qualitygate.wait=true; no separate web API call is made.

CI

.github/workflows/sonarqube.yml already runs compile/unittest/frontend/build steps and the Sonar action (token from ${{ secrets.SONAR_TOKEN }}). An advisory (continue-on-error) npm run qa -- --fast step was added. Make it blocking once the pre-existing failures below are fixed.

Known pre-existing failures (2026-10-04)

  • check:frontend: duplicate top-level say in static/js/voice-archetypes.js and static/js/magazine.js.
  • test_epub_export.EndpointTests.test_downloads_a_valid_epub.
  • Secret scan: tracked scratch/test_openai.py and scratch/test_google_imagen.py contain key-like literals; rotate if real and remove from history/tracking.