@capillarytech/cap-ui-dev-tools 2.0.0 → 2.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/CAPVISION_USAGE.md +68 -2
- package/README.md +23 -3
- package/package.json +1 -1
- package/src/capvision-recorder/core/CapVisionRecorder.js +18 -25
package/CAPVISION_USAGE.md
CHANGED
|
@@ -316,6 +316,72 @@ const enhancer = new ReportEnhancer({
|
|
|
316
316
|
await enhancer.enhanceAllReports();
|
|
317
317
|
```
|
|
318
318
|
|
|
319
|
+
## 🎬 Visual Regression Mode (v1.1.0+)
|
|
320
|
+
|
|
321
|
+
### Overview
|
|
322
|
+
|
|
323
|
+
By default, CapVision only saves recordings for **failed tests** to conserve disk space. Visual Regression Mode changes this behavior to save recordings for **all tests** (pass or fail), enabling on-demand visual verification of the application.
|
|
324
|
+
|
|
325
|
+
### Configuration
|
|
326
|
+
|
|
327
|
+
Enable visual regression by setting `saveAllRecordings: true`:
|
|
328
|
+
|
|
329
|
+
```javascript
|
|
330
|
+
const capVisionHooks = createWDIOCapVisionHooks({
|
|
331
|
+
ENABLE_FEATURE: true,
|
|
332
|
+
saveAllRecordings: true, // 👈 Save recordings for ALL tests
|
|
333
|
+
enabledClusters: ['crm-nightly-new'],
|
|
334
|
+
enabledModules: ['creatives'],
|
|
335
|
+
enabledTestTypes: ['sanity', 'regression']
|
|
336
|
+
});
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Environment Variable Integration
|
|
340
|
+
|
|
341
|
+
For on-demand usage, drive `saveAllRecordings` from an environment variable:
|
|
342
|
+
|
|
343
|
+
```javascript
|
|
344
|
+
const isVisualRegression = process.env.VISUAL_REGRESSION === 'true';
|
|
345
|
+
|
|
346
|
+
const capVisionHooks = createWDIOCapVisionHooks({
|
|
347
|
+
ENABLE_FEATURE: process.env.ENABLE_RECORDING === 'true' || isVisualRegression,
|
|
348
|
+
saveAllRecordings: isVisualRegression,
|
|
349
|
+
enabledTestTypes: ['sanity', 'regression'],
|
|
350
|
+
// ... other config
|
|
351
|
+
});
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Then run with:
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
VISUAL_REGRESSION=true ENABLE_RECORDING=true npx wdio test/wdio.conf.ts --suite visual-regression
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Behavior Comparison
|
|
361
|
+
|
|
362
|
+
| Scenario | `saveAllRecordings` | Passed Tests | Failed Tests |
|
|
363
|
+
|---|---|---|---|
|
|
364
|
+
| Default mode | `false` | ❌ Not saved | ✅ Saved |
|
|
365
|
+
| Visual regression mode | `true` | ✅ Saved | ✅ Saved |
|
|
366
|
+
|
|
367
|
+
### Console Logging
|
|
368
|
+
|
|
369
|
+
When visual regression mode is active, you'll see:
|
|
370
|
+
|
|
371
|
+
```
|
|
372
|
+
🟡 CapVision visual regression mode active — all recordings will be saved regardless of test result
|
|
373
|
+
🟡 Saving CapVision recording (visual regression mode): Testcase_my_test_flow
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### Best Practices
|
|
377
|
+
|
|
378
|
+
1. **Run on-demand only** — Visual regression creates recordings for every test, which uses more disk space
|
|
379
|
+
2. **Use for regression suites** — Point the `visual-regression` suite to your regression test files
|
|
380
|
+
3. **Review recordings in HTML reports** — Open `reports/html-reports/master-report.html` after the run
|
|
381
|
+
4. **Clean up after review** — Old recordings are auto-cleared on the next `onPrepare` call
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
319
385
|
## 🐛 Troubleshooting
|
|
320
386
|
|
|
321
387
|
### No Recordings Created
|
|
@@ -482,7 +548,7 @@ ISC License - Part of @capillarytech/cap-ui-dev-tools
|
|
|
482
548
|
|
|
483
549
|
---
|
|
484
550
|
|
|
485
|
-
**Version**:
|
|
486
|
-
**Module**: `@capillarytech/cap-ui-dev-tools/capvision`
|
|
551
|
+
**Version**: 2.1.0+
|
|
552
|
+
**Module**: `@capillarytech/cap-ui-dev-tools/capvision`
|
|
487
553
|
**Compatibility**: WebdriverIO 7.x, 8.x+
|
|
488
554
|
|
package/README.md
CHANGED
|
@@ -54,7 +54,14 @@ const path = require('path');
|
|
|
54
54
|
|
|
55
55
|
module.exports = {
|
|
56
56
|
mode: 'development',
|
|
57
|
-
|
|
57
|
+
// ... your other webpack config
|
|
58
|
+
|
|
59
|
+
// NO need for a separate resolve.alias block for local development!
|
|
60
|
+
// The plugin handles it for you.
|
|
61
|
+
resolve: {
|
|
62
|
+
// ... any other aliases can stay here
|
|
63
|
+
},
|
|
64
|
+
|
|
58
65
|
plugins: [
|
|
59
66
|
new webpack.HotModuleReplacementPlugin(),
|
|
60
67
|
|
|
@@ -126,6 +133,7 @@ exports.config = {
|
|
|
126
133
|
- ✅ **Console Recording** - Captures console logs with UI interactions
|
|
127
134
|
- ✅ **Privacy First** - Auto-masks sensitive inputs
|
|
128
135
|
- ✅ **Framework Agnostic Core** - Works with WebdriverIO, Playwright, Puppeteer
|
|
136
|
+
- ✅ **Visual Regression Mode** _(v1.1.0)_ - Record ALL tests (pass/fail) for visual verification
|
|
129
137
|
|
|
130
138
|
### Full Documentation
|
|
131
139
|
|
|
@@ -206,6 +214,18 @@ See [CAPVISION_USAGE.md](./CAPVISION_USAGE.md#troubleshooting) for common issues
|
|
|
206
214
|
|
|
207
215
|
## 📝 Changelog
|
|
208
216
|
|
|
217
|
+
### v1.1.0 (2026-02-07)
|
|
218
|
+
- ✨ **NEW**: Visual Regression Mode — `saveAllRecordings` config option
|
|
219
|
+
- ✅ Records ALL tests (pass and fail) when `saveAllRecordings: true`
|
|
220
|
+
- ✅ On-demand visual regression suite support for module-level recording
|
|
221
|
+
- ✅ Automatic mode detection via `VISUAL_REGRESSION` environment variable
|
|
222
|
+
- ✅ Enhanced logging for visual regression mode status
|
|
223
|
+
- 📚 Updated documentation with visual regression usage guide
|
|
224
|
+
|
|
225
|
+
### v2.0.0 (2025-12-20)
|
|
226
|
+
- ✅ Major version bump with package restructuring
|
|
227
|
+
- ✅ Updated dependencies
|
|
228
|
+
|
|
209
229
|
### v1.1.0 (2025-11-12)
|
|
210
230
|
- ✨ **NEW**: Added CapVision session recording module
|
|
211
231
|
- ✅ Support for automatic test recording
|
|
@@ -272,5 +292,5 @@ ISC License
|
|
|
272
292
|
|
|
273
293
|
**Made with ❤️ by Capillary Technologies**
|
|
274
294
|
|
|
275
|
-
**Version**:
|
|
276
|
-
**Includes**: Webpack Hot-Reload Plugin + CapVision Session Recording
|
|
295
|
+
**Version**: 2.1.0
|
|
296
|
+
**Includes**: Webpack Hot-Reload Plugin + CapVision Session Recording + Visual Regression Mode
|
package/package.json
CHANGED
|
@@ -22,6 +22,7 @@ const os = require('os');
|
|
|
22
22
|
* @property {boolean} [collectFonts] - Collect custom fonts
|
|
23
23
|
* @property {boolean} [recordCrossOriginIframes] - Record cross-origin iframes
|
|
24
24
|
* @property {boolean} [useTempFile] - Use temporary file storage instead of sessionStorage
|
|
25
|
+
* @property {boolean} [saveAllRecordings] - When true, save recordings for ALL tests (pass or fail). Used for visual regression mode (default: false)
|
|
25
26
|
* @property {boolean} [recordConsole] - Enable console recording
|
|
26
27
|
* @property {Object} [consoleRecordOptions] - Console recording options
|
|
27
28
|
* @property {string[]} [consoleRecordOptions.level] - Console levels to record
|
|
@@ -40,12 +41,10 @@ const DEFAULT_CONFIG = {
|
|
|
40
41
|
enabledClusters: [],
|
|
41
42
|
enabledModules: [],
|
|
42
43
|
enabledTestTypes: ['smoke', 'sanity', 'regression'],
|
|
43
|
-
|
|
44
44
|
capVisionScriptPath: path.join(__dirname, '../assets/capvision.min.js'),
|
|
45
45
|
consoleRecordPluginPath: path.join(__dirname, '../assets/capvision-plugins/console-record.min.js'),
|
|
46
46
|
consoleReplayPluginPath: path.join(__dirname, '../assets/capvision-plugins/console-replay.min.js'),
|
|
47
47
|
recordingsOutputDir: path.join(process.cwd(), 'reports', 'recordings'),
|
|
48
|
-
|
|
49
48
|
sessionStorageKey: 'capvision_events',
|
|
50
49
|
saveIntervalMs: 60000,
|
|
51
50
|
checkoutIntervalMs: 30000,
|
|
@@ -56,7 +55,7 @@ const DEFAULT_CONFIG = {
|
|
|
56
55
|
collectFonts: true,
|
|
57
56
|
recordCrossOriginIframes: false,
|
|
58
57
|
useTempFile: true,
|
|
59
|
-
|
|
58
|
+
saveAllRecordings: false,
|
|
60
59
|
recordConsole: true,
|
|
61
60
|
consoleRecordOptions: {
|
|
62
61
|
level: ['log', 'info', 'warn', 'error'],
|
|
@@ -172,7 +171,6 @@ class CapVisionRecorder {
|
|
|
172
171
|
}
|
|
173
172
|
|
|
174
173
|
const cluster = currentCluster || process.env.cluster;
|
|
175
|
-
|
|
176
174
|
if (!cluster) {
|
|
177
175
|
return false;
|
|
178
176
|
}
|
|
@@ -192,13 +190,11 @@ class CapVisionRecorder {
|
|
|
192
190
|
}
|
|
193
191
|
|
|
194
192
|
const module = currentModule || process.env.module;
|
|
195
|
-
|
|
196
193
|
if (!module) {
|
|
197
194
|
return false;
|
|
198
195
|
}
|
|
199
196
|
|
|
200
197
|
const isEnabled = this.config.enabledModules.includes(module);
|
|
201
|
-
|
|
202
198
|
return isEnabled;
|
|
203
199
|
}
|
|
204
200
|
|
|
@@ -212,13 +208,11 @@ class CapVisionRecorder {
|
|
|
212
208
|
}
|
|
213
209
|
|
|
214
210
|
const currentTestType = this.getCurrentTestType();
|
|
215
|
-
|
|
216
211
|
if (!currentTestType) {
|
|
217
212
|
return false;
|
|
218
213
|
}
|
|
219
214
|
|
|
220
215
|
const isEnabled = this.config.enabledTestTypes.includes(currentTestType);
|
|
221
|
-
|
|
222
216
|
return isEnabled;
|
|
223
217
|
}
|
|
224
218
|
|
|
@@ -234,21 +228,23 @@ class CapVisionRecorder {
|
|
|
234
228
|
console.log('🟡 CapVision feature disabled (ENABLE_FEATURE=false)');
|
|
235
229
|
return false;
|
|
236
230
|
}
|
|
237
|
-
|
|
231
|
+
|
|
238
232
|
const clusterEnabled = this.isCapVisionEnabledForCluster(cluster);
|
|
239
233
|
const moduleEnabled = this.isCapVisionEnabledForModule(module);
|
|
240
234
|
const testTypeEnabled = this.isCapVisionEnabledForTestType();
|
|
241
|
-
|
|
235
|
+
|
|
242
236
|
const isEnabled = clusterEnabled && moduleEnabled && testTypeEnabled;
|
|
243
|
-
|
|
237
|
+
|
|
244
238
|
if (!isEnabled) {
|
|
245
239
|
const disabledReasons = [];
|
|
246
240
|
if (!clusterEnabled) disabledReasons.push('cluster');
|
|
247
241
|
if (!moduleEnabled) disabledReasons.push('module');
|
|
248
242
|
if (!testTypeEnabled) disabledReasons.push('test type');
|
|
249
243
|
console.log(`🟡 CapVision recording disabled (${disabledReasons.join(', ')} disabled)`);
|
|
244
|
+
} else if (this.config.saveAllRecordings) {
|
|
245
|
+
console.log('🟡 CapVision visual regression mode active — all recordings will be saved regardless of test result');
|
|
250
246
|
}
|
|
251
|
-
|
|
247
|
+
|
|
252
248
|
return isEnabled;
|
|
253
249
|
}
|
|
254
250
|
|
|
@@ -292,7 +288,6 @@ class CapVisionRecorder {
|
|
|
292
288
|
// Find existing recordings for this test
|
|
293
289
|
const existingFiles = fs.readdirSync(recordingsDir);
|
|
294
290
|
const testFilePattern = new RegExp(`^${sanitizedTestName}-(\\d+)\\.json$`);
|
|
295
|
-
|
|
296
291
|
let maxNumber = 0;
|
|
297
292
|
existingFiles.forEach((file) => {
|
|
298
293
|
const match = file.match(testFilePattern);
|
|
@@ -334,7 +329,6 @@ class CapVisionRecorder {
|
|
|
334
329
|
*/
|
|
335
330
|
createTempFile() {
|
|
336
331
|
const tempDir = path.join(os.tmpdir(), 'capvision-recordings');
|
|
337
|
-
|
|
338
332
|
if (!fs.existsSync(tempDir)) {
|
|
339
333
|
fs.mkdirSync(tempDir, { recursive: true });
|
|
340
334
|
}
|
|
@@ -440,7 +434,6 @@ class CapVisionRecorder {
|
|
|
440
434
|
window.capVisionInitialized = false;
|
|
441
435
|
window.capVisionLastCheckTime = Date.now();
|
|
442
436
|
window.capVisionEvents = [];
|
|
443
|
-
|
|
444
437
|
// Inject CapVision script
|
|
445
438
|
const injectScript = () => {
|
|
446
439
|
return new Promise((resolve) => {
|
|
@@ -567,7 +560,6 @@ class CapVisionRecorder {
|
|
|
567
560
|
window.rrwebRecorder = window.rrweb.record({
|
|
568
561
|
emit: (event) => {
|
|
569
562
|
window.capVisionEvents.push(event);
|
|
570
|
-
|
|
571
563
|
if (!config.useTempFile) {
|
|
572
564
|
saveEventsToStorage();
|
|
573
565
|
}
|
|
@@ -650,7 +642,6 @@ class CapVisionRecorder {
|
|
|
650
642
|
const events = await this.browserExecutor.execute(() => {
|
|
651
643
|
return window.capVisionEvents || [];
|
|
652
644
|
});
|
|
653
|
-
|
|
654
645
|
if (events && events.length > 0) {
|
|
655
646
|
this.saveToTempFile(events);
|
|
656
647
|
}
|
|
@@ -666,7 +657,7 @@ class CapVisionRecorder {
|
|
|
666
657
|
* Stop CapVision recording and save events
|
|
667
658
|
* @async
|
|
668
659
|
* @param {string} [testName='test'] - Name of the test for filename
|
|
669
|
-
* @param {boolean} [testPassed=true] - Whether the test passed. If true, recording is not saved permanently but temp file is still deleted
|
|
660
|
+
* @param {boolean} [testPassed=true] - Whether the test passed. If true and saveAllRecordings is false, recording is not saved permanently but temp file is still deleted. When saveAllRecordings is true (visual regression mode), recordings are saved regardless of test result.
|
|
670
661
|
* @returns {Promise<RecordingMetadata>} Recording metadata
|
|
671
662
|
* @throws {Error} If browser executor not set
|
|
672
663
|
*/
|
|
@@ -695,7 +686,6 @@ class CapVisionRecorder {
|
|
|
695
686
|
const finalEvents = await this.browserExecutor.execute(() => {
|
|
696
687
|
return window.capVisionEvents || [];
|
|
697
688
|
});
|
|
698
|
-
|
|
699
689
|
if (finalEvents && finalEvents.length > 0) {
|
|
700
690
|
this.saveToTempFile(finalEvents);
|
|
701
691
|
}
|
|
@@ -738,19 +728,23 @@ class CapVisionRecorder {
|
|
|
738
728
|
};
|
|
739
729
|
}, this.config);
|
|
740
730
|
|
|
741
|
-
// Save to permanent location
|
|
731
|
+
// Save to permanent location based on mode:
|
|
732
|
+
// - Visual regression mode (saveAllRecordings=true): save ALL recordings regardless of test result
|
|
733
|
+
// - Normal mode: save only if test failed
|
|
734
|
+
const shouldSave = this.config.saveAllRecordings || !testPassed;
|
|
742
735
|
let savedFilename = '';
|
|
743
736
|
if (this.config.useTempFile && metadata.totalEvents > 0) {
|
|
744
737
|
try {
|
|
745
738
|
const events = this.readFromTempFile();
|
|
746
|
-
|
|
739
|
+
|
|
747
740
|
if (events && events.length > 0) {
|
|
748
|
-
if (
|
|
749
|
-
|
|
741
|
+
if (shouldSave) {
|
|
742
|
+
const saveReason = this.config.saveAllRecordings ? 'visual regression mode' : 'test failed';
|
|
743
|
+
console.log(`🟡 Saving CapVision recording (${saveReason}): ${testName}`);
|
|
750
744
|
savedFilename = this.saveEventsToFile(events, testName);
|
|
751
745
|
}
|
|
752
746
|
}
|
|
753
|
-
|
|
747
|
+
|
|
754
748
|
// Always delete temp file regardless of test result
|
|
755
749
|
this.deleteTempFile();
|
|
756
750
|
} catch (error) {
|
|
@@ -763,7 +757,6 @@ class CapVisionRecorder {
|
|
|
763
757
|
}
|
|
764
758
|
}
|
|
765
759
|
}
|
|
766
|
-
|
|
767
760
|
return {
|
|
768
761
|
timestamp: metadata.timestamp,
|
|
769
762
|
totalEvents: metadata.totalEvents,
|