@percy/core 1.10.3 → 1.11.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/api.js +42 -4
- package/dist/config.js +106 -46
- package/dist/discovery.js +288 -126
- package/dist/network.js +165 -54
- package/dist/page.js +18 -9
- package/dist/percy.js +156 -279
- package/dist/queue.js +335 -99
- package/dist/snapshot.js +243 -277
- package/dist/utils.js +4 -1
- package/package.json +6 -6
package/dist/api.js
CHANGED
|
@@ -2,9 +2,15 @@ import fs from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { createRequire } from 'module';
|
|
4
4
|
import logger from '@percy/logger';
|
|
5
|
+
import { normalize } from '@percy/config/utils';
|
|
5
6
|
import { getPackageJSON, Server } from './utils.js'; // need require.resolve until import.meta.resolve can be transpiled
|
|
6
7
|
|
|
7
|
-
export const PERCY_DOM = createRequire(import.meta.url).resolve('@percy/dom'); //
|
|
8
|
+
export const PERCY_DOM = createRequire(import.meta.url).resolve('@percy/dom'); // Returns a URL encoded string of nested query params
|
|
9
|
+
|
|
10
|
+
function encodeURLSearchParams(subj, prefix) {
|
|
11
|
+
return typeof subj === 'object' ? Object.entries(subj).map(([key, value]) => encodeURLSearchParams(value, prefix ? `${prefix}[${key}]` : key)).join('&') : `${prefix}=${encodeURIComponent(subj)}`;
|
|
12
|
+
} // Create a Percy CLI API server instance
|
|
13
|
+
|
|
8
14
|
|
|
9
15
|
export function createPercyServer(percy, port) {
|
|
10
16
|
let pkg = getPackageJSON(import.meta.url);
|
|
@@ -71,7 +77,7 @@ export function createPercyServer(percy, port) {
|
|
|
71
77
|
});
|
|
72
78
|
}) // get or set config options
|
|
73
79
|
.route(['get', 'post'], '/percy/config', async (req, res) => res.json(200, {
|
|
74
|
-
config: req.body ?
|
|
80
|
+
config: req.body ? percy.set(req.body) : percy.config,
|
|
75
81
|
success: true
|
|
76
82
|
})) // responds once idle (may take a long time)
|
|
77
83
|
.route('get', '/percy/idle', async (req, res) => res.json(200, {
|
|
@@ -85,14 +91,46 @@ export function createPercyServer(percy, port) {
|
|
|
85
91
|
let content = await fs.promises.readFile(PERCY_DOM, 'utf-8');
|
|
86
92
|
let wrapper = '(window.PercyAgent = class { snapshot(n, o) { return PercyDOM.serialize(o); } });';
|
|
87
93
|
return res.send(200, 'applicaton/javascript', content.concat(wrapper));
|
|
88
|
-
}) // post one or more snapshots
|
|
94
|
+
}) // post one or more snapshots, optionally async
|
|
89
95
|
.route('post', '/percy/snapshot', async (req, res) => {
|
|
90
96
|
let snapshot = percy.snapshot(req.body);
|
|
91
97
|
if (!req.url.searchParams.has('async')) await snapshot;
|
|
92
98
|
return res.json(200, {
|
|
93
99
|
success: true
|
|
94
100
|
});
|
|
95
|
-
}) //
|
|
101
|
+
}) // post one or more comparisons, optionally waiting
|
|
102
|
+
.route('post', '/percy/comparison', async (req, res) => {
|
|
103
|
+
let upload = percy.upload(req.body);
|
|
104
|
+
if (req.url.searchParams.has('await')) await upload; // generate and include one or more redirect links to comparisons
|
|
105
|
+
|
|
106
|
+
let link = ({
|
|
107
|
+
name,
|
|
108
|
+
tag
|
|
109
|
+
}) => {
|
|
110
|
+
var _percy$build;
|
|
111
|
+
|
|
112
|
+
return [percy.client.apiUrl, '/comparisons/redirect?', encodeURLSearchParams(normalize({
|
|
113
|
+
buildId: (_percy$build = percy.build) === null || _percy$build === void 0 ? void 0 : _percy$build.id,
|
|
114
|
+
snapshot: {
|
|
115
|
+
name
|
|
116
|
+
},
|
|
117
|
+
tag
|
|
118
|
+
}, {
|
|
119
|
+
snake: true
|
|
120
|
+
}))].join('');
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
return res.json(200, Object.assign({
|
|
124
|
+
success: true
|
|
125
|
+
}, req.body ? Array.isArray(req.body) ? {
|
|
126
|
+
links: req.body.map(link)
|
|
127
|
+
} : {
|
|
128
|
+
link: link(req.body)
|
|
129
|
+
} : {}));
|
|
130
|
+
}) // flushes one or more snapshots from the internal queue
|
|
131
|
+
.route('post', '/percy/flush', async (req, res) => res.json(200, {
|
|
132
|
+
success: await percy.flush(req.body).then(() => true)
|
|
133
|
+
})) // stops percy at the end of the current event loop
|
|
96
134
|
.route('/percy/stop', (req, res) => {
|
|
97
135
|
setImmediate(() => percy.stop());
|
|
98
136
|
return res.json(200, {
|
package/dist/config.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
// Common config options used in Percy commands
|
|
2
2
|
export const configSchema = {
|
|
3
|
+
percy: {
|
|
4
|
+
type: 'object',
|
|
5
|
+
additionalProperties: false,
|
|
6
|
+
properties: {
|
|
7
|
+
deferUploads: {
|
|
8
|
+
type: 'boolean'
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
},
|
|
3
12
|
snapshot: {
|
|
4
13
|
type: 'object',
|
|
5
14
|
additionalProperties: false,
|
|
@@ -10,7 +19,7 @@ export const configSchema = {
|
|
|
10
19
|
items: {
|
|
11
20
|
type: 'integer',
|
|
12
21
|
maximum: 2000,
|
|
13
|
-
minimum:
|
|
22
|
+
minimum: 120
|
|
14
23
|
}
|
|
15
24
|
},
|
|
16
25
|
minHeight: {
|
|
@@ -28,9 +37,6 @@ export const configSchema = {
|
|
|
28
37
|
},
|
|
29
38
|
scope: {
|
|
30
39
|
type: 'string'
|
|
31
|
-
},
|
|
32
|
-
devicePixelRatio: {
|
|
33
|
-
type: 'integer'
|
|
34
40
|
}
|
|
35
41
|
}
|
|
36
42
|
},
|
|
@@ -129,6 +135,9 @@ export const configSchema = {
|
|
|
129
135
|
userAgent: {
|
|
130
136
|
type: 'string'
|
|
131
137
|
},
|
|
138
|
+
devicePixelRatio: {
|
|
139
|
+
type: 'integer'
|
|
140
|
+
},
|
|
132
141
|
concurrency: {
|
|
133
142
|
type: 'integer',
|
|
134
143
|
minimum: 1
|
|
@@ -180,9 +189,6 @@ export const snapshotSchema = {
|
|
|
180
189
|
enableJavaScript: {
|
|
181
190
|
$ref: '/config/snapshot#/properties/enableJavaScript'
|
|
182
191
|
},
|
|
183
|
-
devicePixelRatio: {
|
|
184
|
-
$ref: '/config/snapshot#/properties/devicePixelRatio'
|
|
185
|
-
},
|
|
186
192
|
discovery: {
|
|
187
193
|
type: 'object',
|
|
188
194
|
additionalProperties: false,
|
|
@@ -204,6 +210,9 @@ export const snapshotSchema = {
|
|
|
204
210
|
},
|
|
205
211
|
userAgent: {
|
|
206
212
|
$ref: '/config/discovery#/properties/userAgent'
|
|
213
|
+
},
|
|
214
|
+
devicePixelRatio: {
|
|
215
|
+
$ref: '/config/discovery#/properties/devicePixelRatio'
|
|
207
216
|
}
|
|
208
217
|
}
|
|
209
218
|
}
|
|
@@ -388,6 +397,9 @@ export const snapshotSchema = {
|
|
|
388
397
|
},
|
|
389
398
|
domSnapshot: {
|
|
390
399
|
type: 'string'
|
|
400
|
+
},
|
|
401
|
+
width: {
|
|
402
|
+
$ref: '/config/snapshot#/properties/widths/items'
|
|
391
403
|
}
|
|
392
404
|
},
|
|
393
405
|
errors: {
|
|
@@ -470,9 +482,87 @@ export const snapshotSchema = {
|
|
|
470
482
|
}
|
|
471
483
|
}
|
|
472
484
|
}
|
|
485
|
+
}; // Comparison upload options
|
|
486
|
+
|
|
487
|
+
export const comparisonSchema = {
|
|
488
|
+
type: 'object',
|
|
489
|
+
$id: '/comparison',
|
|
490
|
+
required: ['name', 'tag'],
|
|
491
|
+
additionalProperties: false,
|
|
492
|
+
properties: {
|
|
493
|
+
name: {
|
|
494
|
+
type: 'string'
|
|
495
|
+
},
|
|
496
|
+
externalDebugUrl: {
|
|
497
|
+
type: 'string'
|
|
498
|
+
},
|
|
499
|
+
tag: {
|
|
500
|
+
type: 'object',
|
|
501
|
+
additionalProperties: false,
|
|
502
|
+
required: ['name'],
|
|
503
|
+
properties: {
|
|
504
|
+
name: {
|
|
505
|
+
type: 'string'
|
|
506
|
+
},
|
|
507
|
+
osName: {
|
|
508
|
+
type: 'string'
|
|
509
|
+
},
|
|
510
|
+
osVersion: {
|
|
511
|
+
type: 'string'
|
|
512
|
+
},
|
|
513
|
+
width: {
|
|
514
|
+
type: 'integer',
|
|
515
|
+
maximum: 2000,
|
|
516
|
+
minimum: 120
|
|
517
|
+
},
|
|
518
|
+
height: {
|
|
519
|
+
type: 'integer',
|
|
520
|
+
minimum: 10
|
|
521
|
+
},
|
|
522
|
+
orientation: {
|
|
523
|
+
type: 'string',
|
|
524
|
+
enum: ['portrait', 'landscape']
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
},
|
|
528
|
+
tiles: {
|
|
529
|
+
type: 'array',
|
|
530
|
+
items: {
|
|
531
|
+
type: 'object',
|
|
532
|
+
additionalProperties: false,
|
|
533
|
+
properties: {
|
|
534
|
+
filepath: {
|
|
535
|
+
type: 'string'
|
|
536
|
+
},
|
|
537
|
+
content: {
|
|
538
|
+
type: 'string'
|
|
539
|
+
},
|
|
540
|
+
statusBarHeight: {
|
|
541
|
+
type: 'integer',
|
|
542
|
+
minimum: 0
|
|
543
|
+
},
|
|
544
|
+
navBarHeight: {
|
|
545
|
+
type: 'integer',
|
|
546
|
+
minimum: 0
|
|
547
|
+
},
|
|
548
|
+
headerHeight: {
|
|
549
|
+
type: 'integer',
|
|
550
|
+
minimum: 0
|
|
551
|
+
},
|
|
552
|
+
footerHeight: {
|
|
553
|
+
type: 'integer',
|
|
554
|
+
minimum: 0
|
|
555
|
+
},
|
|
556
|
+
fullscreen: {
|
|
557
|
+
type: 'boolean'
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
473
563
|
}; // Grouped schemas for easier registration
|
|
474
564
|
|
|
475
|
-
export const schemas = [configSchema, snapshotSchema]; // Config migrate function
|
|
565
|
+
export const schemas = [configSchema, snapshotSchema, comparisonSchema]; // Config migrate function
|
|
476
566
|
|
|
477
567
|
export function configMigration(config, util) {
|
|
478
568
|
/* eslint-disable curly */
|
|
@@ -485,41 +575,21 @@ export function configMigration(config, util) {
|
|
|
485
575
|
util.map('agent.assetDiscovery.pagePoolSizeMax', 'discovery.concurrency');
|
|
486
576
|
util.del('agent');
|
|
487
577
|
} else {
|
|
488
|
-
|
|
578
|
+
util.deprecate('snapshot.devicePixelRatio', {
|
|
579
|
+
map: 'discovery.devicePixelRatio',
|
|
489
580
|
type: 'config',
|
|
490
|
-
until: '
|
|
491
|
-
}; // snapshot discovery options have moved
|
|
492
|
-
|
|
493
|
-
util.deprecate('snapshot.authorization', {
|
|
494
|
-
map: 'discovery.authorization',
|
|
495
|
-
...notice
|
|
496
|
-
});
|
|
497
|
-
util.deprecate('snapshot.requestHeaders', {
|
|
498
|
-
map: 'discovery.requestHeaders',
|
|
499
|
-
...notice
|
|
581
|
+
until: '2.0.0'
|
|
500
582
|
});
|
|
501
583
|
}
|
|
502
584
|
} // Snapshot option migrate function
|
|
503
585
|
|
|
504
586
|
export function snapshotMigration(config, util, root = '') {
|
|
505
|
-
|
|
587
|
+
// discovery options have moved
|
|
588
|
+
util.deprecate(`${root}.devicePixelRatio`, {
|
|
589
|
+
map: `${root}.discovery.devicePixelRatio`,
|
|
506
590
|
type: 'snapshot',
|
|
507
|
-
until: '
|
|
591
|
+
until: '2.0.0',
|
|
508
592
|
warn: true
|
|
509
|
-
}; // discovery options have moved
|
|
510
|
-
|
|
511
|
-
util.deprecate(`${root}.authorization`, {
|
|
512
|
-
map: `${root}.discovery.authorization`,
|
|
513
|
-
...notice
|
|
514
|
-
});
|
|
515
|
-
util.deprecate(`${root}.requestHeaders`, {
|
|
516
|
-
map: `${root}.discovery.requestHeaders`,
|
|
517
|
-
...notice
|
|
518
|
-
}); // snapshots option was renamed
|
|
519
|
-
|
|
520
|
-
util.deprecate(`${root}.snapshots`, {
|
|
521
|
-
map: `${root}.additionalSnapshots`,
|
|
522
|
-
...notice
|
|
523
593
|
});
|
|
524
594
|
} // Snapshot list options migrate function
|
|
525
595
|
|
|
@@ -531,18 +601,8 @@ export function snapshotListMigration(config, util) {
|
|
|
531
601
|
snapshotMigration(config, util, `snapshots[${i}]`);
|
|
532
602
|
}
|
|
533
603
|
}
|
|
534
|
-
} //
|
|
535
|
-
|
|
604
|
+
} // migrate options
|
|
536
605
|
|
|
537
|
-
let notice = {
|
|
538
|
-
type: 'snapshot',
|
|
539
|
-
until: '1.0.0',
|
|
540
|
-
warn: true
|
|
541
|
-
};
|
|
542
|
-
util.deprecate('overrides', {
|
|
543
|
-
map: 'options',
|
|
544
|
-
...notice
|
|
545
|
-
}); // migrate options
|
|
546
606
|
|
|
547
607
|
if (Array.isArray(config.options)) {
|
|
548
608
|
for (let i in config.options) {
|