@percy/core 1.3.0 → 1.5.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 +6 -11
- package/dist/config.js +6 -0
- package/dist/page.js +6 -4
- package/dist/server.js +15 -1
- package/dist/snapshot.js +48 -34
- package/dist/utils.js +2 -1
- package/package.json +6 -6
package/dist/api.js
CHANGED
|
@@ -2,14 +2,13 @@ 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 { getPackageJSON } from './utils.js';
|
|
6
|
-
import Server from './server.js'; // need require.resolve until import.meta.resolve can be transpiled
|
|
5
|
+
import { getPackageJSON, Server } from './utils.js'; // need require.resolve until import.meta.resolve can be transpiled
|
|
7
6
|
|
|
8
7
|
export const PERCY_DOM = createRequire(import.meta.url).resolve('@percy/dom'); // Create a Percy CLI API server instance
|
|
9
8
|
|
|
10
9
|
export function createPercyServer(percy, port) {
|
|
11
10
|
let pkg = getPackageJSON(import.meta.url);
|
|
12
|
-
return
|
|
11
|
+
return Server.createServer({
|
|
13
12
|
port
|
|
14
13
|
}) // facilitate logger websocket connections
|
|
15
14
|
.websocket('/(logger)?', ws => {
|
|
@@ -83,14 +82,10 @@ export function createPercyServer(percy, port) {
|
|
|
83
82
|
|
|
84
83
|
export function createStaticServer(options) {
|
|
85
84
|
let {
|
|
86
|
-
serve,
|
|
87
|
-
|
|
88
|
-
baseUrl = '/',
|
|
89
|
-
...opts
|
|
85
|
+
serve: dir,
|
|
86
|
+
baseUrl = '/'
|
|
90
87
|
} = options;
|
|
91
|
-
let server =
|
|
92
|
-
port
|
|
93
|
-
}).serve(baseUrl, serve, opts); // used when generating an automatic sitemap
|
|
88
|
+
let server = Server.createServer(options); // used when generating an automatic sitemap
|
|
94
89
|
|
|
95
90
|
let toURL = Server.createRewriter( // reverse rewrites' src, dest, & order
|
|
96
91
|
Object.entries((options === null || options === void 0 ? void 0 : options.rewrites) ?? {}).reduce((acc, rw) => [rw.reverse(), ...acc], []), (filename, rewrite) => new URL(path.posix.join(baseUrl, // cleanUrls will trim trailing .html/index.html from paths
|
|
@@ -101,7 +96,7 @@ export function createStaticServer(options) {
|
|
|
101
96
|
default: glob
|
|
102
97
|
} = await import('fast-glob');
|
|
103
98
|
let files = await glob('**/*.html', {
|
|
104
|
-
cwd:
|
|
99
|
+
cwd: dir,
|
|
105
100
|
fs
|
|
106
101
|
});
|
|
107
102
|
return res.send(200, 'application/xml', ['<?xml version="1.0" encoding="UTF-8"?>', '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">', ...files.map(name => ` <url><loc>${toURL(name)}</loc></url>`), '</urlset>'].join('\n'));
|
package/dist/config.js
CHANGED
|
@@ -28,6 +28,9 @@ export const configSchema = {
|
|
|
28
28
|
},
|
|
29
29
|
scope: {
|
|
30
30
|
type: 'string'
|
|
31
|
+
},
|
|
32
|
+
devicePixelRatio: {
|
|
33
|
+
type: 'integer'
|
|
31
34
|
}
|
|
32
35
|
}
|
|
33
36
|
},
|
|
@@ -177,6 +180,9 @@ export const snapshotSchema = {
|
|
|
177
180
|
enableJavaScript: {
|
|
178
181
|
$ref: '/config/snapshot#/properties/enableJavaScript'
|
|
179
182
|
},
|
|
183
|
+
devicePixelRatio: {
|
|
184
|
+
$ref: '/config/snapshot#/properties/devicePixelRatio'
|
|
185
|
+
},
|
|
180
186
|
discovery: {
|
|
181
187
|
type: 'object',
|
|
182
188
|
additionalProperties: false,
|
package/dist/page.js
CHANGED
|
@@ -29,12 +29,14 @@ export class Page {
|
|
|
29
29
|
|
|
30
30
|
async resize({
|
|
31
31
|
width,
|
|
32
|
-
height
|
|
32
|
+
height,
|
|
33
|
+
deviceScaleFactor = 1,
|
|
34
|
+
mobile = false
|
|
33
35
|
}) {
|
|
34
|
-
this.log.debug(`Resize page to ${width}x${height}`);
|
|
36
|
+
this.log.debug(`Resize page to ${width}x${height} @${deviceScaleFactor}x`);
|
|
35
37
|
await this.session.send('Emulation.setDeviceMetricsOverride', {
|
|
36
|
-
deviceScaleFactor
|
|
37
|
-
mobile
|
|
38
|
+
deviceScaleFactor,
|
|
39
|
+
mobile,
|
|
38
40
|
height,
|
|
39
41
|
width
|
|
40
42
|
});
|
package/dist/server.js
CHANGED
|
@@ -422,9 +422,23 @@ function parseByteRange(range, size) {
|
|
|
422
422
|
start,
|
|
423
423
|
end
|
|
424
424
|
};
|
|
425
|
-
} //
|
|
425
|
+
} // shorthand function for creating a new server with specific options
|
|
426
426
|
|
|
427
427
|
|
|
428
|
+
export function createServer(options = {}) {
|
|
429
|
+
let {
|
|
430
|
+
serve,
|
|
431
|
+
port,
|
|
432
|
+
baseUrl = '/',
|
|
433
|
+
...opts
|
|
434
|
+
} = options;
|
|
435
|
+
let server = new Server({
|
|
436
|
+
port
|
|
437
|
+
});
|
|
438
|
+
return serve ? server.serve(baseUrl, serve, opts) : server;
|
|
439
|
+
} // include some exports as static properties
|
|
440
|
+
|
|
428
441
|
Server.Error = ServerError;
|
|
429
442
|
Server.createRewriter = createRewriter;
|
|
443
|
+
Server.createServer = createServer;
|
|
430
444
|
export default Server;
|
package/dist/snapshot.js
CHANGED
|
@@ -260,6 +260,7 @@ function debugSnapshotConfig(snapshot, showInfo) {
|
|
|
260
260
|
debugProp(snapshot, 'widths', v => `${v}px`);
|
|
261
261
|
debugProp(snapshot, 'minHeight', v => `${v}px`);
|
|
262
262
|
debugProp(snapshot, 'enableJavaScript');
|
|
263
|
+
debugProp(snapshot, 'deviceScaleFactor');
|
|
263
264
|
debugProp(snapshot, 'waitForTimeout');
|
|
264
265
|
debugProp(snapshot, 'waitForSelector');
|
|
265
266
|
debugProp(snapshot, 'execute.afterNavigation');
|
|
@@ -320,20 +321,55 @@ function waitForDiscoveryNetworkIdle(page, options) {
|
|
|
320
321
|
} // Used to cache resources across core instances
|
|
321
322
|
|
|
322
323
|
|
|
323
|
-
const RESOURCE_CACHE_KEY = Symbol('resource-cache'); //
|
|
324
|
+
const RESOURCE_CACHE_KEY = Symbol('resource-cache'); // Trigger resource requests for a page by iterating over snapshot widths and calling any provided
|
|
325
|
+
// execute options. Additional resize options may be provided to capture resources mobile resources
|
|
326
|
+
|
|
327
|
+
function* triggerResourceRequests(page, snapshot, options) {
|
|
328
|
+
// copy widths to prevent mutation later
|
|
329
|
+
let [initialWidth, ...widths] = snapshot.widths; // set the initial page size
|
|
330
|
+
|
|
331
|
+
yield page.resize({
|
|
332
|
+
width: initialWidth,
|
|
333
|
+
height: snapshot.minHeight,
|
|
334
|
+
...options
|
|
335
|
+
}); // navigate to the url
|
|
336
|
+
|
|
337
|
+
yield page.goto(snapshot.url);
|
|
338
|
+
|
|
339
|
+
if (snapshot.execute) {
|
|
340
|
+
// when any execute options are provided, inject snapshot options
|
|
341
|
+
|
|
342
|
+
/* istanbul ignore next: cannot detect coverage of injected code */
|
|
343
|
+
yield page.eval((_, s) => window.__PERCY__.snapshot = s, snapshot);
|
|
344
|
+
yield page.evaluate(snapshot.execute.afterNavigation);
|
|
345
|
+
} // trigger resize events for other widths
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
for (let width of widths) {
|
|
349
|
+
var _snapshot$execute, _snapshot$execute2;
|
|
350
|
+
|
|
351
|
+
yield page.evaluate((_snapshot$execute = snapshot.execute) === null || _snapshot$execute === void 0 ? void 0 : _snapshot$execute.beforeResize);
|
|
352
|
+
yield waitForDiscoveryNetworkIdle(page, snapshot.discovery);
|
|
353
|
+
yield page.resize({
|
|
354
|
+
width,
|
|
355
|
+
height: snapshot.minHeight,
|
|
356
|
+
...options
|
|
357
|
+
});
|
|
358
|
+
yield page.evaluate((_snapshot$execute2 = snapshot.execute) === null || _snapshot$execute2 === void 0 ? void 0 : _snapshot$execute2.afterResize);
|
|
359
|
+
}
|
|
360
|
+
} // Discovers resources for a snapshot using a browser page to intercept requests. The callback
|
|
324
361
|
// function will be called with the snapshot name (for additional snapshots) and an array of
|
|
325
362
|
// discovered resources. When additional snapshots are provided, the callback will be called once
|
|
326
363
|
// for each snapshot.
|
|
327
364
|
|
|
365
|
+
|
|
328
366
|
export async function* discoverSnapshotResources(percy, snapshot, callback) {
|
|
329
367
|
debugSnapshotConfig(snapshot, percy.dryRun); // when dry-running, invoke the callback for each snapshot and immediately return
|
|
330
368
|
|
|
331
369
|
let allSnapshots = [snapshot, ...(snapshot.additionalSnapshots || [])];
|
|
332
370
|
if (percy.dryRun) return allSnapshots.map(s => callback(s)); // keep a global resource cache across snapshots
|
|
333
371
|
|
|
334
|
-
let cache = percy[RESOURCE_CACHE_KEY] || (percy[RESOURCE_CACHE_KEY] = new Map()); //
|
|
335
|
-
|
|
336
|
-
let widths = snapshot.widths.slice(); // preload the root resource for existing dom snapshots
|
|
372
|
+
let cache = percy[RESOURCE_CACHE_KEY] || (percy[RESOURCE_CACHE_KEY] = new Map()); // preload the root resource for existing dom snapshots
|
|
337
373
|
|
|
338
374
|
let resources = new Map(snapshot.domSnapshot && [createRootResource(snapshot.url, snapshot.domSnapshot)].map(resource => [resource.url, resource])); // open a new browser page
|
|
339
375
|
|
|
@@ -356,33 +392,15 @@ export async function* discoverSnapshotResources(percy, snapshot, callback) {
|
|
|
356
392
|
});
|
|
357
393
|
|
|
358
394
|
try {
|
|
359
|
-
//
|
|
360
|
-
yield page.resize({
|
|
361
|
-
width: widths.shift(),
|
|
362
|
-
height: snapshot.minHeight
|
|
363
|
-
}); // navigate to the url
|
|
364
|
-
|
|
365
|
-
yield page.goto(snapshot.url);
|
|
366
|
-
|
|
367
|
-
if (snapshot.execute) {
|
|
368
|
-
// when any execute options are provided, inject snapshot options
|
|
369
|
-
|
|
370
|
-
/* istanbul ignore next: cannot detect coverage of injected code */
|
|
371
|
-
yield page.eval((_, s) => window.__PERCY__.snapshot = s, snapshot);
|
|
372
|
-
yield page.evaluate(snapshot.execute.afterNavigation);
|
|
373
|
-
} // trigger resize events for other widths
|
|
374
|
-
|
|
395
|
+
yield* triggerResourceRequests(page, snapshot); // trigger resource requests for any alternate device pixel ratio
|
|
375
396
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
yield page.evaluate((_snapshot$execute = snapshot.execute) === null || _snapshot$execute === void 0 ? void 0 : _snapshot$execute.beforeResize);
|
|
397
|
+
if (snapshot.devicePixelRatio) {
|
|
398
|
+
// wait for any existing pending resource requests first
|
|
380
399
|
yield waitForDiscoveryNetworkIdle(page, snapshot.discovery);
|
|
381
|
-
yield page
|
|
382
|
-
|
|
383
|
-
|
|
400
|
+
yield* triggerResourceRequests(page, snapshot, {
|
|
401
|
+
deviceScaleFactor: snapshot.devicePixelRatio,
|
|
402
|
+
mobile: true
|
|
384
403
|
});
|
|
385
|
-
yield page.evaluate((_snapshot$execute2 = snapshot.execute) === null || _snapshot$execute2 === void 0 ? void 0 : _snapshot$execute2.afterResize);
|
|
386
404
|
}
|
|
387
405
|
|
|
388
406
|
if (snapshot.domSnapshot) {
|
|
@@ -413,12 +431,8 @@ export async function* discoverSnapshotResources(percy, snapshot, callback) {
|
|
|
413
431
|
|
|
414
432
|
resources.delete(root.url);
|
|
415
433
|
}
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
await page.close();
|
|
420
|
-
} catch (error) {
|
|
434
|
+
}
|
|
435
|
+
} finally {
|
|
421
436
|
await page.close();
|
|
422
|
-
throw error;
|
|
423
437
|
}
|
|
424
438
|
}
|
package/dist/utils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import EventEmitter from 'events';
|
|
2
2
|
import { sha256hash } from '@percy/client/utils';
|
|
3
|
-
export { request, getPackageJSON, hostnameMatches } from '@percy/client/utils';
|
|
3
|
+
export { request, getPackageJSON, hostnameMatches } from '@percy/client/utils';
|
|
4
|
+
export { Server, createServer } from './server.js'; // Returns the hostname portion of a URL.
|
|
4
5
|
|
|
5
6
|
export function hostname(url) {
|
|
6
7
|
return new URL(url).hostname;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@percy/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.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.
|
|
43
|
-
"@percy/config": "1.
|
|
44
|
-
"@percy/dom": "1.
|
|
45
|
-
"@percy/logger": "1.
|
|
42
|
+
"@percy/client": "1.5.0",
|
|
43
|
+
"@percy/config": "1.5.0",
|
|
44
|
+
"@percy/dom": "1.5.0",
|
|
45
|
+
"@percy/logger": "1.5.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": "
|
|
56
|
+
"gitHead": "813db57980acd418a03d5bf39174ee840feb6229"
|
|
57
57
|
}
|