Releases: vizzly-testing/cli
✨ v0.22.0
✨ v0.21.2
What's Changed
✨ v0.21.1
🏗️ Static Site Plugin v0.0.9
[0.0.9] - 2025-12-22
What's Changed
Added
--dry-runoption - Preview discovered pages and screenshot count without actually capturing screenshots. Perfect for debugging page discovery and understanding what will be tested.- Interactive progress display - Real-time progress updates with ETA in terminal mode, showing completion percentage and time remaining
Changed
- Smart concurrency defaults - Automatically detects optimal concurrency based on CPU cores (uses half of available cores, minimum 2, maximum 8). No more manual tuning needed!
- Improved error messages - Clear, actionable guidance when no TDD server or API token is found, showing both local and cloud workflow options
Fixed
- Sitemap index handling - Properly follows child sitemap references instead of treating sitemap files as pages to screenshot
- Progress output - Better handling of errors and completion messages in both interactive (TTY) and CI environments
Full Changelog: static-site/v0.0.8...static-site/v0.0.9
🏗️ Static Site Plugin v0.0.8
[0.0.8] - 2025-12-22
What's Changed
Changed
- Refactor to functional tab pool + work queue architecture for improved performance and reliability
- True tab-level concurrency (max tabs actually means max browser tabs, not max pages)
- Tab reuse via pooling eliminates create/destroy overhead
- Task-based processing where each (page, viewport) tuple is independent
- Better work distribution across concurrent tasks
- Migrate test suite from Vitest to Node.js built-in test runner (22+ required)
- Migrate from ESLint + Prettier to Biome for unified, faster linting and formatting
Fixed
- Fix cloud mode crash when using
services.get()API (now uses direct property access) - Fix accessibility issues in example code (button types, aria-hidden attributes)
Full Changelog: static-site/v0.0.7...static-site/v0.0.8
🏗️ Static Site Plugin v0.0.10
[0.0.10] - 2025-12-22
What's Changed
Added
- Screenshot timeout configuration: New
--timeoutoption (default: 45 seconds) prevents hanging on slow-loading pages - Automatic retry logic: Failed screenshots now retry once with a fresh browser tab to recover from timeouts and protocol errors
- Tab recycling: Browser tabs are automatically recycled after 10 uses to prevent memory leaks in long-running screenshot jobs
Changed
- CI Performance: Optimized browser arguments for resource-constrained CI environments (disabled GPU, reduced memory usage, limited V8 heap to 512MB)
- Protocol timeout reduced from 180s to 60s for faster failure detection
- CLI output now uses proper formatting methods for better readability
Fixed
- Improved reliability in CI environments where resource constraints previously caused timeout spikes and hanging jobs
- Better handling of crashed tabs and protocol errors through automatic retry mechanism
Full Changelog: static-site/v0.0.9...static-site/v0.0.10
✨ v0.21.0
🎉 Major Release: Architecture Overhaul
A massive overhaul including test framework migration, functional architecture refactor, and significant new features.
✨ New Features
- Server-Sent Events - Real-time dashboard updates without polling (#148)
- Delete Comparisons - Remove unwanted new screenshots from dashboard (#145)
- TUI Toolkit - Branded CLI output with polished help commands (#141)
- Quiet-by-Default - Cleaner, focused CLI output (#138)
- Observatory Design System - Refreshed reporter UI (#147)
🐛 Bug Fixes
- Wire authService and projectService into TDD server (#149)
- Fix HTTP keep-alive preventing clean process exit (#146)
- Fix acceptBaseline saving with double .png extension (#144)
- Fix comparison rejection not working in TDD mode (#137)
- Fix undefined dependencies in TddService methods (#136)
⚙️ Breaking Changes
- Node.js requirement updated to >=22.0.0 (was >=20.0.0)
♻️ Functional Architecture Refactor
Eliminated thin service wrapper classes and rebuilt around functional modules with explicit dependency injection.
New Module Structure
| Module | Location | Purpose |
|---|---|---|
| API | src/api/ |
createApiClient(), endpoints, request handling |
| Auth | src/auth/ |
createAuthClient(), login/logout, token refresh |
| Config | src/config/ |
Config merging, serialization, validation |
| Project | src/project/ |
Project operations, status updates |
| TDD | src/tdd/ |
Comparisons, baselines, hotspots, results |
| Report | src/report-generator/ |
HTML report generation |
| Server | src/screenshot-server/ |
HTTP handling, middleware |
Migration Guide
// Old (deprecated, still works)
import { createServices } from '@vizzly-testing/cli'
const services = createServices(config)
await services.apiService.request(...)
// New (recommended)
import { createApiClient, getBuild } from '@vizzly-testing/cli/api'
const client = createApiClient(config)
const build = await getBuild(client, buildId)🧪 Test Framework Migration
Migrated from Vitest to Node.js 22+ built-in test runner with c8 for coverage.
Coverage Improvements
| Metric | Before | After |
|---|---|---|
| Lines | ~30% | 87% |
| Functions | ~25% | 91% |
| Branches | ~40% | 95% |
1,432 tests with full coverage of all CLI commands, API client, auth, config, TDD service, and error handling.
📊 Stats
- ~30,000 insertions / ~21,000 deletions
- ~700 lines removed from services layer
- Service wrappers removed: ApiService, AuthService, ConfigService, ProjectService, BuildManager
- All public APIs remain backward compatible
✨ v0.20.1
🧪 v0.20.1-beta.1
What's Changed
- 🔖 v0.20.1-beta.1
- 🐛 Fix HTTP keep-alive preventing clean process exit (#146)
- ✨ Add delete comparison feature for new screenshots (#145)
- 🐛 Fix acceptBaseline saving to wrong path with double .png extension (#144)
- ✨ Add TUI visual tests using tui-driver (#143)
- ✨ Add TUI toolkit with branded help output and dynamic context (#141)
- ⬆️ Bump the dependencies group with 8 updates (#139)
- ⬆️ Bump @types/node from 24.10.1 to 25.0.2 (#140)
- ✨ Improve CLI output with quiet-by-default behavior and clean summaries (#138)
- 🐛 Fix comparison rejection not working in TDD mode (#137)
- 🐛 Fix undefined dependencies in TddService methods (#136)
🧪 v0.20.1-beta.0
Test Framework Migration
Migrated the entire test suite from Vitest to Node.js 20+ built-in test runner with c8 for coverage. The old Vitest configuration and coverage tooling have been completely removed.
Coverage improvements:
- Line coverage: ~30% → 87.07%
- Function coverage: ~25% → 90.79%
- Branch coverage: ~40% → 94.99%
New test coverage:
- All CLI commands: run, tdd, upload, finalize, login, logout, project, whoami, doctor, status (100% coverage)
- API client: request handling, endpoint operations, error responses
- Auth module: token refresh, login flows, token store operations
- Config system: file loading, environment variable merging, validation, serialization
- TDD service: baseline management, comparison logic, hotspot detection
- Screenshot server: HTTP handling, middleware, routers
- Error handling: All VizzlyError subclasses at 100% coverage
- Utilities: git operations, CI environment detection, security, output formatting
The test suite now has 1,432 tests total. Scripts updated to use node --test instead of vitest, with no configuration files required.
Functional Architecture Refactor
Eliminated the thin service wrapper classes (ApiService, AuthService, ConfigService, ProjectService, TddService) and rebuilt the codebase around functional modules with explicit dependency injection.
New module structure:
API Module (src/api/)
client.js: Factory functioncreateApiClient()that returns a request handler with token refresh logiccore.js: Pure functions for building URLs, headers, auth tokens, payload formatting, and error parsingendpoints.js: Functions likecreateBuild(),getBuild(),uploadScreenshot(),checkShas(), etc.index.js: Public exports for all above
Auth Module (src/auth/)
client.js: Factory functioncreateAuthClient()for auth operationscore.js: Pure functions for building auth payloads, parsing responses, validating credentialsoperations.js: High-level operations like login, logout, token refreshindex.js: Public exports includingcreateTokenStore()helper for commands
Config Module (src/config/)
core.js: Pure functions for merging config objects, serializing to JSON/JavaScript, validating read/write scopesoperations.js: Functions likegetConfig(),updateConfig(),getMergedConfig()that take filesystem and cosmiconfig functions as dependenciesindex.js: Public exports
Project Module (src/project/)
core.js: Pure functions for parsing project responses, building project operationsoperations.js: Functions likegetCurrentProject(),updateProjectStatus(),getProjectByOrg()that take API client as dependencyindex.js: Public exports
TDD Module (src/tdd/)
- Restructured into
services/subdirectory with specialized modules:comparison-service.js: Core screenshot comparison logic using honeydiffbaseline-manager.js: Baseline storage and retrievalhotspot-service.js: Hotspot detection and coveragebaseline-downloader.js: Downloading baselines from cloudresult-service.js: Result aggregation and status tracking
core/: Pure functions for signature generation and hotspot coverage calculationsmetadata/: Baseline and hotspot metadata managementindex.js: Public exports for TDD operations
Report Generator Module (src/report-generator/)
- New functional module for generating HTML reports
- Replaces old asset-based approach with computed reports
- Functions like
generateReport(),collectComparisons()
Screenshot Server Module (src/screenshot-server/)
- Extracted from TddService into dedicated module
core.js: HTTP request/response handlingoperations.js: Router operations and middleware- Server lifecycle management
Commands now import directly from these functional modules instead of going through createServices(). This eliminates indirection and makes testing straightforward—just pass mock dependencies.
Migration for v0.21+:
The testRunner and serverManager classes remain in src/services/ for backward compatibility with the plugin API. These are marked for removal in the next major version. Plugin authors should migrate to using the functional modules directly:
```javascript
// Old (still works, deprecated)
import { createServices } from '@vizzly-testing/cli'
const services = createServices(config)
await services.apiService.request(...)
// New (recommended)
import { createApiClient, getBuild } from '@vizzly-testing/cli/api'
const client = createApiClient(config)
const build = await getBuild(client, buildId)
```
Command Changes
All commands refactored to use functional modules directly with dependency injection for testability.
run.js, tdd.js, upload.js, finalize.js, login.js, logout.js, project.js, whoami.js, doctor.js, status.js: All updated to import from functional modules with dependency injection. Commands accept deps parameter for test mocking. No changes to command-line interfaces or user-facing behavior.
Dependency Changes
Removed:
- vitest (v4.0.3)
- @vitest/coverage-v8
Build scripts: Removed copy-assets step (report-generator now uses functional code, not static assets)
Lint commands: Updated from biome lint to biome check
Engine Requirements
Node.js requirement updated to >=22.0.0 (was >=20.0.0)
Bug Fixes
Fixed createTokenStore export — A simplification in the auth module migration accidentally made helper functions unavailable in scope. Changed to import-then-re-export pattern.
Removed flaky tests — Tests that were intermittently failing in CI have been removed and will be rewritten with proper isolation.
E2E Test Coverage
Added end-to-end tests for reporter UI workflows using Playwright, covering navigation, baseline acceptance, settings updates, and project linking.
Summary
- 202 files changed: 30,740 insertions / 21,004 deletions
- 13 commits since v0.20.0
- 1,432 tests with 87% code coverage
- ~700 lines removed from services layer through functional refactoring
- Service wrappers removed: ApiService, AuthService, ConfigService, ProjectService (class wrappers), BuildManager (class), html-report-generator
All commands, configuration, and public APIs remain backward compatible. This is an internal restructuring to improve code quality and testability.