@percy/core 1.28.8-beta.6 → 1.28.9-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/discovery.js +23 -3
- package/dist/percy.js +140 -34
- package/dist/snapshot.js +21 -3
- package/package.json +7 -7
package/dist/discovery.js
CHANGED
|
@@ -321,6 +321,9 @@ export function createDiscoveryQueue(percy) {
|
|
|
321
321
|
// on start, launch the browser and run the queue
|
|
322
322
|
.handle('start', async () => {
|
|
323
323
|
cache = percy[RESOURCE_CACHE_KEY] = new Map();
|
|
324
|
+
|
|
325
|
+
// If browser.launch() fails it will get captured in
|
|
326
|
+
// *percy.start()
|
|
324
327
|
await percy.browser.launch();
|
|
325
328
|
queue.run();
|
|
326
329
|
})
|
|
@@ -395,17 +398,34 @@ export function createDiscoveryQueue(percy) {
|
|
|
395
398
|
throwOn: ['AbortError']
|
|
396
399
|
});
|
|
397
400
|
});
|
|
398
|
-
}).handle('error', ({
|
|
401
|
+
}).handle('error', async ({
|
|
399
402
|
name,
|
|
400
403
|
meta
|
|
401
404
|
}, error) => {
|
|
402
405
|
if (error.name === 'AbortError' && queue.readyState < 3) {
|
|
403
406
|
// only error about aborted snapshots when not closed
|
|
404
|
-
|
|
407
|
+
let errMsg = 'Received a duplicate snapshot, ' + `the previous snapshot was aborted: ${snapshotLogName(name, meta)}`;
|
|
408
|
+
percy.log.error(errMsg, {
|
|
409
|
+
snapshotLevel: true,
|
|
410
|
+
snapshotName: name
|
|
411
|
+
});
|
|
412
|
+
await percy.suggestionsForFix(errMsg, meta);
|
|
405
413
|
} else {
|
|
406
414
|
// log all other encountered errors
|
|
407
|
-
|
|
415
|
+
let errMsg = `Encountered an error taking snapshot: ${name}`;
|
|
416
|
+
percy.log.error(errMsg, meta);
|
|
408
417
|
percy.log.error(error, meta);
|
|
418
|
+
let assetDiscoveryErrors = [{
|
|
419
|
+
message: errMsg,
|
|
420
|
+
meta
|
|
421
|
+
}, {
|
|
422
|
+
message: error === null || error === void 0 ? void 0 : error.message,
|
|
423
|
+
meta
|
|
424
|
+
}];
|
|
425
|
+
await percy.suggestionsForFix(assetDiscoveryErrors, {
|
|
426
|
+
snapshotLevel: true,
|
|
427
|
+
snapshotName: name
|
|
428
|
+
});
|
|
409
429
|
}
|
|
410
430
|
});
|
|
411
431
|
}
|
package/dist/percy.js
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
|
+
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
|
|
2
|
+
function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
|
|
3
|
+
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
|
|
4
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
5
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
6
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
7
|
+
function _classPrivateMethodGet(s, a, r) { return _assertClassBrand(a, s), r; }
|
|
8
|
+
function _classPrivateFieldGet2(e, t) { var r = _classPrivateFieldGet(t, e); return _classApplyDescriptorGet(e, r); }
|
|
9
|
+
function _classApplyDescriptorGet(e, t) { return t.get ? t.get.call(e) : t.value; }
|
|
10
|
+
function _classPrivateFieldSet(e, t, r) { var s = _classPrivateFieldGet(t, e); return _classApplyDescriptorSet(e, s, r), r; }
|
|
11
|
+
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
|
|
12
|
+
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
|
|
13
|
+
function _classApplyDescriptorSet(e, t, l) { if (t.set) t.set.call(e, l);else { if (!t.writable) throw new TypeError("attempted to set read only private field"); t.value = l; } }
|
|
1
14
|
import PercyClient from '@percy/client';
|
|
2
15
|
import PercyConfig from '@percy/config';
|
|
3
16
|
import logger from '@percy/logger';
|
|
17
|
+
import { getProxy } from '@percy/client/utils';
|
|
4
18
|
import Browser from './browser.js';
|
|
5
19
|
import Pako from 'pako';
|
|
6
20
|
import { base64encode, generatePromise, yieldAll, yieldTo, redactSecrets } from './utils.js';
|
|
@@ -12,12 +26,11 @@ import { WaitForJob } from './wait-for-job.js';
|
|
|
12
26
|
// A Percy instance will create a new build when started, handle snapshot creation, asset discovery,
|
|
13
27
|
// and resource uploads, and will finalize the build when stopped. Snapshots are processed
|
|
14
28
|
// concurrently and the build is not finalized until all snapshots have been handled.
|
|
29
|
+
var _discovery = /*#__PURE__*/new WeakMap();
|
|
30
|
+
var _snapshots = /*#__PURE__*/new WeakMap();
|
|
31
|
+
var _displaySuggestionLogs = /*#__PURE__*/new WeakSet();
|
|
32
|
+
var _proxyEnabled = /*#__PURE__*/new WeakSet();
|
|
15
33
|
export class Percy {
|
|
16
|
-
log = logger('core');
|
|
17
|
-
readyState = null;
|
|
18
|
-
#discovery = null;
|
|
19
|
-
#snapshots = null;
|
|
20
|
-
|
|
21
34
|
// Static shortcut to create and start an instance in one call
|
|
22
35
|
static async start(options) {
|
|
23
36
|
let instance = new this(options);
|
|
@@ -52,17 +65,31 @@ export class Percy {
|
|
|
52
65
|
projectType = null,
|
|
53
66
|
// options such as `snapshot` and `discovery` that are valid Percy config
|
|
54
67
|
// options which will become accessible via the `.config` property
|
|
55
|
-
...
|
|
68
|
+
..._options
|
|
56
69
|
} = {}) {
|
|
57
|
-
var _config$percy;
|
|
70
|
+
var _config$percy, _config$percy2;
|
|
71
|
+
_classPrivateMethodInitSpec(this, _proxyEnabled);
|
|
72
|
+
_classPrivateMethodInitSpec(this, _displaySuggestionLogs);
|
|
73
|
+
_defineProperty(this, "log", logger('core'));
|
|
74
|
+
_defineProperty(this, "readyState", null);
|
|
75
|
+
_classPrivateFieldInitSpec(this, _discovery, {
|
|
76
|
+
writable: true,
|
|
77
|
+
value: null
|
|
78
|
+
});
|
|
79
|
+
_classPrivateFieldInitSpec(this, _snapshots, {
|
|
80
|
+
writable: true,
|
|
81
|
+
value: null
|
|
82
|
+
});
|
|
58
83
|
let config = PercyConfig.load({
|
|
59
|
-
overrides:
|
|
84
|
+
overrides: _options,
|
|
60
85
|
path: configFile
|
|
61
86
|
});
|
|
62
|
-
|
|
87
|
+
labels ?? (labels = (_config$percy = config.percy) === null || _config$percy === void 0 ? void 0 : _config$percy.labels);
|
|
88
|
+
deferUploads ?? (deferUploads = (_config$percy2 = config.percy) === null || _config$percy2 === void 0 ? void 0 : _config$percy2.deferUploads);
|
|
63
89
|
this.config = config;
|
|
64
90
|
if (testing) loglevel = 'silent';
|
|
65
91
|
if (loglevel) this.loglevel(loglevel);
|
|
92
|
+
this.port = port;
|
|
66
93
|
this.projectType = projectType;
|
|
67
94
|
this.testing = testing ? {} : null;
|
|
68
95
|
this.dryRun = !!testing || !!dryRun;
|
|
@@ -80,8 +107,8 @@ export class Percy {
|
|
|
80
107
|
});
|
|
81
108
|
if (server) this.server = createPercyServer(this, port);
|
|
82
109
|
this.browser = new Browser(this);
|
|
83
|
-
this
|
|
84
|
-
this
|
|
110
|
+
_classPrivateFieldSet(this, _discovery, createDiscoveryQueue(this));
|
|
111
|
+
_classPrivateFieldSet(this, _snapshots, createSnapshotsQueue(this));
|
|
85
112
|
|
|
86
113
|
// generator methods are wrapped to autorun and return promises
|
|
87
114
|
for (let m of ['start', 'stop', 'flush', 'idle', 'snapshot', 'upload']) {
|
|
@@ -134,10 +161,10 @@ export class Percy {
|
|
|
134
161
|
let {
|
|
135
162
|
concurrency
|
|
136
163
|
} = this.config.discovery;
|
|
137
|
-
this
|
|
164
|
+
_classPrivateFieldGet2(this, _discovery).set({
|
|
138
165
|
concurrency
|
|
139
166
|
});
|
|
140
|
-
this
|
|
167
|
+
_classPrivateFieldGet2(this, _snapshots).set({
|
|
141
168
|
concurrency
|
|
142
169
|
});
|
|
143
170
|
return this.config;
|
|
@@ -153,9 +180,9 @@ export class Percy {
|
|
|
153
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');
|
|
154
181
|
}
|
|
155
182
|
// start the snapshots queue immediately when not delayed or deferred
|
|
156
|
-
if (!this.delayUploads && !this.deferUploads) yield this
|
|
183
|
+
if (!this.delayUploads && !this.deferUploads) yield _classPrivateFieldGet2(this, _snapshots).start();
|
|
157
184
|
// do not start the discovery queue when not needed
|
|
158
|
-
if (!this.skipDiscovery) yield this
|
|
185
|
+
if (!this.skipDiscovery) yield _classPrivateFieldGet2(this, _discovery).start();
|
|
159
186
|
// start a local API server for SDK communication
|
|
160
187
|
if (this.server) yield this.server.listen();
|
|
161
188
|
if (this.projectType === 'web') {
|
|
@@ -173,16 +200,19 @@ export class Percy {
|
|
|
173
200
|
var _this$server2;
|
|
174
201
|
// on error, close any running server and end queues
|
|
175
202
|
await ((_this$server2 = this.server) === null || _this$server2 === void 0 ? void 0 : _this$server2.close());
|
|
176
|
-
await this
|
|
177
|
-
await this
|
|
203
|
+
await _classPrivateFieldGet2(this, _discovery).end();
|
|
204
|
+
await _classPrivateFieldGet2(this, _snapshots).end();
|
|
178
205
|
|
|
179
206
|
// mark this instance as closed unless aborting
|
|
180
207
|
this.readyState = error.name !== 'AbortError' ? 3 : null;
|
|
181
208
|
|
|
182
209
|
// throw an easier-to-understand error when the port is in use
|
|
183
210
|
if (error.code === 'EADDRINUSE') {
|
|
184
|
-
|
|
211
|
+
let errMsg = `Percy is already running or the port ${this.port} is in use`;
|
|
212
|
+
await this.suggestionsForFix(errMsg);
|
|
213
|
+
throw new Error(errMsg);
|
|
185
214
|
} else {
|
|
215
|
+
await this.suggestionsForFix(error.message);
|
|
186
216
|
throw error;
|
|
187
217
|
}
|
|
188
218
|
}
|
|
@@ -190,8 +220,8 @@ export class Percy {
|
|
|
190
220
|
|
|
191
221
|
// Resolves once snapshot and upload queues are idle
|
|
192
222
|
async *idle() {
|
|
193
|
-
yield* this
|
|
194
|
-
yield* this
|
|
223
|
+
yield* _classPrivateFieldGet2(this, _discovery).idle();
|
|
224
|
+
yield* _classPrivateFieldGet2(this, _snapshots).idle();
|
|
195
225
|
}
|
|
196
226
|
|
|
197
227
|
// Wait for currently queued snapshots then run and wait for resulting uploads
|
|
@@ -204,13 +234,13 @@ export class Percy {
|
|
|
204
234
|
yield new Promise(r => setImmediate(r));
|
|
205
235
|
|
|
206
236
|
// flush and log progress for discovery before snapshots
|
|
207
|
-
if (!this.skipDiscovery && this
|
|
208
|
-
if (options) yield* yieldAll(options.map(o => this
|
|
237
|
+
if (!this.skipDiscovery && _classPrivateFieldGet2(this, _discovery).size) {
|
|
238
|
+
if (options) yield* yieldAll(options.map(o => _classPrivateFieldGet2(this, _discovery).process(o)));else yield* _classPrivateFieldGet2(this, _discovery).flush(size => callback === null || callback === void 0 ? void 0 : callback('Processing', size));
|
|
209
239
|
}
|
|
210
240
|
|
|
211
241
|
// flush and log progress for snapshot uploads
|
|
212
|
-
if (!this.skipUploads && this
|
|
213
|
-
if (options) yield* yieldAll(options.map(o => this
|
|
242
|
+
if (!this.skipUploads && _classPrivateFieldGet2(this, _snapshots).size) {
|
|
243
|
+
if (options) yield* yieldAll(options.map(o => _classPrivateFieldGet2(this, _snapshots).process(o)));else yield* _classPrivateFieldGet2(this, _snapshots).flush(size => callback === null || callback === void 0 ? void 0 : callback('Uploading', size));
|
|
214
244
|
}
|
|
215
245
|
}
|
|
216
246
|
|
|
@@ -229,8 +259,8 @@ export class Percy {
|
|
|
229
259
|
|
|
230
260
|
// close queues asap
|
|
231
261
|
if (force) {
|
|
232
|
-
this
|
|
233
|
-
this
|
|
262
|
+
_classPrivateFieldGet2(this, _discovery).close(true);
|
|
263
|
+
_classPrivateFieldGet2(this, _snapshots).close(true);
|
|
234
264
|
}
|
|
235
265
|
|
|
236
266
|
// already stopping
|
|
@@ -255,14 +285,14 @@ export class Percy {
|
|
|
255
285
|
}
|
|
256
286
|
|
|
257
287
|
// if dry-running, log the total number of snapshots
|
|
258
|
-
if (this.dryRun && this
|
|
259
|
-
this.log.info(info('Found', this
|
|
288
|
+
if (this.dryRun && _classPrivateFieldGet2(this, _snapshots).size) {
|
|
289
|
+
this.log.info(info('Found', _classPrivateFieldGet2(this, _snapshots).size));
|
|
260
290
|
}
|
|
261
291
|
|
|
262
292
|
// close server and end queues
|
|
263
293
|
await ((_this$server3 = this.server) === null || _this$server3 === void 0 ? void 0 : _this$server3.close());
|
|
264
|
-
await this
|
|
265
|
-
await this
|
|
294
|
+
await _classPrivateFieldGet2(this, _discovery).end();
|
|
295
|
+
await _classPrivateFieldGet2(this, _snapshots).end();
|
|
266
296
|
|
|
267
297
|
// mark instance as stopped
|
|
268
298
|
this.readyState = 3;
|
|
@@ -270,6 +300,9 @@ export class Percy {
|
|
|
270
300
|
this.log.error(err);
|
|
271
301
|
throw err;
|
|
272
302
|
} finally {
|
|
303
|
+
// This issue doesn't comes under regular error logs,
|
|
304
|
+
// it's detected if we just and stop percy server
|
|
305
|
+
await this.checkForNoSnapshotCommandError();
|
|
273
306
|
await this.sendBuildLogs();
|
|
274
307
|
}
|
|
275
308
|
}
|
|
@@ -322,7 +355,7 @@ export class Percy {
|
|
|
322
355
|
}
|
|
323
356
|
|
|
324
357
|
// gather snapshots and discover snapshot resources
|
|
325
|
-
yield* discoverSnapshotResources(this
|
|
358
|
+
yield* discoverSnapshotResources(_classPrivateFieldGet2(this, _discovery), {
|
|
326
359
|
skipDiscovery: this.skipDiscovery,
|
|
327
360
|
dryRun: this.dryRun,
|
|
328
361
|
snapshots: yield* gatherSnapshots(options, {
|
|
@@ -342,7 +375,7 @@ export class Percy {
|
|
|
342
375
|
});
|
|
343
376
|
}
|
|
344
377
|
// push each finished snapshot to the snapshots queue
|
|
345
|
-
this
|
|
378
|
+
_classPrivateFieldGet2(this, _snapshots).push(snapshot);
|
|
346
379
|
});
|
|
347
380
|
} finally {
|
|
348
381
|
var _server;
|
|
@@ -402,9 +435,11 @@ export class Percy {
|
|
|
402
435
|
// return an async generator to allow cancelation
|
|
403
436
|
return async function* () {
|
|
404
437
|
try {
|
|
405
|
-
return yield* yieldTo(this
|
|
438
|
+
return yield* yieldTo(_classPrivateFieldGet2(this, _snapshots).push(options));
|
|
406
439
|
} catch (error) {
|
|
407
|
-
this
|
|
440
|
+
_classPrivateFieldGet2(this, _snapshots).cancel(options);
|
|
441
|
+
// Detecting and suggesting fix for errors;
|
|
442
|
+
await this.suggestionsForFix(error.message);
|
|
408
443
|
throw error;
|
|
409
444
|
}
|
|
410
445
|
}.call(this);
|
|
@@ -436,6 +471,48 @@ export class Percy {
|
|
|
436
471
|
if (syncMode) options.sync = syncMode;
|
|
437
472
|
return syncMode;
|
|
438
473
|
}
|
|
474
|
+
|
|
475
|
+
// This specific error will be hard coded
|
|
476
|
+
async checkForNoSnapshotCommandError() {
|
|
477
|
+
let isPercyStarted = false;
|
|
478
|
+
let containsSnapshotTaken = false;
|
|
479
|
+
logger.query(item => {
|
|
480
|
+
var _item$message, _item$message2, _item$message3;
|
|
481
|
+
isPercyStarted || (isPercyStarted = item === null || item === void 0 ? void 0 : (_item$message = item.message) === null || _item$message === void 0 ? void 0 : _item$message.includes('Percy has started'));
|
|
482
|
+
containsSnapshotTaken || (containsSnapshotTaken = item === null || item === void 0 ? void 0 : (_item$message2 = item.message) === null || _item$message2 === void 0 ? void 0 : _item$message2.includes('Snapshot taken'));
|
|
483
|
+
|
|
484
|
+
// This case happens when you directly upload it using cli-upload
|
|
485
|
+
containsSnapshotTaken || (containsSnapshotTaken = item === null || item === void 0 ? void 0 : (_item$message3 = item.message) === null || _item$message3 === void 0 ? void 0 : _item$message3.includes('Snapshot uploaded'));
|
|
486
|
+
return item;
|
|
487
|
+
});
|
|
488
|
+
if (isPercyStarted && !containsSnapshotTaken) {
|
|
489
|
+
// This is the case for No snapshot command called
|
|
490
|
+
_classPrivateMethodGet(this, _displaySuggestionLogs, _displaySuggestionLogs2).call(this, [{
|
|
491
|
+
failure_reason: 'Snapshot command was not called',
|
|
492
|
+
reason_message: 'Snapshot Command was not called. please check your CI for errors',
|
|
493
|
+
suggestion: 'Try using percy snapshot command to take snapshots',
|
|
494
|
+
reference_doc_link: ['https://www.browserstack.com/docs/percy/take-percy-snapshots/']
|
|
495
|
+
}]);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
async suggestionsForFix(errors, options = {}) {
|
|
499
|
+
try {
|
|
500
|
+
const suggestionResponse = await this.client.getErrorAnalysis(errors);
|
|
501
|
+
_classPrivateMethodGet(this, _displaySuggestionLogs, _displaySuggestionLogs2).call(this, suggestionResponse, options);
|
|
502
|
+
} catch (e) {
|
|
503
|
+
// Common error code for Proxy issues
|
|
504
|
+
const PROXY_CODES = ['ECONNREFUSED', 'ECONNRESET', 'EHOSTUNREACH'];
|
|
505
|
+
if (!!e.code && PROXY_CODES.includes(e.code)) {
|
|
506
|
+
// This can be due to proxy issue
|
|
507
|
+
this.log.error('percy.io might not be reachable, check network connection, proxy and ensure that percy.io is whitelisted.');
|
|
508
|
+
if (!_classPrivateMethodGet(this, _proxyEnabled, _proxyEnabled2).call(this)) {
|
|
509
|
+
this.log.error('If inside a proxied envirnment, please configure the following environment variables: HTTP_PROXY, [ and optionally HTTPS_PROXY if you need it ]. Refer to our documentation for more details');
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
this.log.error('Unable to analyze error logs');
|
|
513
|
+
this.log.debug(e);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
439
516
|
async sendBuildLogs() {
|
|
440
517
|
if (!process.env.PERCY_TOKEN) return;
|
|
441
518
|
try {
|
|
@@ -443,6 +520,7 @@ export class Percy {
|
|
|
443
520
|
const logsObject = {
|
|
444
521
|
clilogs: logger.query(log => !['ci'].includes(log.debug))
|
|
445
522
|
};
|
|
523
|
+
|
|
446
524
|
// Only add CI logs if not disabled voluntarily.
|
|
447
525
|
const sendCILogs = process.env.PERCY_CLIENT_ERROR_LOGS !== 'false';
|
|
448
526
|
if (sendCILogs) {
|
|
@@ -466,4 +544,32 @@ export class Percy {
|
|
|
466
544
|
}
|
|
467
545
|
}
|
|
468
546
|
}
|
|
547
|
+
function _displaySuggestionLogs2(suggestions, options = {}) {
|
|
548
|
+
if (!(suggestions !== null && suggestions !== void 0 && suggestions.length)) return;
|
|
549
|
+
suggestions.forEach(item => {
|
|
550
|
+
const failure = item === null || item === void 0 ? void 0 : item.failure_reason;
|
|
551
|
+
const failureReason = item === null || item === void 0 ? void 0 : item.reason_message;
|
|
552
|
+
const suggestion = item === null || item === void 0 ? void 0 : item.suggestion;
|
|
553
|
+
const referenceDocLinks = item === null || item === void 0 ? void 0 : item.reference_doc_link;
|
|
554
|
+
if (options !== null && options !== void 0 && options.snapshotLevel) {
|
|
555
|
+
this.log.warn(`Detected erorr for Snapshot: ${options === null || options === void 0 ? void 0 : options.snapshotName}`);
|
|
556
|
+
} else {
|
|
557
|
+
this.log.warn('Detected error for percy build');
|
|
558
|
+
}
|
|
559
|
+
this.log.warn(`Failure: ${failure}`);
|
|
560
|
+
this.log.warn(`Failure Reason: ${failureReason}`);
|
|
561
|
+
this.log.warn(`Suggestion: ${suggestion}`);
|
|
562
|
+
if ((referenceDocLinks === null || referenceDocLinks === void 0 ? void 0 : referenceDocLinks.length) > 0) {
|
|
563
|
+
this.log.warn('Refer to the below Doc Links for the same');
|
|
564
|
+
referenceDocLinks === null || referenceDocLinks === void 0 ? void 0 : referenceDocLinks.forEach(_docLink => {
|
|
565
|
+
this.log.warn(`* ${_docLink}`);
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
function _proxyEnabled2() {
|
|
571
|
+
return !!(getProxy({
|
|
572
|
+
protocol: 'https:'
|
|
573
|
+
}) || getProxy({}));
|
|
574
|
+
}
|
|
469
575
|
export default Percy;
|
package/dist/snapshot.js
CHANGED
|
@@ -234,6 +234,7 @@ export async function handleSyncJob(jobPromise, percy, type) {
|
|
|
234
234
|
data = await percy.client.getComparisonDetails(id);
|
|
235
235
|
}
|
|
236
236
|
} catch (e) {
|
|
237
|
+
await percy.suggestionsForFix(e.message);
|
|
237
238
|
data = {
|
|
238
239
|
error: e.message
|
|
239
240
|
};
|
|
@@ -453,7 +454,7 @@ export function createSnapshotsQueue(percy) {
|
|
|
453
454
|
};
|
|
454
455
|
})
|
|
455
456
|
// handle possible build errors returned by the API
|
|
456
|
-
.handle('error', (snapshot, error) => {
|
|
457
|
+
.handle('error', async (snapshot, error) => {
|
|
457
458
|
var _error$response, _error$response2, _error$response2$body;
|
|
458
459
|
let result = {
|
|
459
460
|
...snapshot,
|
|
@@ -478,12 +479,29 @@ export function createSnapshotsQueue(percy) {
|
|
|
478
479
|
let duplicate = (errors === null || errors === void 0 ? void 0 : errors.length) > 1 && errors[1].detail.includes('must be unique');
|
|
479
480
|
if (duplicate) {
|
|
480
481
|
if (process.env.PERCY_IGNORE_DUPLICATES !== 'true') {
|
|
481
|
-
|
|
482
|
+
let errMsg = `Ignored duplicate snapshot. ${errors[1].detail}`;
|
|
483
|
+
percy.log.warn(errMsg);
|
|
484
|
+
await percy.suggestionsForFix(errMsg, {
|
|
485
|
+
snapshotLevel: true,
|
|
486
|
+
snapshotName: name
|
|
487
|
+
});
|
|
482
488
|
}
|
|
483
489
|
return result;
|
|
484
490
|
}
|
|
485
|
-
|
|
491
|
+
let errMsg = `Encountered an error uploading snapshot: ${name}`;
|
|
492
|
+
percy.log.error(errMsg, meta);
|
|
486
493
|
percy.log.error(error, meta);
|
|
494
|
+
let snapshotErrors = [{
|
|
495
|
+
message: errMsg,
|
|
496
|
+
meta
|
|
497
|
+
}, {
|
|
498
|
+
message: error === null || error === void 0 ? void 0 : error.message,
|
|
499
|
+
meta
|
|
500
|
+
}];
|
|
501
|
+
await percy.suggestionsForFix(snapshotErrors, {
|
|
502
|
+
snapshotLevel: true,
|
|
503
|
+
snapshotName: name
|
|
504
|
+
});
|
|
487
505
|
if (snapshot.sync) snapshot.reject(error);
|
|
488
506
|
return result;
|
|
489
507
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@percy/core",
|
|
3
|
-
"version": "1.28.
|
|
3
|
+
"version": "1.28.9-beta.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -43,11 +43,11 @@
|
|
|
43
43
|
"test:types": "tsd"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@percy/client": "1.28.
|
|
47
|
-
"@percy/config": "1.28.
|
|
48
|
-
"@percy/dom": "1.28.
|
|
49
|
-
"@percy/logger": "1.28.
|
|
50
|
-
"@percy/webdriver-utils": "1.28.
|
|
46
|
+
"@percy/client": "1.28.9-beta.0",
|
|
47
|
+
"@percy/config": "1.28.9-beta.0",
|
|
48
|
+
"@percy/dom": "1.28.9-beta.0",
|
|
49
|
+
"@percy/logger": "1.28.9-beta.0",
|
|
50
|
+
"@percy/webdriver-utils": "1.28.9-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": "a1114f1e18518012f48756c9558a8e7895d2b3a9"
|
|
64
64
|
}
|