@percy/core 1.29.0 → 1.29.1-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.
- package/dist/config.js +7 -0
- package/dist/network.js +12 -1
- package/dist/percy.js +4 -1
- package/dist/snapshot.js +20 -3
- package/dist/utils.js +59 -0
- package/package.json +8 -8
package/dist/config.js
CHANGED
|
@@ -7,6 +7,10 @@ export const configSchema = {
|
|
|
7
7
|
deferUploads: {
|
|
8
8
|
type: 'boolean'
|
|
9
9
|
},
|
|
10
|
+
useSystemProxy: {
|
|
11
|
+
type: 'boolean',
|
|
12
|
+
default: false
|
|
13
|
+
},
|
|
10
14
|
token: {
|
|
11
15
|
type: 'string'
|
|
12
16
|
},
|
|
@@ -584,6 +588,9 @@ export const snapshotSchema = {
|
|
|
584
588
|
type: 'string'
|
|
585
589
|
}
|
|
586
590
|
},
|
|
591
|
+
cookies: {
|
|
592
|
+
type: 'string'
|
|
593
|
+
},
|
|
587
594
|
resources: {
|
|
588
595
|
type: 'array',
|
|
589
596
|
items: {
|
package/dist/network.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { request as makeRequest } from '@percy/client/utils';
|
|
2
2
|
import logger from '@percy/logger';
|
|
3
3
|
import mime from 'mime-types';
|
|
4
|
-
import { DefaultMap, createResource, hostnameMatches, normalizeURL, waitFor } from './utils.js';
|
|
4
|
+
import { DefaultMap, createResource, decodeAndEncodeURLWithLogging, hostnameMatches, normalizeURL, waitFor } from './utils.js';
|
|
5
5
|
const MAX_RESOURCE_SIZE = 25 * 1024 ** 2; // 25MB
|
|
6
6
|
const ALLOWED_STATUSES = [200, 201, 301, 302, 304, 307, 308];
|
|
7
7
|
const ALLOWED_RESOURCES = ['Document', 'Stylesheet', 'Image', 'Media', 'Font', 'Other'];
|
|
@@ -213,6 +213,17 @@ export class Network {
|
|
|
213
213
|
|
|
214
214
|
// do not handle data urls
|
|
215
215
|
if (request.url.startsWith('data:')) return;
|
|
216
|
+
|
|
217
|
+
// Browsers handle URL encoding leniently, but invalid characters can break tools like Jackproxy.
|
|
218
|
+
// This code checks for issues such as `%` and leading spaces and warns the user accordingly.
|
|
219
|
+
decodeAndEncodeURLWithLogging(request.url, this.log, {
|
|
220
|
+
meta: {
|
|
221
|
+
...this.meta,
|
|
222
|
+
url: request.url
|
|
223
|
+
},
|
|
224
|
+
shouldLogWarning: true,
|
|
225
|
+
warningMessage: `An invalid URL was detected for url: ${request.url} - the snapshot may fail on Percy. Please verify that your asset URL is valid.`
|
|
226
|
+
});
|
|
216
227
|
if (this.intercept) {
|
|
217
228
|
this.#pending.set(requestId, event);
|
|
218
229
|
if (this.captureMockedServiceWorker) {
|
package/dist/percy.js
CHANGED
|
@@ -17,7 +17,7 @@ import logger from '@percy/logger';
|
|
|
17
17
|
import { getProxy } from '@percy/client/utils';
|
|
18
18
|
import Browser from './browser.js';
|
|
19
19
|
import Pako from 'pako';
|
|
20
|
-
import { base64encode, generatePromise, yieldAll, yieldTo, redactSecrets } from './utils.js';
|
|
20
|
+
import { base64encode, generatePromise, yieldAll, yieldTo, redactSecrets, detectSystemProxyAndLog } from './utils.js';
|
|
21
21
|
import { createPercyServer, createStaticServer } from './api.js';
|
|
22
22
|
import { gatherSnapshots, createSnapshotsQueue, validateSnapshotOptions } from './snapshot.js';
|
|
23
23
|
import { discoverSnapshotResources, createDiscoveryQueue } from './discovery.js';
|
|
@@ -179,6 +179,9 @@ export class Percy {
|
|
|
179
179
|
if (process.env.PERCY_CLIENT_ERROR_LOGS !== 'false') {
|
|
180
180
|
this.log.warn('Notice: Percy collects CI logs for service improvement, stored for 30 days. Opt-out anytime with export PERCY_CLIENT_ERROR_LOGS=false');
|
|
181
181
|
}
|
|
182
|
+
// Not awaiting proxy check as this can be asyncronous when not enabled
|
|
183
|
+
const detectProxy = detectSystemProxyAndLog(this.config.percy.useSystemProxy);
|
|
184
|
+
if (this.config.percy.useSystemProxy) await detectProxy;
|
|
182
185
|
// start the snapshots queue immediately when not delayed or deferred
|
|
183
186
|
if (!this.delayUploads && !this.deferUploads) yield _classPrivateFieldGet2(this, _snapshots).start();
|
|
184
187
|
// do not start the discovery queue when not needed
|
package/dist/snapshot.js
CHANGED
|
@@ -3,7 +3,7 @@ import PercyConfig from '@percy/config';
|
|
|
3
3
|
import micromatch from 'micromatch';
|
|
4
4
|
import { configSchema } from './config.js';
|
|
5
5
|
import Queue from './queue.js';
|
|
6
|
-
import { request, hostnameMatches, yieldTo, snapshotLogName } from './utils.js';
|
|
6
|
+
import { request, hostnameMatches, yieldTo, snapshotLogName, decodeAndEncodeURLWithLogging } from './utils.js';
|
|
7
7
|
import { JobData } from './wait-for-job.js';
|
|
8
8
|
|
|
9
9
|
// Throw a better error message for missing or invalid urls
|
|
@@ -17,6 +17,23 @@ function validURL(url, base) {
|
|
|
17
17
|
throw new Error(`Invalid snapshot URL: ${e.input}`);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
+
function validateAndFixSnapshotUrl(snapshot) {
|
|
21
|
+
let log = logger('core:snapshot');
|
|
22
|
+
// encoding snapshot url, if contians invalid URI characters/syntax
|
|
23
|
+
let modifiedURL = decodeAndEncodeURLWithLogging(snapshot.url, log, {
|
|
24
|
+
meta: {
|
|
25
|
+
snapshot: {
|
|
26
|
+
name: snapshot.name || snapshot.url
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
shouldLogWarning: true,
|
|
30
|
+
warningMessage: `Invalid URL detected for url: ${snapshot.url} - the snapshot may fail on Percy. Please confirm that your website URL is valid.`
|
|
31
|
+
});
|
|
32
|
+
if (modifiedURL !== snapshot.url) {
|
|
33
|
+
log.debug(`Snapshot URL modified to: ${modifiedURL}`);
|
|
34
|
+
snapshot.url = modifiedURL;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
20
37
|
|
|
21
38
|
// used to deserialize regular expression strings
|
|
22
39
|
const RE_REGEXP = /^\/(.+)\/(\w+)?$/;
|
|
@@ -86,9 +103,9 @@ function mapSnapshotOptions(snapshots, context) {
|
|
|
86
103
|
if (typeof snapshot === 'string') snapshot = {
|
|
87
104
|
url: snapshot
|
|
88
105
|
};
|
|
89
|
-
|
|
90
|
-
// normalize the snapshot url and use it for the default name
|
|
106
|
+
validateAndFixSnapshotUrl(snapshot);
|
|
91
107
|
let url = validURL(snapshot.url, context === null || context === void 0 ? void 0 : context.baseUrl);
|
|
108
|
+
// normalize the snapshot url and use it for the default name
|
|
92
109
|
(_snapshot = snapshot).name || (_snapshot.name = `${url.pathname}${url.search}${url.hash}`);
|
|
93
110
|
snapshot.url = url.href;
|
|
94
111
|
|
package/dist/utils.js
CHANGED
|
@@ -5,6 +5,8 @@ import YAML from 'yaml';
|
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import url from 'url';
|
|
7
7
|
import { readFileSync } from 'fs';
|
|
8
|
+
import logger from '@percy/logger';
|
|
9
|
+
import DetectProxy from '@percy/client/detect-proxy';
|
|
8
10
|
export { request, getPackageJSON, hostnameMatches } from '@percy/client/utils';
|
|
9
11
|
export { Server, createServer } from './server.js';
|
|
10
12
|
|
|
@@ -377,6 +379,35 @@ export function redactSecrets(data) {
|
|
|
377
379
|
export function base64encode(content) {
|
|
378
380
|
return Buffer.from(content).toString('base64');
|
|
379
381
|
}
|
|
382
|
+
|
|
383
|
+
// This function replaces invalid character that are not the
|
|
384
|
+
// part of valid URI syntax with there correct encoded value.
|
|
385
|
+
// Also, if a character is a part of valid URI syntax, those characters
|
|
386
|
+
// are not encoded
|
|
387
|
+
// Eg: [abc] -> gets encoded to %5Babc%5D
|
|
388
|
+
// ab c -> ab%20c
|
|
389
|
+
export function decodeAndEncodeURLWithLogging(url, logger, options = {}) {
|
|
390
|
+
// In case the url is partially encoded, then directly using encodeURI()
|
|
391
|
+
// will encode those characters again. Therefore decodeURI once helps is decoding
|
|
392
|
+
// partially encoded URL and then after encoding it again, full URL get encoded
|
|
393
|
+
// correctly.
|
|
394
|
+
const {
|
|
395
|
+
meta,
|
|
396
|
+
shouldLogWarning,
|
|
397
|
+
warningMessage
|
|
398
|
+
} = options;
|
|
399
|
+
try {
|
|
400
|
+
let decodedURL = decodeURI(url); // This can throw error, so handle it will trycatch
|
|
401
|
+
let encodedURL = encodeURI(decodedURL);
|
|
402
|
+
return encodedURL;
|
|
403
|
+
} catch (error) {
|
|
404
|
+
logger.debug(error, meta);
|
|
405
|
+
if (error.name === 'URIError' && shouldLogWarning) {
|
|
406
|
+
logger.warn(warningMessage);
|
|
407
|
+
}
|
|
408
|
+
return url;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
380
411
|
export function snapshotLogName(name, meta) {
|
|
381
412
|
var _meta$snapshot;
|
|
382
413
|
if (meta !== null && meta !== void 0 && (_meta$snapshot = meta.snapshot) !== null && _meta$snapshot !== void 0 && _meta$snapshot.testCase) {
|
|
@@ -384,6 +415,34 @@ export function snapshotLogName(name, meta) {
|
|
|
384
415
|
}
|
|
385
416
|
return name;
|
|
386
417
|
}
|
|
418
|
+
export async function detectSystemProxyAndLog(applyProxy) {
|
|
419
|
+
// if proxy is already set no need to check again
|
|
420
|
+
if (process.env.HTTPS_PROXY || process.env.HTTP_PROXY) return;
|
|
421
|
+
let proxyPresent = false;
|
|
422
|
+
const log = logger('core:utils');
|
|
423
|
+
// Checking proxy shouldn't cause failure
|
|
424
|
+
try {
|
|
425
|
+
const detectProxy = new DetectProxy();
|
|
426
|
+
const proxies = await detectProxy.getSystemProxy();
|
|
427
|
+
proxyPresent = proxies.length !== 0;
|
|
428
|
+
if (proxyPresent) {
|
|
429
|
+
if (applyProxy) {
|
|
430
|
+
proxies.forEach(proxy => {
|
|
431
|
+
if (proxy.type === 'HTTPS') {
|
|
432
|
+
process.env.HTTPS_PROXY = 'https://' + proxy.host + ':' + proxy.port;
|
|
433
|
+
} else if (proxy.type === 'HTTP') {
|
|
434
|
+
process.env.HTTP_PROXY = 'http://' + proxy.host + ':' + proxy.port;
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
} else {
|
|
438
|
+
log.warn('We have detected a system level proxy in your system. use HTTP_PROXY or HTTPS_PROXY env vars or To auto apply proxy set useSystemProxy: true under percy in config file');
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
} catch (e) {
|
|
442
|
+
log.debug(`Failed to detect system proxy ${e}`);
|
|
443
|
+
}
|
|
444
|
+
return proxyPresent;
|
|
445
|
+
}
|
|
387
446
|
|
|
388
447
|
// DefaultMap, which returns a default value for an uninitialized key
|
|
389
448
|
// Similar to defaultDict in python
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@percy/core",
|
|
3
|
-
"version": "1.29.0",
|
|
3
|
+
"version": "1.29.1-beta.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"publishConfig": {
|
|
11
11
|
"access": "public",
|
|
12
|
-
"tag": "
|
|
12
|
+
"tag": "beta"
|
|
13
13
|
},
|
|
14
14
|
"engines": {
|
|
15
15
|
"node": ">=14"
|
|
@@ -43,11 +43,11 @@
|
|
|
43
43
|
"test:types": "tsd"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@percy/client": "1.29.0",
|
|
47
|
-
"@percy/config": "1.29.0",
|
|
48
|
-
"@percy/dom": "1.29.0",
|
|
49
|
-
"@percy/logger": "1.29.0",
|
|
50
|
-
"@percy/webdriver-utils": "1.29.0",
|
|
46
|
+
"@percy/client": "1.29.1-beta.0",
|
|
47
|
+
"@percy/config": "1.29.1-beta.0",
|
|
48
|
+
"@percy/dom": "1.29.1-beta.0",
|
|
49
|
+
"@percy/logger": "1.29.1-beta.0",
|
|
50
|
+
"@percy/webdriver-utils": "1.29.1-beta.0",
|
|
51
51
|
"content-disposition": "^0.5.4",
|
|
52
52
|
"cross-spawn": "^7.0.3",
|
|
53
53
|
"extract-zip": "^2.0.1",
|
|
@@ -60,5 +60,5 @@
|
|
|
60
60
|
"ws": "^8.17.1",
|
|
61
61
|
"yaml": "^2.4.1"
|
|
62
62
|
},
|
|
63
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "d325b7bbe56764dbde494477d1f4f3bfdc562d6e"
|
|
64
64
|
}
|