@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.
@@ -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**: 1.1.0+
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**: 1.1.0
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capillarytech/cap-ui-dev-tools",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Development tools for Capillary UI projects including webpack hot-reload plugin and CapVision session recording",
5
5
  "main": "src/index.js",
6
6
  "exports": {
@@ -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 only if test failed
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 (!testPassed) {
749
- // Only save permanently if test failed
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,