@percy/core 1.14.0 → 1.15.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/dist/config.js CHANGED
@@ -396,11 +396,47 @@ export const snapshotSchema = {
396
396
  name: {
397
397
  type: 'string'
398
398
  },
399
- domSnapshot: {
400
- type: 'string'
401
- },
402
399
  width: {
403
400
  $ref: '/config/snapshot#/properties/widths/items'
401
+ },
402
+ domSnapshot: {
403
+ oneOf: [{
404
+ type: 'string'
405
+ }, {
406
+ type: 'object',
407
+ required: ['html'],
408
+ unevaluatedProperties: false,
409
+ properties: {
410
+ html: {
411
+ type: 'string'
412
+ },
413
+ warnings: {
414
+ type: 'array',
415
+ items: {
416
+ type: 'string'
417
+ }
418
+ },
419
+ resources: {
420
+ type: 'array',
421
+ items: {
422
+ type: 'object',
423
+ required: ['url', 'content', 'mimetype'],
424
+ unevaluatedProperties: false,
425
+ properties: {
426
+ url: {
427
+ type: 'string'
428
+ },
429
+ content: {
430
+ type: 'string'
431
+ },
432
+ mimetype: {
433
+ type: 'string'
434
+ }
435
+ }
436
+ }
437
+ }
438
+ }
439
+ }]
404
440
  }
405
441
  },
406
442
  errors: {
@@ -514,12 +550,13 @@ export const comparisonSchema = {
514
550
  },
515
551
  width: {
516
552
  type: 'integer',
517
- maximum: 2000,
518
- minimum: 120
553
+ minimum: 1,
554
+ maximum: 10000
519
555
  },
520
556
  height: {
521
557
  type: 'integer',
522
- minimum: 10
558
+ minimum: 1,
559
+ maximum: 10000
523
560
  },
524
561
  orientation: {
525
562
  type: 'string',
package/dist/discovery.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import logger from '@percy/logger';
2
2
  import Queue from './queue.js';
3
- import { normalizeURL, hostnameMatches, createRootResource, createPercyCSSResource, createLogResource, yieldAll } from './utils.js';
3
+ import { normalizeURL, hostnameMatches, createResource, createRootResource, createPercyCSSResource, createLogResource, yieldAll } from './utils.js';
4
4
 
5
5
  // Logs verbose debug logs detailing various snapshot options.
6
6
  function debugSnapshotOptions(snapshot) {
@@ -58,6 +58,39 @@ function waitForDiscoveryNetworkIdle(page, options) {
58
58
  return page.network.idle(filter, networkIdleTimeout);
59
59
  }
60
60
 
61
+ // Creates an initial resource map for a snapshot containing serialized DOM
62
+ function parseDomResources({
63
+ url,
64
+ domSnapshot
65
+ }) {
66
+ if (!domSnapshot) return new Map();
67
+ let isHTML = typeof domSnapshot === 'string';
68
+ let {
69
+ html,
70
+ resources = []
71
+ } = isHTML ? {
72
+ html: domSnapshot
73
+ } : domSnapshot;
74
+ let rootResource = createRootResource(url, html);
75
+
76
+ // reduce the array of resources into a keyed map
77
+ return resources.reduce((map, {
78
+ url,
79
+ content,
80
+ mimetype
81
+ }) => {
82
+ // serialized resource contents are base64 encoded
83
+ content = Buffer.from(content, 'base64');
84
+ // specify the resource as provided to prevent overwriting during asset discovery
85
+ let resource = createResource(url, content, mimetype, {
86
+ provided: true
87
+ });
88
+ // key the resource by its url and return the map
89
+ return map.set(resource.url, resource);
90
+ // the initial map is created with at least a root resource
91
+ }, new Map([[rootResource.url, rootResource]]));
92
+ }
93
+
61
94
  // Calls the provided callback with additional resources
62
95
  function processSnapshotResources({
63
96
  domSnapshot,
@@ -67,11 +100,18 @@ function processSnapshotResources({
67
100
  var _resources;
68
101
  resources = [...(((_resources = resources) === null || _resources === void 0 ? void 0 : _resources.values()) ?? [])];
69
102
 
70
- // find or create a root resource if one does not exist
71
- let root = resources.find(r => r.content === domSnapshot);
103
+ // find any root resource matching the provided dom snapshot
104
+ let rootContent = (domSnapshot === null || domSnapshot === void 0 ? void 0 : domSnapshot.html) ?? domSnapshot;
105
+ let root = resources.find(r => r.content === rootContent);
106
+
107
+ // initialize root resources if needed
72
108
  if (!root) {
73
- root = createRootResource(snapshot.url, domSnapshot);
74
- resources.unshift(root);
109
+ let domResources = parseDomResources({
110
+ ...snapshot,
111
+ domSnapshot
112
+ });
113
+ resources = [...domResources.values(), ...resources];
114
+ root = resources[0];
75
115
  }
76
116
 
77
117
  // inject Percy CSS
@@ -247,14 +287,9 @@ export function createDiscoveryQueue(percy) {
247
287
  name,
248
288
  widths
249
289
  }, snapshot) => snapshot.name === name && (!percy.deferUploads || !widths || widths.join() === snapshot.widths.join()))
250
- // initialize the root resource for DOM snapshots
290
+ // initialize the resources for DOM snapshots
251
291
  .handle('push', snapshot => {
252
- let {
253
- url,
254
- domSnapshot
255
- } = snapshot;
256
- let root = domSnapshot && createRootResource(url, domSnapshot);
257
- let resources = new Map(root ? [[root.url, root]] : []);
292
+ let resources = parseDomResources(snapshot);
258
293
  return {
259
294
  ...snapshot,
260
295
  resources
package/dist/network.js CHANGED
@@ -290,7 +290,7 @@ async function sendResponseResource(network, request, session) {
290
290
  requestId: request.interceptId,
291
291
  errorReason: 'Aborted'
292
292
  });
293
- } else if (resource && (resource.root || !disableCache)) {
293
+ } else if (resource && (resource.root || resource.provided || !disableCache)) {
294
294
  log.debug(resource.root ? '- Serving root resource' : '- Resource cache hit', meta);
295
295
  await session.send('Fetch.fulfillRequest', {
296
296
  requestId: request.interceptId,
@@ -356,7 +356,7 @@ async function saveResponseResource(network, request) {
356
356
  url
357
357
  };
358
358
  let resource = network.intercept.getResource(url);
359
- if (!resource || !resource.root && disableCache) {
359
+ if (!resource || !resource.root && !resource.provided && disableCache) {
360
360
  try {
361
361
  log.debug(`Processing resource: ${url}`, meta);
362
362
  let shouldCapture = response && hostnameMatches(allowedHostnames, url);
package/dist/snapshot.js CHANGED
@@ -163,7 +163,9 @@ function getSnapshotOptions(options, {
163
163
  // properties. Eagerly throws an error when missing a URL for any snapshot, and warns about all
164
164
  // other invalid options which are also scrubbed from the returned migrated options.
165
165
  export function validateSnapshotOptions(options) {
166
- var _migrated$baseUrl;
166
+ var _migrated$baseUrl, _migrated$domSnapshot;
167
+ let log = logger('core:snapshot');
168
+
167
169
  // decide which schema to validate against
168
170
  let schema = ['domSnapshot', 'dom-snapshot', 'dom_snapshot'].some(k => k in options) && '/snapshot/dom' || 'url' in options && '/snapshot' || 'sitemap' in options && '/snapshot/sitemap' || 'serve' in options && '/snapshot/server' || 'snapshots' in options && '/snapshot/list' || '/snapshot';
169
171
  let {
@@ -185,10 +187,22 @@ export function validateSnapshotOptions(options) {
185
187
 
186
188
  // add back snapshots before validating and scrubbing; function snapshots are validated later
187
189
  if (snapshots) migrated.snapshots = typeof snapshots === 'function' ? [] : snapshots;else if (!isSnapshot && options.snapshots) migrated.snapshots = [];
190
+
191
+ // parse json dom snapshots
192
+ if (schema === '/snapshot/dom' && typeof migrated.domSnapshot === 'string' && migrated.domSnapshot.startsWith('{') && migrated.domSnapshot.endsWith('}')) {
193
+ migrated.domSnapshot = JSON.parse(migrated.domSnapshot);
194
+ }
195
+
196
+ // log warnings encountered during dom serialization
197
+ let domWarnings = ((_migrated$domSnapshot = migrated.domSnapshot) === null || _migrated$domSnapshot === void 0 ? void 0 : _migrated$domSnapshot.warnings) || [];
198
+ if (domWarnings.length) {
199
+ log.warn('Encountered snapshot serialization warnings:');
200
+ for (let w of domWarnings) log.warn(`- ${w}`);
201
+ }
202
+
203
+ // warn on validation errors
188
204
  let errors = PercyConfig.validate(migrated, schema);
189
205
  if (errors) {
190
- // warn on validation errors
191
- let log = logger('core:snapshot');
192
206
  log.warn('Invalid snapshot options:');
193
207
  for (let e of errors) log.warn(`- ${e.path}: ${e.message}`);
194
208
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@percy/core",
3
- "version": "1.14.0",
3
+ "version": "1.15.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -39,10 +39,10 @@
39
39
  "test:types": "tsd"
40
40
  },
41
41
  "dependencies": {
42
- "@percy/client": "1.14.0",
43
- "@percy/config": "1.14.0",
44
- "@percy/dom": "1.14.0",
45
- "@percy/logger": "1.14.0",
42
+ "@percy/client": "1.15.0",
43
+ "@percy/config": "1.15.0",
44
+ "@percy/dom": "1.15.0",
45
+ "@percy/logger": "1.15.0",
46
46
  "content-disposition": "^0.5.4",
47
47
  "cross-spawn": "^7.0.3",
48
48
  "extract-zip": "^2.0.1",
@@ -53,5 +53,5 @@
53
53
  "rimraf": "^3.0.2",
54
54
  "ws": "^8.0.0"
55
55
  },
56
- "gitHead": "fd72688e449d6dd3eafd346fc07879cb3bb01a4e"
56
+ "gitHead": "383ce2888d2e4fe6972368f9bbe8580b23431a98"
57
57
  }