@percy/core
Advanced tools
Comparing version 1.28.2-beta.1 to 1.28.2-beta.2
@@ -258,2 +258,6 @@ // Common config options used in Percy commands | ||
}, | ||
retry: { | ||
type: 'boolean', | ||
default: false | ||
}, | ||
launchOptions: { | ||
@@ -361,2 +365,5 @@ type: 'object', | ||
$ref: '/config/discovery#/properties/devicePixelRatio' | ||
}, | ||
retry: { | ||
$ref: '/config/discovery#/properties/retry' | ||
} | ||
@@ -363,0 +370,0 @@ } |
import logger from '@percy/logger'; | ||
import Queue from './queue.js'; | ||
import { normalizeURL, hostnameMatches, createResource, createRootResource, createPercyCSSResource, createLogResource, yieldAll, snapshotLogName } from './utils.js'; | ||
import { normalizeURL, hostnameMatches, createResource, createRootResource, createPercyCSSResource, createLogResource, yieldAll, snapshotLogName, withRetries } from './utils.js'; | ||
@@ -343,36 +343,45 @@ // Logs verbose debug logs detailing various snapshot options. | ||
percy.log.debug(`Asset discovery Browser Page enable JS: ${assetDiscoveryPageEnableJS}`); | ||
// create a new browser page | ||
let page = yield percy.browser.page({ | ||
enableJavaScript: assetDiscoveryPageEnableJS, | ||
networkIdleTimeout: snapshot.discovery.networkIdleTimeout, | ||
requestHeaders: snapshot.discovery.requestHeaders, | ||
authorization: snapshot.discovery.authorization, | ||
userAgent: snapshot.discovery.userAgent, | ||
captureMockedServiceWorker: snapshot.discovery.captureMockedServiceWorker, | ||
meta: snapshot.meta, | ||
// enable network inteception | ||
intercept: { | ||
enableJavaScript: snapshot.enableJavaScript, | ||
disableCache: snapshot.discovery.disableCache, | ||
allowedHostnames: snapshot.discovery.allowedHostnames, | ||
disallowedHostnames: snapshot.discovery.disallowedHostnames, | ||
getResource: u => snapshot.resources.get(u) || cache.get(u), | ||
saveResource: r => { | ||
snapshot.resources.set(r.url, r); | ||
if (!r.root) { | ||
cache.set(r.url, r); | ||
await withRetries(async function* () { | ||
// create a new browser page | ||
let page = yield percy.browser.page({ | ||
enableJavaScript: assetDiscoveryPageEnableJS, | ||
networkIdleTimeout: snapshot.discovery.networkIdleTimeout, | ||
requestHeaders: snapshot.discovery.requestHeaders, | ||
authorization: snapshot.discovery.authorization, | ||
userAgent: snapshot.discovery.userAgent, | ||
captureMockedServiceWorker: snapshot.discovery.captureMockedServiceWorker, | ||
meta: snapshot.meta, | ||
// enable network inteception | ||
intercept: { | ||
enableJavaScript: snapshot.enableJavaScript, | ||
disableCache: snapshot.discovery.disableCache, | ||
allowedHostnames: snapshot.discovery.allowedHostnames, | ||
disallowedHostnames: snapshot.discovery.disallowedHostnames, | ||
getResource: u => snapshot.resources.get(u) || cache.get(u), | ||
saveResource: r => { | ||
snapshot.resources.set(r.url, r); | ||
if (!r.root) { | ||
cache.set(r.url, r); | ||
} | ||
} | ||
} | ||
}); | ||
try { | ||
yield* captureSnapshotResources(page, snapshot, { | ||
captureWidths: !snapshot.domSnapshot && percy.deferUploads, | ||
capture: callback, | ||
captureForDevices: percy.deviceDetails || [] | ||
}); | ||
} finally { | ||
// always close the page when done | ||
await page.close(); | ||
} | ||
}, { | ||
count: snapshot.discovery.retry ? 3 : 1, | ||
onRetry: () => { | ||
percy.log.info(`Retrying snapshot: ${snapshotLogName(snapshot.name, snapshot.meta)}`, snapshot.meta); | ||
}, | ||
signal: snapshot._ctrl.signal, | ||
throwOn: ['AbortError'] | ||
}); | ||
try { | ||
yield* captureSnapshotResources(page, snapshot, { | ||
captureWidths: !snapshot.domSnapshot && percy.deferUploads, | ||
capture: callback, | ||
captureForDevices: percy.deviceDetails || [] | ||
}); | ||
} finally { | ||
// always close the page when done | ||
await page.close(); | ||
} | ||
}).handle('error', ({ | ||
@@ -379,0 +388,0 @@ name, |
@@ -31,2 +31,3 @@ import { request as makeRequest } from '@percy/client/utils'; | ||
#aborted = new Set(); | ||
#finishedUrls = new Set(); | ||
constructor(page, options) { | ||
@@ -82,2 +83,8 @@ this.page = page; | ||
requests = Array.from(this.#requests.values()).filter(filter); | ||
// remove requests which are finished at least once | ||
// this happens when same request is made multiple times by browser in parallel and one of | ||
// them gets stuck in pending state in browser [ need to debug why ]. So we dont receive | ||
// loadingFinished event, causing it to show up in Active requests, but we can only store one | ||
// response per url so as long as we have captured one, we dont care about other such requests | ||
requests = requests.filter(req => !this.#finishedUrls.has(req.url)); | ||
return requests.length === 0; | ||
@@ -125,6 +132,8 @@ }, { | ||
requestId, | ||
interceptId | ||
interceptId, | ||
url | ||
}, keepPending) { | ||
this.#requests.delete(requestId); | ||
this.#authentications.delete(interceptId); | ||
this.#finishedUrls.add(url); | ||
if (!keepPending) { | ||
@@ -131,0 +140,0 @@ this.#pending.delete(requestId); |
@@ -125,5 +125,11 @@ function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); } | ||
let exists = this.cancel(item); | ||
task.ctrl = new AbortController(); | ||
// duplicate abortion controller on task, so it can can be used in further | ||
// generators and can be cancelled internally | ||
// TODO fix this for non object item usecase | ||
if (typeof item === 'object' && !Array.isArray(item) && item !== null) { | ||
item._ctrl = task.ctrl; | ||
} | ||
task.item = item = _classPrivateFieldGet(this, _handlers).push ? _classPrivateFieldGet(this, _handlers).push(item, exists) : item; | ||
task.handler = () => _classPrivateFieldGet(this, _handlers).task ? _classPrivateFieldGet(this, _handlers).task(item, ...args) : item; | ||
task.ctrl = new AbortController(); | ||
@@ -130,0 +136,0 @@ // queue this task & maybe dequeue the next task |
@@ -132,3 +132,4 @@ import logger from '@percy/logger'; | ||
captureSrcset: config.discovery.captureSrcset, | ||
userAgent: config.discovery.userAgent | ||
userAgent: config.discovery.userAgent, | ||
retry: config.discovery.retry | ||
} | ||
@@ -135,0 +136,0 @@ }, options], (path, prev, next) => { |
@@ -331,2 +331,25 @@ import EventEmitter from 'events'; | ||
} | ||
export async function withRetries(fn, { | ||
count, | ||
onRetry, | ||
signal, | ||
throwOn | ||
}) { | ||
count || (count = 1); // default a single try | ||
let run = 0; | ||
while (true) { | ||
run += 1; | ||
try { | ||
return await generatePromise(fn, signal); | ||
} catch (e) { | ||
// if this error should not be retried on, we want to skip errors | ||
let throwError = throwOn === null || throwOn === void 0 ? void 0 : throwOn.includes(e.name); | ||
if (!throwError && run < count) { | ||
await (onRetry === null || onRetry === void 0 ? void 0 : onRetry()); | ||
continue; | ||
} | ||
throw e; | ||
} | ||
} | ||
} | ||
export function snapshotLogName(name, meta) { | ||
@@ -333,0 +356,0 @@ var _meta$snapshot; |
{ | ||
"name": "@percy/core", | ||
"version": "1.28.2-beta.1", | ||
"version": "1.28.2-beta.2", | ||
"license": "MIT", | ||
@@ -46,7 +46,7 @@ "repository": { | ||
"dependencies": { | ||
"@percy/client": "1.28.2-beta.1", | ||
"@percy/config": "1.28.2-beta.1", | ||
"@percy/dom": "1.28.2-beta.1", | ||
"@percy/logger": "1.28.2-beta.1", | ||
"@percy/webdriver-utils": "1.28.2-beta.1", | ||
"@percy/client": "1.28.2-beta.2", | ||
"@percy/config": "1.28.2-beta.2", | ||
"@percy/dom": "1.28.2-beta.2", | ||
"@percy/logger": "1.28.2-beta.2", | ||
"@percy/webdriver-utils": "1.28.2-beta.2", | ||
"content-disposition": "^0.5.4", | ||
@@ -62,3 +62,3 @@ "cross-spawn": "^7.0.3", | ||
}, | ||
"gitHead": "c4d0637366dbc28eeda234f93d44424d9c565f49" | ||
"gitHead": "7c2bdccd896be9da7d07dd30ead802fbb4ca9fab" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
204193
4932
+ Added@percy/client@1.28.2-beta.2(transitive)
+ Added@percy/config@1.28.2-beta.2(transitive)
+ Added@percy/dom@1.28.2-beta.2(transitive)
+ Added@percy/env@1.28.2-beta.2(transitive)
+ Added@percy/logger@1.28.2-beta.2(transitive)
+ Added@percy/sdk-utils@1.28.2-beta.2(transitive)
+ Added@percy/webdriver-utils@1.28.2-beta.2(transitive)
- Removed@percy/client@1.28.2-beta.1(transitive)
- Removed@percy/config@1.28.2-beta.1(transitive)
- Removed@percy/dom@1.28.2-beta.1(transitive)
- Removed@percy/env@1.28.2-beta.1(transitive)
- Removed@percy/logger@1.28.2-beta.1(transitive)
- Removed@percy/sdk-utils@1.28.2-beta.1(transitive)
- Removed@percy/webdriver-utils@1.28.2-beta.1(transitive)
Updated@percy/client@1.28.2-beta.2
Updated@percy/config@1.28.2-beta.2
Updated@percy/dom@1.28.2-beta.2
Updated@percy/logger@1.28.2-beta.2