@percy/dom 1.31.1-beta.2 → 1.31.2-beta.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.
Files changed (2) hide show
  1. package/dist/bundle.js +55 -33
  2. package/package.json +2 -2
package/dist/bundle.js CHANGED
@@ -336,14 +336,50 @@
336
336
  }
337
337
  }
338
338
 
339
+ // Helper function to create and insert image element
340
+ function createAndInsertImageElement(canvas, clone, percyElementId, imageUrl) {
341
+ let img = document.createElement('img');
342
+
343
+ // copy canvas element attributes to the image element
344
+ for (let {
345
+ name,
346
+ value
347
+ } of canvas.attributes) {
348
+ img.setAttribute(name, value);
349
+ }
350
+
351
+ // mark the image as serialized and set src attribute
352
+ img.setAttribute('data-percy-canvas-serialized', '');
353
+ img.setAttribute('data-percy-serialized-attribute-src', imageUrl);
354
+
355
+ // set a default max width to account for canvases that might resize with JS
356
+ img.style.maxWidth = img.style.maxWidth || '100%';
357
+
358
+ // insert the image into the cloned DOM and remove the cloned canvas element
359
+ let cloneEl = clone.querySelector(`[data-percy-element-id=${percyElementId}]`);
360
+ if (!cloneEl) {
361
+ throw new Error(`Clone element not found for percy-element-id: ${percyElementId}`);
362
+ }
363
+
364
+ // `parentElement` for elements directly under shadow root is `null` -> Incase of Nested Shadow DOM.
365
+ if (cloneEl.parentElement) {
366
+ cloneEl.parentElement.insertBefore(img, cloneEl);
367
+ } else {
368
+ clone.insertBefore(img, cloneEl);
369
+ }
370
+ cloneEl.remove();
371
+ }
372
+
339
373
  // Serialize in-memory canvas elements into images.
340
374
  function serializeCanvas(ctx) {
341
375
  let {
342
376
  dom,
343
377
  clone,
344
- resources
378
+ resources,
379
+ ignoreCanvasSerializationErrors
345
380
  } = ctx;
346
381
  for (let canvas of dom.querySelectorAll('canvas')) {
382
+ let percyElementId = canvas.getAttribute('data-percy-element-id');
347
383
  try {
348
384
  // Note: the `.toDataURL` API requires WebGL canvas elements to use
349
385
  // `preserveDrawingBuffer: true`. This is because `.toDataURL` uses the
@@ -353,41 +389,25 @@
353
389
  // skip empty canvases
354
390
  if (!dataUrl || dataUrl === 'data:,') continue;
355
391
 
356
- // get the element's percy id and create a resource for it
357
- let percyElementId = canvas.getAttribute('data-percy-element-id');
392
+ // create a resource for the canvas data
358
393
  let resource = resourceFromDataURL(percyElementId, dataUrl);
359
394
  resources.add(resource);
360
395
 
361
- // create an image element in the cloned dom
362
- let img = document.createElement('img');
363
- // use a data attribute to avoid making a real request
364
- img.setAttribute('data-percy-serialized-attribute-src', resource.url);
365
-
366
- // copy canvas element attributes to the image element such as style, class,
367
- // or data attributes that may be targeted by CSS
368
- for (let {
369
- name,
370
- value
371
- } of canvas.attributes) {
372
- img.setAttribute(name, value);
373
- }
374
-
375
- // mark the image as serialized (can be targeted by CSS)
376
- img.setAttribute('data-percy-canvas-serialized', '');
377
- // set a default max width to account for canvases that might resize with JS
378
- img.style.maxWidth = img.style.maxWidth || '100%';
379
-
380
- // insert the image into the cloned DOM and remove the cloned canvas element
381
- let cloneEl = clone.querySelector(`[data-percy-element-id=${percyElementId}]`);
382
- // `parentElement` for elements directly under shadow root is `null` -> Incase of Nested Shadow DOM.
383
- if (cloneEl.parentElement) {
384
- cloneEl.parentElement.insertBefore(img, cloneEl);
396
+ // create and insert image element with the resource URL
397
+ createAndInsertImageElement(canvas, clone, percyElementId, resource.url);
398
+ } catch (err) {
399
+ if (ignoreCanvasSerializationErrors) {
400
+ try {
401
+ // create and insert image element with empty src
402
+ ctx.warnings.add('Canvas Serialization failed, Replaced canvas with empty Image');
403
+ ctx.warnings.add('Error: ' + err.message);
404
+ createAndInsertImageElement(canvas, clone, percyElementId, '');
405
+ } catch (fallbackErr) {
406
+ ctx.warnings.add('Error creating fallback image element: ' + fallbackErr.message);
407
+ }
385
408
  } else {
386
- clone.insertBefore(img, cloneEl);
409
+ handleErrors(err, 'Error serializing canvas element: ', canvas);
387
410
  }
388
- cloneEl.remove();
389
- } catch (err) {
390
- handleErrors(err, 'Error serializing canvas element: ', canvas);
391
411
  }
392
412
  }
393
413
  }
@@ -729,7 +749,8 @@
729
749
  domTransformation = options === null || options === void 0 ? void 0 : options.dom_transformation,
730
750
  stringifyResponse = options === null || options === void 0 ? void 0 : options.stringify_response,
731
751
  disableShadowDOM = options === null || options === void 0 ? void 0 : options.disable_shadow_dom,
732
- reshuffleInvalidTags = options === null || options === void 0 ? void 0 : options.reshuffle_invalid_tags
752
+ reshuffleInvalidTags = options === null || options === void 0 ? void 0 : options.reshuffle_invalid_tags,
753
+ ignoreCanvasSerializationErrors = options === null || options === void 0 ? void 0 : options.ignore_canvas_serialization_errors
733
754
  } = options || {};
734
755
 
735
756
  // keep certain records throughout serialization
@@ -740,7 +761,8 @@
740
761
  cache: new Map(),
741
762
  shadowRootElements: [],
742
763
  enableJavaScript,
743
- disableShadowDOM
764
+ disableShadowDOM,
765
+ ignoreCanvasSerializationErrors
744
766
  };
745
767
  ctx.dom = dom;
746
768
  ctx.clone = cloneNodeAndShadow(ctx);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@percy/dom",
3
- "version": "1.31.1-beta.2",
3
+ "version": "1.31.2-beta.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,5 +35,5 @@
35
35
  "devDependencies": {
36
36
  "interactor.js": "^2.0.0-beta.10"
37
37
  },
38
- "gitHead": "809b770761a7a5ad0044e462218452e920a4d1f0"
38
+ "gitHead": "6d36e464efaa1261bf1f1e7c7302c64cc85eccc7"
39
39
  }