@vizzly-testing/cli 0.1.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/LICENSE +21 -0
- package/README.md +363 -0
- package/bin/vizzly.js +3 -0
- package/dist/cli.js +104 -0
- package/dist/client/index.js +237 -0
- package/dist/commands/doctor.js +158 -0
- package/dist/commands/init.js +102 -0
- package/dist/commands/run.js +224 -0
- package/dist/commands/status.js +164 -0
- package/dist/commands/tdd.js +212 -0
- package/dist/commands/upload.js +181 -0
- package/dist/container/index.js +184 -0
- package/dist/errors/vizzly-error.js +149 -0
- package/dist/index.js +31 -0
- package/dist/screenshot-wrapper.js +68 -0
- package/dist/sdk/index.js +364 -0
- package/dist/server/index.js +522 -0
- package/dist/services/api-service.js +215 -0
- package/dist/services/base-service.js +154 -0
- package/dist/services/build-manager.js +214 -0
- package/dist/services/screenshot-server.js +96 -0
- package/dist/services/server-manager.js +61 -0
- package/dist/services/service-utils.js +171 -0
- package/dist/services/tdd-service.js +444 -0
- package/dist/services/test-runner.js +210 -0
- package/dist/services/uploader.js +413 -0
- package/dist/types/cli.d.ts +2 -0
- package/dist/types/client/index.d.ts +76 -0
- package/dist/types/commands/doctor.d.ts +11 -0
- package/dist/types/commands/init.d.ts +14 -0
- package/dist/types/commands/run.d.ts +13 -0
- package/dist/types/commands/status.d.ts +13 -0
- package/dist/types/commands/tdd.d.ts +13 -0
- package/dist/types/commands/upload.d.ts +13 -0
- package/dist/types/container/index.d.ts +61 -0
- package/dist/types/errors/vizzly-error.d.ts +75 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.js +153 -0
- package/dist/types/screenshot-wrapper.d.ts +27 -0
- package/dist/types/sdk/index.d.ts +108 -0
- package/dist/types/server/index.d.ts +38 -0
- package/dist/types/services/api-service.d.ts +77 -0
- package/dist/types/services/base-service.d.ts +72 -0
- package/dist/types/services/build-manager.d.ts +68 -0
- package/dist/types/services/screenshot-server.d.ts +10 -0
- package/dist/types/services/server-manager.d.ts +8 -0
- package/dist/types/services/service-utils.d.ts +45 -0
- package/dist/types/services/tdd-service.d.ts +55 -0
- package/dist/types/services/test-runner.d.ts +25 -0
- package/dist/types/services/uploader.d.ts +34 -0
- package/dist/types/types/index.d.ts +373 -0
- package/dist/types/utils/colors.d.ts +12 -0
- package/dist/types/utils/config-helpers.d.ts +6 -0
- package/dist/types/utils/config-loader.d.ts +22 -0
- package/dist/types/utils/console-ui.d.ts +61 -0
- package/dist/types/utils/diagnostics.d.ts +69 -0
- package/dist/types/utils/environment-config.d.ts +54 -0
- package/dist/types/utils/environment.d.ts +36 -0
- package/dist/types/utils/error-messages.d.ts +42 -0
- package/dist/types/utils/fetch-utils.d.ts +1 -0
- package/dist/types/utils/framework-detector.d.ts +5 -0
- package/dist/types/utils/git.d.ts +44 -0
- package/dist/types/utils/help.d.ts +11 -0
- package/dist/types/utils/image-comparison.d.ts +42 -0
- package/dist/types/utils/logger-factory.d.ts +26 -0
- package/dist/types/utils/logger.d.ts +79 -0
- package/dist/types/utils/package-info.d.ts +15 -0
- package/dist/types/utils/package.d.ts +1 -0
- package/dist/types/utils/project-detection.d.ts +19 -0
- package/dist/types/utils/ui-helpers.d.ts +23 -0
- package/dist/utils/colors.js +66 -0
- package/dist/utils/config-helpers.js +8 -0
- package/dist/utils/config-loader.js +120 -0
- package/dist/utils/console-ui.js +226 -0
- package/dist/utils/diagnostics.js +184 -0
- package/dist/utils/environment-config.js +93 -0
- package/dist/utils/environment.js +109 -0
- package/dist/utils/error-messages.js +34 -0
- package/dist/utils/fetch-utils.js +9 -0
- package/dist/utils/framework-detector.js +40 -0
- package/dist/utils/git.js +226 -0
- package/dist/utils/help.js +66 -0
- package/dist/utils/image-comparison.js +172 -0
- package/dist/utils/logger-factory.js +76 -0
- package/dist/utils/logger.js +231 -0
- package/dist/utils/package-info.js +38 -0
- package/dist/utils/package.js +9 -0
- package/dist/utils/project-detection.js +145 -0
- package/dist/utils/ui-helpers.js +86 -0
- package/package.json +103 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Stubborn Mule Software
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
# Vizzly CLI
|
|
2
|
+
|
|
3
|
+
> Visual review platform for UI developers and designers
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@vizzly-testing/cli)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## What is Vizzly?
|
|
9
|
+
|
|
10
|
+
Vizzly is a visual review platform designed for how modern teams work. Instead of recreating your components in a sandboxed environment, Vizzly captures screenshots directly from your functional tests. This means you test the *real thing*, not a snapshot.
|
|
11
|
+
|
|
12
|
+
It's fast because we don't render anything—we process the images you provide from any source. Bring screenshots from web apps, mobile apps, or even design mockups, and use our collaborative dashboard to streamline the review process between developers and designers.
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- 📸 **Smart Screenshots** - Automatic deduplication and intelligent diffing
|
|
17
|
+
- 🎨 **Any Screenshot** - Web, mobile, desktop, design mockups, or any visual content
|
|
18
|
+
- 🏃 **TDD Mode** - Local visual comparison for rapid development
|
|
19
|
+
- 📊 **Beautiful Dashboard** - Intuitive web interface for reviewing changes
|
|
20
|
+
- 👥 **Team Collaboration** - Built for UI developers and designers to work together
|
|
21
|
+
- 🔄 **CI/CD Ready** - GitHub, GitLab, CircleCI, and more
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
Requirements: Node.js 20 or newer.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Install globally
|
|
29
|
+
npm install -g @vizzly-testing/cli
|
|
30
|
+
|
|
31
|
+
# Initialize your project
|
|
32
|
+
vizzly init
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Set up your API token
|
|
36
|
+
|
|
37
|
+
For local development, create a `.env` file in your project root and add your token:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
VIZZLY_TOKEN=your-api-token
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Then add `.env` to your `.gitignore` file. For CI/CD, use your provider's secret management system.
|
|
44
|
+
|
|
45
|
+
### Upload existing screenshots
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
vizzly upload ./screenshots --build-name "Release v1.2.3"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Integrate with your tests
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Run tests with Vizzly integration
|
|
55
|
+
vizzly run "npm test"
|
|
56
|
+
|
|
57
|
+
# Use TDD mode for local development
|
|
58
|
+
vizzly run "npm test" --tdd
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### In your test code
|
|
62
|
+
|
|
63
|
+
```javascript
|
|
64
|
+
import { vizzlyScreenshot } from '@vizzly-testing/cli/client';
|
|
65
|
+
|
|
66
|
+
// Your test framework takes the screenshot
|
|
67
|
+
const screenshot = await page.screenshot();
|
|
68
|
+
|
|
69
|
+
// Send to Vizzly for review
|
|
70
|
+
await vizzlyScreenshot('homepage', screenshot, {
|
|
71
|
+
browser: 'chrome',
|
|
72
|
+
viewport: '1920x1080'
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
> **Multi-Language Support**: Currently available as a JavaScript/Node.js SDK with Python, Ruby, and other language bindings coming soon. The client SDK is lightweight and simply POSTs screenshot data to the CLI for processing.
|
|
77
|
+
|
|
78
|
+
## Commands
|
|
79
|
+
|
|
80
|
+
### Upload Screenshots
|
|
81
|
+
```bash
|
|
82
|
+
vizzly upload <directory> # Upload screenshots from directory
|
|
83
|
+
vizzly upload ./screenshots --wait # Wait for processing
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Run Tests with Integration
|
|
87
|
+
```bash
|
|
88
|
+
vizzly run "npm test" # Run with Vizzly integration
|
|
89
|
+
vizzly run "npm test" --tdd # Local TDD mode
|
|
90
|
+
vizzly run "pytest" --port 3002 # Custom port
|
|
91
|
+
vizzly run "npm test" --wait # Wait for build completion
|
|
92
|
+
vizzly run "npm test" --eager # Create build immediately
|
|
93
|
+
vizzly run "npm test" --allow-no-token # Run without API token
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### Run Command Options
|
|
97
|
+
|
|
98
|
+
**Server Configuration:**
|
|
99
|
+
- `--port <port>` - Port for screenshot server (default: 47392)
|
|
100
|
+
- `--timeout <ms>` - Server timeout in milliseconds (default: 30000)
|
|
101
|
+
|
|
102
|
+
**Build Configuration:**
|
|
103
|
+
- `-b, --build-name <name>` - Custom build name
|
|
104
|
+
- `--branch <branch>` - Git branch override
|
|
105
|
+
- `--commit <sha>` - Git commit SHA override
|
|
106
|
+
- `--message <msg>` - Commit message
|
|
107
|
+
- `--environment <env>` - Environment name (default: test)
|
|
108
|
+
|
|
109
|
+
**Processing Options:**
|
|
110
|
+
- `--wait` - Wait for build completion and exit with appropriate code
|
|
111
|
+
- `--eager` - Create build immediately (default: lazy creation)
|
|
112
|
+
- `--threshold <number>` - Comparison threshold (0-1, default: 0.01)
|
|
113
|
+
- `--batch-size <n>` - Upload batch size used with `--wait`
|
|
114
|
+
- `--upload-timeout <ms>` - Upload wait timeout in ms
|
|
115
|
+
|
|
116
|
+
**Development & Testing:**
|
|
117
|
+
- `--tdd` - Enable TDD mode with local comparisons
|
|
118
|
+
- `--allow-no-token` - Allow running without API token (useful for local development)
|
|
119
|
+
- `--token <token>` - API token override
|
|
120
|
+
|
|
121
|
+
**Baseline Configuration:**
|
|
122
|
+
- `--baseline-build <id>` - Use specific build as baseline for comparisons
|
|
123
|
+
- `--baseline-comparison <id>` - Use specific comparison as baseline
|
|
124
|
+
|
|
125
|
+
### Setup and Status Commands
|
|
126
|
+
```bash
|
|
127
|
+
vizzly init # Create vizzly.config.js with defaults
|
|
128
|
+
vizzly status <build-id> # Check build progress and results
|
|
129
|
+
vizzly status <build-id> --verbose # Detailed build information
|
|
130
|
+
vizzly status <build-id> --json # Machine-readable output
|
|
131
|
+
vizzly doctor # Fast local preflight (no network)
|
|
132
|
+
vizzly doctor --api # Include API connectivity checks
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### Init Command
|
|
136
|
+
Creates a basic `vizzly.config.js` configuration file with sensible defaults. No interactive prompts - just generates a clean config you can customize.
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
vizzly init # Create config file
|
|
140
|
+
vizzly init --force # Overwrite existing config
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### Status Command
|
|
144
|
+
Check the progress and results of your builds. Shows comprehensive information including:
|
|
145
|
+
- Build status and progress
|
|
146
|
+
- Screenshot and comparison counts (new, changed, identical)
|
|
147
|
+
- Git branch and commit details
|
|
148
|
+
- Direct web dashboard link
|
|
149
|
+
- Timing and execution information
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Basic status check
|
|
153
|
+
vizzly status abc123-def456-build-id
|
|
154
|
+
|
|
155
|
+
# Detailed information for debugging
|
|
156
|
+
vizzly status abc123-def456-build-id --verbose
|
|
157
|
+
|
|
158
|
+
# JSON output for CI/CD integration
|
|
159
|
+
vizzly status abc123-def456-build-id --json
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Doctor
|
|
163
|
+
- Purpose: Quickly validate your local setup without network calls by default.
|
|
164
|
+
- Checks: Node.js version (>= 20), `apiUrl` format, comparison `threshold`, effective `port` (default 47392).
|
|
165
|
+
- Optional: Add `--api` to verify connectivity using your `VIZZLY_TOKEN`.
|
|
166
|
+
|
|
167
|
+
Examples:
|
|
168
|
+
```bash
|
|
169
|
+
# Local-only checks
|
|
170
|
+
vizzly doctor
|
|
171
|
+
|
|
172
|
+
# Include API connectivity
|
|
173
|
+
VIZZLY_TOKEN=your-token vizzly doctor --api
|
|
174
|
+
|
|
175
|
+
# JSON output for tooling
|
|
176
|
+
vizzly doctor --json
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## TDD Mode
|
|
180
|
+
|
|
181
|
+
TDD mode enables fast local development by comparing screenshots locally without uploading to Vizzly:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# First run - creates local baselines (no token needed)
|
|
185
|
+
npx vizzly tdd "npm test"
|
|
186
|
+
|
|
187
|
+
# Make changes and test - fails if visual differences detected
|
|
188
|
+
npx vizzly tdd "npm test"
|
|
189
|
+
|
|
190
|
+
# Accept changes as new baseline
|
|
191
|
+
npx vizzly tdd "npm test" --set-baseline
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
- **🐻 Auto-baseline creation**: Creates baselines locally when none exist
|
|
195
|
+
- **🐻 No token required**: Works entirely offline for local development
|
|
196
|
+
- **🐻 Tests fail on differences**: Immediate feedback when visuals change
|
|
197
|
+
- **🐻 Accept changes**: Use `--set-baseline` to update baselines
|
|
198
|
+
|
|
199
|
+
## Configuration
|
|
200
|
+
|
|
201
|
+
Create a `vizzly.config.js` file with `vizzly init` or manually:
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
204
|
+
export default {
|
|
205
|
+
// API configuration
|
|
206
|
+
// Set VIZZLY_TOKEN environment variable or uncomment and set here:
|
|
207
|
+
// apiToken: 'your-token-here',
|
|
208
|
+
|
|
209
|
+
// Screenshot configuration
|
|
210
|
+
screenshots: {
|
|
211
|
+
directory: './screenshots',
|
|
212
|
+
formats: ['png']
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
// Server configuration
|
|
216
|
+
server: {
|
|
217
|
+
port: 47392,
|
|
218
|
+
screenshotPath: '/screenshot'
|
|
219
|
+
},
|
|
220
|
+
|
|
221
|
+
// Comparison configuration
|
|
222
|
+
comparison: {
|
|
223
|
+
threshold: 0.1,
|
|
224
|
+
ignoreAntialiasing: true
|
|
225
|
+
},
|
|
226
|
+
|
|
227
|
+
// Upload configuration
|
|
228
|
+
upload: {
|
|
229
|
+
concurrency: 5,
|
|
230
|
+
timeout: 30000
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Run `vizzly init` to generate this file automatically with sensible defaults.
|
|
236
|
+
|
|
237
|
+
## Config Reference
|
|
238
|
+
|
|
239
|
+
For the full configuration schema and CLI options, see docs/api-reference.md.
|
|
240
|
+
|
|
241
|
+
## Framework Examples
|
|
242
|
+
|
|
243
|
+
### Playwright
|
|
244
|
+
```javascript
|
|
245
|
+
import { vizzlyScreenshot } from '@vizzly-testing/cli/client';
|
|
246
|
+
|
|
247
|
+
test('homepage test', async ({ page }) => {
|
|
248
|
+
await page.goto('/');
|
|
249
|
+
const screenshot = await page.screenshot();
|
|
250
|
+
await vizzlyScreenshot('homepage', screenshot, {
|
|
251
|
+
browser: 'chrome',
|
|
252
|
+
viewport: '1920x1080'
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Cypress
|
|
258
|
+
```javascript
|
|
259
|
+
// cypress/support/commands.js
|
|
260
|
+
Cypress.Commands.add('vizzlyScreenshot', (name, properties = {}) => {
|
|
261
|
+
cy.screenshot(name, { capture: 'viewport' });
|
|
262
|
+
cy.readFile(`cypress/screenshots/${name}.png`, 'base64').then((imageBase64) => {
|
|
263
|
+
const imageBuffer = Buffer.from(imageBase64, 'base64');
|
|
264
|
+
return vizzlyScreenshot(name, imageBuffer, {
|
|
265
|
+
browser: Cypress.browser.name,
|
|
266
|
+
...properties
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## CI/CD Integration
|
|
273
|
+
|
|
274
|
+
For CI/CD pipelines, use the `--wait` flag to wait for visual comparison results and get appropriate exit codes:
|
|
275
|
+
|
|
276
|
+
### GitHub Actions
|
|
277
|
+
```yaml
|
|
278
|
+
- name: Visual Tests
|
|
279
|
+
run: npx vizzly run "npm test" --wait
|
|
280
|
+
env:
|
|
281
|
+
VIZZLY_TOKEN: ${{ secrets.VIZZLY_TOKEN }}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### GitLab CI
|
|
285
|
+
```yaml
|
|
286
|
+
visual-tests:
|
|
287
|
+
stage: test
|
|
288
|
+
image: node:20
|
|
289
|
+
script:
|
|
290
|
+
- npm ci
|
|
291
|
+
- npx vizzly run "npm test" --wait
|
|
292
|
+
variables:
|
|
293
|
+
VIZZLY_TOKEN: $VIZZLY_TOKEN
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
The `--wait` flag ensures the process:
|
|
297
|
+
- Waits for all screenshots to be processed
|
|
298
|
+
- Exits with code `1` if visual differences are detected
|
|
299
|
+
- Exits with code `0` if all comparisons pass
|
|
300
|
+
- Allows your CI to fail appropriately when visual regressions occur
|
|
301
|
+
|
|
302
|
+
## API Reference
|
|
303
|
+
|
|
304
|
+
### `vizzlyScreenshot(name, imageBuffer, properties)`
|
|
305
|
+
Send a screenshot to Vizzly.
|
|
306
|
+
- `name` (string): Screenshot identifier
|
|
307
|
+
- `imageBuffer` (Buffer): Image data
|
|
308
|
+
- `properties` (object): Metadata for organization
|
|
309
|
+
|
|
310
|
+
### `isVizzlyEnabled()`
|
|
311
|
+
Check if Vizzly is enabled in the current environment.
|
|
312
|
+
|
|
313
|
+
## Documentation
|
|
314
|
+
|
|
315
|
+
- [Getting Started](./docs/getting-started.md)
|
|
316
|
+
- [Upload Command Guide](./docs/upload-command.md)
|
|
317
|
+
- [Test Integration Guide](./docs/test-integration.md)
|
|
318
|
+
- [TDD Mode Guide](./docs/tdd-mode.md)
|
|
319
|
+
- [API Reference](./docs/api-reference.md)
|
|
320
|
+
- [Doctor Command](./docs/doctor-command.md)
|
|
321
|
+
|
|
322
|
+
## Environment Variables
|
|
323
|
+
|
|
324
|
+
- `VIZZLY_TOKEN`: API authentication token. Example: `export VIZZLY_TOKEN=your-token`.
|
|
325
|
+
- `VIZZLY_API_URL`: Override API base URL. Default: `https://vizzly.dev`.
|
|
326
|
+
- `VIZZLY_LOG_LEVEL`: Logger level. One of `debug`, `info`, `warn`, `error`. Example: `export VIZZLY_LOG_LEVEL=debug`.
|
|
327
|
+
|
|
328
|
+
## Contributing
|
|
329
|
+
|
|
330
|
+
We welcome contributions! Whether you're fixing bugs, adding features, or improving documentation, your help makes Vizzly better for everyone.
|
|
331
|
+
|
|
332
|
+
### Getting Started
|
|
333
|
+
|
|
334
|
+
1. Fork the repository on [GitHub](https://github.com/vizzly/cli)
|
|
335
|
+
2. Clone your fork locally: `git clone https://github.com/your-username/cli.git`
|
|
336
|
+
3. Install dependencies: `npm install`
|
|
337
|
+
4. Run tests to ensure everything works: `npm test`
|
|
338
|
+
|
|
339
|
+
### Development Workflow
|
|
340
|
+
|
|
341
|
+
1. Create a feature branch: `git checkout -b feature/your-feature-name`
|
|
342
|
+
2. Make your changes and **add tests** for any new functionality
|
|
343
|
+
3. Run the linter: `npm run lint`
|
|
344
|
+
4. Run tests: `npm test`
|
|
345
|
+
5. Commit your changes using [gitmoji](https://gitmoji.dev/) format: `git commit -m '✨ Add your feature'`
|
|
346
|
+
6. Push to your fork: `git push origin feature/your-feature-name`
|
|
347
|
+
7. Open a Pull Request
|
|
348
|
+
|
|
349
|
+
### Reporting Issues
|
|
350
|
+
|
|
351
|
+
Found a bug or have a feature request? Please [open an issue](https://github.com/vizzly/cli/issues) with:
|
|
352
|
+
|
|
353
|
+
- A clear description of the problem or request
|
|
354
|
+
- Steps to reproduce (for bugs)
|
|
355
|
+
- Your environment details (OS, Node.js version, etc.)
|
|
356
|
+
|
|
357
|
+
### Development Setup
|
|
358
|
+
|
|
359
|
+
The CLI is built with modern JavaScript and requires Node.js 20+ (LTS). See the development scripts in `package.json` for available commands.
|
|
360
|
+
|
|
361
|
+
## License
|
|
362
|
+
|
|
363
|
+
MIT © Stubborn Mule Software
|
package/bin/vizzly.js
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { program } from 'commander';
|
|
3
|
+
import { init } from './commands/init.js';
|
|
4
|
+
import { uploadCommand, validateUploadOptions } from './commands/upload.js';
|
|
5
|
+
import { runCommand, validateRunOptions } from './commands/run.js';
|
|
6
|
+
import { tddCommand, validateTddOptions } from './commands/tdd.js';
|
|
7
|
+
import { statusCommand, validateStatusOptions } from './commands/status.js';
|
|
8
|
+
import { doctorCommand, validateDoctorOptions } from './commands/doctor.js';
|
|
9
|
+
import { getPackageVersion } from './utils/package-info.js';
|
|
10
|
+
program.name('vizzly').description('Vizzly CLI for visual regression testing').version(getPackageVersion()).option('-c, --config <path>', 'Config file path').option('--token <token>', 'Vizzly API token').option('-v, --verbose', 'Verbose output').option('--json', 'Machine-readable output').option('--no-color', 'Disable colored output');
|
|
11
|
+
program.command('init').description('Initialize Vizzly in your project').option('--force', 'Overwrite existing configuration').action(async options => {
|
|
12
|
+
const globalOptions = program.opts();
|
|
13
|
+
await init({
|
|
14
|
+
...globalOptions,
|
|
15
|
+
...options
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
program.command('upload').description('Upload screenshots to Vizzly').argument('<path>', 'Path to screenshots directory or file').option('-b, --build-name <name>', 'Build name for grouping').option('-m, --metadata <json>', 'Additional metadata as JSON').option('--batch-size <n>', 'Upload batch size', v => parseInt(v, 10)).option('--upload-timeout <ms>', 'Upload timeout in milliseconds', v => parseInt(v, 10)).option('--branch <branch>', 'Git branch').option('--commit <sha>', 'Git commit SHA').option('--message <msg>', 'Commit message').option('--environment <env>', 'Environment name', 'test').option('--threshold <number>', 'Comparison threshold', parseFloat).option('--token <token>', 'API token override').option('--wait', 'Wait for build completion').action(async (path, options) => {
|
|
19
|
+
const globalOptions = program.opts();
|
|
20
|
+
|
|
21
|
+
// Validate options
|
|
22
|
+
const validationErrors = validateUploadOptions(path, options);
|
|
23
|
+
if (validationErrors.length > 0) {
|
|
24
|
+
console.error('Validation errors:');
|
|
25
|
+
validationErrors.forEach(error => console.error(` - ${error}`));
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
await uploadCommand(path, options, globalOptions);
|
|
29
|
+
});
|
|
30
|
+
program.command('tdd').description('Run tests in TDD mode with local visual comparisons').argument('<command>', 'Test command to run').option('--port <port>', 'Port for screenshot server', '47392').option('--branch <branch>', 'Git branch override').option('--environment <env>', 'Environment name', 'test').option('--threshold <number>', 'Comparison threshold', parseFloat).option('--token <token>', 'API token override').option('--timeout <ms>', 'Server timeout in milliseconds', '30000').option('--baseline-build <id>', 'Use specific build as baseline').option('--baseline-comparison <id>', 'Use specific comparison as baseline').option('--set-baseline', 'Accept current screenshots as new baseline (overwrites existing)').option('--allow-no-token', 'Allow running without API token (no baselines)').action(async (command, options) => {
|
|
31
|
+
const globalOptions = program.opts();
|
|
32
|
+
|
|
33
|
+
// Validate options
|
|
34
|
+
const validationErrors = validateTddOptions(command, options);
|
|
35
|
+
if (validationErrors.length > 0) {
|
|
36
|
+
console.error('Validation errors:');
|
|
37
|
+
validationErrors.forEach(error => console.error(` - ${error}`));
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
await tddCommand(command, options, globalOptions);
|
|
41
|
+
});
|
|
42
|
+
program.command('run').description('Run tests with Vizzly integration').argument('<command>', 'Test command to run').option('--tdd', 'Enable TDD mode with auto-reload').option('--port <port>', 'Port for screenshot server', '47392').option('-b, --build-name <name>', 'Custom build name').option('--branch <branch>', 'Git branch override').option('--commit <sha>', 'Git commit SHA').option('--message <msg>', 'Commit message').option('--environment <env>', 'Environment name', 'test').option('--threshold <number>', 'Comparison threshold', parseFloat).option('--token <token>', 'API token override').option('--wait', 'Wait for build completion').option('--timeout <ms>', 'Server timeout in milliseconds', '30000').option('--eager', 'Create build immediately (default: lazy)').option('--allow-no-token', 'Allow running without API token').option('--baseline-build <id>', 'Use specific build as baseline').option('--baseline-comparison <id>', 'Use specific comparison as baseline').action(async (command, options) => {
|
|
43
|
+
const globalOptions = program.opts();
|
|
44
|
+
|
|
45
|
+
// Forward --tdd flag to TDD command (shortcut)
|
|
46
|
+
if (options.tdd) {
|
|
47
|
+
// Forward to tdd command with appropriate options
|
|
48
|
+
const tddOptions = {
|
|
49
|
+
port: options.port,
|
|
50
|
+
branch: options.branch,
|
|
51
|
+
environment: options.environment,
|
|
52
|
+
threshold: options.threshold,
|
|
53
|
+
token: options.token,
|
|
54
|
+
timeout: options.timeout,
|
|
55
|
+
baselineBuild: options.baselineBuild,
|
|
56
|
+
baselineComparison: options.baselineComparison,
|
|
57
|
+
allowNoToken: options.allowNoToken
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Validate options using TDD validator
|
|
61
|
+
const validationErrors = validateTddOptions(command, tddOptions);
|
|
62
|
+
if (validationErrors.length > 0) {
|
|
63
|
+
console.error('Validation errors:');
|
|
64
|
+
validationErrors.forEach(error => console.error(` - ${error}`));
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
await tddCommand(command, tddOptions, globalOptions);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Validate options
|
|
72
|
+
const validationErrors = validateRunOptions(command, options);
|
|
73
|
+
if (validationErrors.length > 0) {
|
|
74
|
+
console.error('Validation errors:');
|
|
75
|
+
validationErrors.forEach(error => console.error(` - ${error}`));
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
await runCommand(command, options, globalOptions);
|
|
79
|
+
});
|
|
80
|
+
program.command('status').description('Check the status of a build').argument('<build-id>', 'Build ID to check status for').action(async (buildId, options) => {
|
|
81
|
+
const globalOptions = program.opts();
|
|
82
|
+
|
|
83
|
+
// Validate options
|
|
84
|
+
const validationErrors = validateStatusOptions(buildId, options);
|
|
85
|
+
if (validationErrors.length > 0) {
|
|
86
|
+
console.error('Validation errors:');
|
|
87
|
+
validationErrors.forEach(error => console.error(` - ${error}`));
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
await statusCommand(buildId, options, globalOptions);
|
|
91
|
+
});
|
|
92
|
+
program.command('doctor').description('Run diagnostics to check your environment and configuration').option('--api', 'Include API connectivity checks').action(async options => {
|
|
93
|
+
const globalOptions = program.opts();
|
|
94
|
+
|
|
95
|
+
// Validate options
|
|
96
|
+
const validationErrors = validateDoctorOptions(options);
|
|
97
|
+
if (validationErrors.length > 0) {
|
|
98
|
+
console.error('Validation errors:');
|
|
99
|
+
validationErrors.forEach(error => console.error(` - ${error}`));
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
await doctorCommand(options, globalOptions);
|
|
103
|
+
});
|
|
104
|
+
program.parse();
|