@vizzly-testing/honeydiff 0.1.1 → 0.2.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/README.md CHANGED
@@ -10,6 +10,7 @@ validation, and detecting visual changes.
10
10
  **Why Honeydiff?**
11
11
  - **Fast:** Native performance processing 230M+ pixels/sec
12
12
  - **Smart:** Intelligent anti-aliasing detection filters rendering artifacts
13
+ - **Accessible:** Built-in WCAG contrast checking and color blindness simulation
13
14
  - **Flexible:** File paths or Buffers, async or sync APIs
14
15
  - **Complete:** TypeScript types, pre-built binaries for all platforms
15
16
  - **Advanced:** SSIM perceptual scoring, spatial clustering, variable-height screenshots
@@ -92,6 +93,9 @@ interface CompareOptions {
92
93
  includeDiffPixels?: boolean; // Detailed pixel list (default: false)
93
94
  includeClusters?: boolean; // Spatial clusters (default: false)
94
95
  includeSSIM?: boolean; // SSIM score (default: false)
96
+ includeAccessibilityData?: boolean; // RGB, luminance, WCAG (default: false)
97
+ checkColorBlindness?: boolean; // Color blindness simulation (default: false)
98
+ colorBlindnessThreshold?: number; // Visibility threshold 0-255 (default: 30)
95
99
  diffPath?: string; // Save diff image
96
100
  maskPath?: string; // Save mask image
97
101
  overlayPath?: string; // Save overlay image
@@ -194,6 +198,53 @@ if (result.intensityStats) {
194
198
  // Output: Range: 12-255, Mean: 87.3
195
199
  ```
196
200
 
201
+ **Accessibility Features**
202
+
203
+ ```javascript
204
+ // WCAG contrast checking and RGB analysis
205
+ let result = await compare('baseline.png', 'current.png', {
206
+ includeClusters: true,
207
+ includeAccessibilityData: true
208
+ });
209
+
210
+ if (result.diffClusters) {
211
+ result.diffClusters.forEach(cluster => {
212
+ if (cluster.accessibilityMetadata) {
213
+ let meta = cluster.accessibilityMetadata;
214
+ console.log(`RGB diffs: R=${meta.avgRDiff}, G=${meta.avgGDiff}, B=${meta.avgBDiff}`);
215
+ console.log(`Dominant channel: ${meta.dominantChannel}`);
216
+ console.log(`WCAG contrast: ${meta.contrastRatio.toFixed(2)}:1`);
217
+
218
+ if (meta.contrastRatio < 4.5) {
219
+ console.log('⚠️ Below WCAG AA threshold');
220
+ }
221
+ }
222
+ });
223
+ }
224
+
225
+ // Color blindness simulation
226
+ let result = await compare('baseline.png', 'current.png', {
227
+ includeClusters: true,
228
+ checkColorBlindness: true
229
+ });
230
+
231
+ if (result.diffClusters) {
232
+ result.diffClusters.forEach(cluster => {
233
+ if (cluster.accessibilityMetadata?.colorBlindnessImpact) {
234
+ let impact = cluster.accessibilityMetadata.colorBlindnessImpact;
235
+ console.log(`Visibility score: ${(impact.visibilityScore * 100).toFixed(0)}%`);
236
+ console.log(`Deuteranopia (red-green): ${impact.deuteranopiaVisible ? '✓' : '✗'}`);
237
+ console.log(`Protanopia (red-weak): ${impact.protanopiaVisible ? '✓' : '✗'}`);
238
+ console.log(`Tritanopia (blue-yellow): ${impact.tritanopiaVisible ? '✓' : '✗'}`);
239
+
240
+ if (impact.visibilityScore < 0.5) {
241
+ console.log('⚠️ May not be visible to colorblind users');
242
+ }
243
+ }
244
+ });
245
+ }
246
+ ```
247
+
197
248
  **Complete Result Example**
198
249
  ```javascript
199
250
  let result = await compare('baseline.png', 'current.png', {
@@ -254,6 +305,7 @@ console.log(JSON.stringify(result, null, 2));
254
305
 
255
306
  - **Visual Regression Testing:** Detect unintended UI changes in your test suite
256
307
  - **Screenshot Validation:** Compare generated screenshots against baselines
308
+ - **Accessibility Testing:** Validate WCAG contrast ratios and color blindness visibility
257
309
  - **Design QA:** Validate UI implementations match designs
258
310
  - **Cross-browser Testing:** Detect rendering differences across browsers
259
311
  - **Scrollable Content:** Compare full-page screenshots with variable heights
@@ -273,6 +325,13 @@ Tested on real-world tall screenshots (750 x 24,162 pixels = 18.3M pixels):
273
325
 
274
326
  ## Advanced Features
275
327
 
328
+ **Accessibility Testing**
329
+ - **RGB Channel Analysis:** Track which color channels changed (R/G/B)
330
+ - **Luminance Tracking:** Measure perceived brightness using sRGB relative luminance
331
+ - **WCAG Contrast Ratios:** Validate contrast meets AA (4.5:1) and AAA (7:1) standards
332
+ - **Color Blindness Simulation:** Test visibility for deuteranopia, protanopia, tritanopia, and achromatopsia
333
+ - **Visibility Scoring:** 0-100% score indicating how visible changes are to colorblind users
334
+
276
335
  **Variable Height Screenshots**
277
336
  Compare scrollable content with different heights. Overlapping regions are compared pixel-by-pixel,
278
337
  extra rows counted as differences.
package/index.d.ts CHANGED
@@ -49,6 +49,42 @@ export interface IntensityStats {
49
49
  stdDev: number;
50
50
  }
51
51
 
52
+ export interface ColorBlindnessImpact {
53
+ /** Whether the difference is visible to people with deuteranopia (red-green color blindness) */
54
+ deuteranopiaVisible: boolean;
55
+ /** Whether the difference is visible to people with protanopia (red-weak color blindness) */
56
+ protanopiaVisible: boolean;
57
+ /** Whether the difference is visible to people with tritanopia (blue-yellow color blindness) */
58
+ tritanopiaVisible: boolean;
59
+ /** Whether the difference is visible to people with achromatopsia (complete color blindness) */
60
+ achromatopsiaVisible: boolean;
61
+ /** Overall visibility score (0.0-1.0, higher = more visible) */
62
+ visibilityScore: number;
63
+ }
64
+
65
+ export interface AccessibilityMetadata {
66
+ /** Average difference in red channel (0-255) */
67
+ avgRDiff: number;
68
+ /** Average difference in green channel (0-255) */
69
+ avgGDiff: number;
70
+ /** Average difference in blue channel (0-255) */
71
+ avgBDiff: number;
72
+ /** Dominant color channel ('R', 'G', or 'B') */
73
+ dominantChannel: string;
74
+ /** Average relative luminance of baseline pixels (0.0-1.0, sRGB) */
75
+ avgBaselineLuminance: number;
76
+ /** Average relative luminance of current pixels (0.0-1.0, sRGB) */
77
+ avgCurrentLuminance: number;
78
+ /** WCAG contrast ratio between average colors (1.0-21.0, values below 4.5 may fail WCAG AA) */
79
+ contrastRatio: number;
80
+ /** Minimum WCAG contrast ratio in this cluster (worst case) */
81
+ minContrastRatio: number;
82
+ /** Maximum WCAG contrast ratio in this cluster (best case) */
83
+ maxContrastRatio: number;
84
+ /** Color blindness visibility analysis (null unless checkColorBlindness is enabled) */
85
+ colorBlindnessImpact: ColorBlindnessImpact | null;
86
+ }
87
+
52
88
  export interface DiffCluster {
53
89
  /** Number of pixels in this cluster */
54
90
  pixelCount: number;
@@ -58,6 +94,8 @@ export interface DiffCluster {
58
94
  avgIntensity: number;
59
95
  /** Bounding box containing this cluster */
60
96
  boundingBox: BoundingBox;
97
+ /** Accessibility metadata (null unless includeAccessibilityData is enabled) */
98
+ accessibilityMetadata: AccessibilityMetadata | null;
61
99
  }
62
100
 
63
101
  export interface DiffResult {
@@ -170,6 +208,28 @@ export interface CompareOptions {
170
208
  * @default false
171
209
  */
172
210
  overwrite?: boolean;
211
+
212
+ /**
213
+ * Include accessibility metadata (RGB channels, luminance, WCAG contrast)
214
+ * When enabled, each cluster will include detailed color and brightness analysis
215
+ * @default false
216
+ */
217
+ includeAccessibilityData?: boolean;
218
+
219
+ /**
220
+ * Check if differences are visible to color blind users
221
+ * Automatically enables includeAccessibilityData if not already enabled
222
+ * Tests visibility for deuteranopia, protanopia, tritanopia, and achromatopsia
223
+ * @default false
224
+ */
225
+ checkColorBlindness?: boolean;
226
+
227
+ /**
228
+ * Threshold for color blindness visibility detection (0-255)
229
+ * Differences below this threshold after color blindness simulation are considered invisible
230
+ * @default 30.0
231
+ */
232
+ colorBlindnessThreshold?: number;
173
233
  }
174
234
 
175
235
  // ============================================================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vizzly-testing/honeydiff",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "High-performance image diffing for Node.js - Native bindings to Honeydiff Rust library",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -60,6 +60,11 @@
60
60
  "index.d.ts",
61
61
  "load-platform.js",
62
62
  "platforms/*.node",
63
+ "README.md",
64
+ "index.js",
65
+ "index.d.ts",
66
+ "load-platform.js",
67
+ "platforms/*.node",
63
68
  "README.md"
64
69
  ],
65
70
  "engines": {