playwright-core 1.54.0-alpha-2025-06-20 → 1.54.0-alpha-1750421372000
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/lib/client/playwright.js +2 -2
- package/lib/inProcessFactory.js +2 -2
- package/lib/protocol/validator.js +2 -2
- package/lib/remote/playwrightConnection.js +27 -168
- package/lib/remote/playwrightServer.js +173 -27
- package/lib/server/android/android.js +31 -25
- package/lib/server/bidi/bidiChromium.js +1 -1
- package/lib/server/bidi/bidiFirefox.js +4 -1
- package/lib/server/browser.js +13 -12
- package/lib/server/browserContext.js +49 -46
- package/lib/server/browserType.js +26 -19
- package/lib/server/chromium/chromium.js +9 -7
- package/lib/server/chromium/videoRecorder.js +2 -1
- package/lib/server/debugController.js +1 -1
- package/lib/server/dispatchers/androidDispatcher.js +4 -4
- package/lib/server/dispatchers/browserContextDispatcher.js +1 -1
- package/lib/server/dispatchers/browserDispatcher.js +2 -2
- package/lib/server/dispatchers/electronDispatcher.js +2 -2
- package/lib/server/dispatchers/frameDispatcher.js +1 -1
- package/lib/server/dispatchers/localUtilsDispatcher.js +1 -2
- package/lib/server/dispatchers/playwrightDispatcher.js +5 -21
- package/lib/server/dom.js +3 -4
- package/lib/server/electron/electron.js +15 -16
- package/lib/server/fetch.js +12 -26
- package/lib/server/firefox/ffPage.js +0 -1
- package/lib/server/frames.js +93 -92
- package/lib/server/helper.js +1 -1
- package/lib/server/page.js +48 -42
- package/lib/server/playwright.js +2 -2
- package/lib/server/recorder/recorderApp.js +1 -1
- package/lib/server/registry/index.js +7 -20
- package/lib/server/screenshotter.js +17 -31
- package/lib/server/socksClientCertificatesInterceptor.js +7 -3
- package/lib/server/trace/viewer/traceViewer.js +1 -1
- package/lib/server/transport.js +3 -7
- package/lib/server/utils/processLauncher.js +1 -1
- package/lib/vite/htmlReport/index.html +9 -9
- package/package.json +1 -1
package/lib/server/page.js
CHANGED
|
@@ -55,7 +55,6 @@ var import_manualPromise = require("../utils/isomorphic/manualPromise");
|
|
|
55
55
|
var import_utilityScriptSerializers = require("../utils/isomorphic/utilityScriptSerializers");
|
|
56
56
|
var import_callLog = require("./callLog");
|
|
57
57
|
var rawBindingsControllerSource = __toESM(require("../generated/bindingsControllerSource"));
|
|
58
|
-
var import_protocolError = require("./protocolError");
|
|
59
58
|
class Page extends import_instrumentation.SdkObject {
|
|
60
59
|
constructor(delegate, browserContext) {
|
|
61
60
|
super(browserContext, "page");
|
|
@@ -250,27 +249,30 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
250
249
|
this.emitOnContextOnceInitialized(import_browserContext.BrowserContext.Events.Console, message);
|
|
251
250
|
}
|
|
252
251
|
async reload(metadata, options) {
|
|
253
|
-
const controller = new import_progress.ProgressController(metadata, this);
|
|
254
|
-
return controller.run((progress) => this.mainFrame().raceNavigationAction(progress,
|
|
252
|
+
const controller = new import_progress.ProgressController(metadata, this, "strict");
|
|
253
|
+
return controller.run((progress) => this.mainFrame().raceNavigationAction(progress, async () => {
|
|
255
254
|
const [response] = await Promise.all([
|
|
256
255
|
// Reload must be a new document, and should not be confused with a stray pushState.
|
|
257
256
|
this.mainFrame()._waitForNavigation(progress, true, options),
|
|
258
|
-
this.delegate.reload()
|
|
257
|
+
progress.race(this.delegate.reload())
|
|
259
258
|
]);
|
|
260
259
|
return response;
|
|
261
260
|
}), options.timeout);
|
|
262
261
|
}
|
|
263
262
|
async goBack(metadata, options) {
|
|
264
|
-
const controller = new import_progress.ProgressController(metadata, this);
|
|
265
|
-
return controller.run((progress) => this.mainFrame().raceNavigationAction(progress,
|
|
263
|
+
const controller = new import_progress.ProgressController(metadata, this, "strict");
|
|
264
|
+
return controller.run((progress) => this.mainFrame().raceNavigationAction(progress, async () => {
|
|
266
265
|
let error;
|
|
267
266
|
const waitPromise = this.mainFrame()._waitForNavigation(progress, false, options).catch((e) => {
|
|
268
267
|
error = e;
|
|
269
268
|
return null;
|
|
270
269
|
});
|
|
271
|
-
const result = await this.delegate.goBack();
|
|
272
|
-
if (!result)
|
|
270
|
+
const result = await progress.race(this.delegate.goBack());
|
|
271
|
+
if (!result) {
|
|
272
|
+
waitPromise.catch(() => {
|
|
273
|
+
});
|
|
273
274
|
return null;
|
|
275
|
+
}
|
|
274
276
|
const response = await waitPromise;
|
|
275
277
|
if (error)
|
|
276
278
|
throw error;
|
|
@@ -278,16 +280,19 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
278
280
|
}), options.timeout);
|
|
279
281
|
}
|
|
280
282
|
async goForward(metadata, options) {
|
|
281
|
-
const controller = new import_progress.ProgressController(metadata, this);
|
|
282
|
-
return controller.run((progress) => this.mainFrame().raceNavigationAction(progress,
|
|
283
|
+
const controller = new import_progress.ProgressController(metadata, this, "strict");
|
|
284
|
+
return controller.run((progress) => this.mainFrame().raceNavigationAction(progress, async () => {
|
|
283
285
|
let error;
|
|
284
286
|
const waitPromise = this.mainFrame()._waitForNavigation(progress, false, options).catch((e) => {
|
|
285
287
|
error = e;
|
|
286
288
|
return null;
|
|
287
289
|
});
|
|
288
|
-
const result = await this.delegate.goForward();
|
|
289
|
-
if (!result)
|
|
290
|
+
const result = await progress.race(this.delegate.goForward());
|
|
291
|
+
if (!result) {
|
|
292
|
+
waitPromise.catch(() => {
|
|
293
|
+
});
|
|
290
294
|
return null;
|
|
295
|
+
}
|
|
291
296
|
const response = await waitPromise;
|
|
292
297
|
if (error)
|
|
293
298
|
throw error;
|
|
@@ -441,11 +446,11 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
441
446
|
return await locator.frame.rafrafTimeoutScreenshotElementWithProgress(progress, locator.selector, timeout, options || {});
|
|
442
447
|
} : async (progress, timeout) => {
|
|
443
448
|
await this.performActionPreChecks(progress);
|
|
444
|
-
await this.mainFrame().rafrafTimeout(timeout);
|
|
449
|
+
await this.mainFrame().rafrafTimeout(progress, timeout);
|
|
445
450
|
return await this.screenshotter.screenshotPage(progress, options || {});
|
|
446
451
|
};
|
|
447
452
|
const comparator = (0, import_comparators.getComparator)("image/png");
|
|
448
|
-
const controller = new import_progress.ProgressController(metadata, this);
|
|
453
|
+
const controller = new import_progress.ProgressController(metadata, this, "strict");
|
|
449
454
|
if (!options.expected && options.isNot)
|
|
450
455
|
return { errorMessage: '"not" matcher requires expected result' };
|
|
451
456
|
try {
|
|
@@ -476,7 +481,6 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
476
481
|
progress.log(` generating new stable screenshot expectation`);
|
|
477
482
|
let isFirstIteration = true;
|
|
478
483
|
while (true) {
|
|
479
|
-
progress.throwIfAborted();
|
|
480
484
|
if (this.isClosed())
|
|
481
485
|
throw new Error("The page has closed");
|
|
482
486
|
const screenshotTimeout = pollIntervals.shift() ?? 1e3;
|
|
@@ -484,6 +488,8 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
484
488
|
progress.log(`waiting ${screenshotTimeout}ms before taking screenshot`);
|
|
485
489
|
previous = actual;
|
|
486
490
|
actual = await rafrafScreenshot(progress, screenshotTimeout).catch((e) => {
|
|
491
|
+
if (this.mainFrame().isNonRetriableError(e))
|
|
492
|
+
throw e;
|
|
487
493
|
progress.log(`failed to take screenshot - ` + e.message);
|
|
488
494
|
return void 0;
|
|
489
495
|
});
|
|
@@ -623,10 +629,13 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
623
629
|
markAsServerSideOnly() {
|
|
624
630
|
this._isServerSideOnly = true;
|
|
625
631
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
632
|
+
snapshotForAI(metadata) {
|
|
633
|
+
const controller = new import_progress.ProgressController(metadata, this, "strict");
|
|
634
|
+
return controller.run(async (progress) => {
|
|
635
|
+
this.lastSnapshotFrameIds = [];
|
|
636
|
+
const snapshot = await snapshotFrameForAI(progress, this.mainFrame(), 0, this.lastSnapshotFrameIds);
|
|
637
|
+
return snapshot.join("\n");
|
|
638
|
+
});
|
|
630
639
|
}
|
|
631
640
|
}
|
|
632
641
|
class Worker extends import_instrumentation.SdkObject {
|
|
@@ -767,28 +776,25 @@ class FrameThrottler {
|
|
|
767
776
|
}
|
|
768
777
|
}
|
|
769
778
|
}
|
|
770
|
-
async function snapshotFrameForAI(
|
|
771
|
-
const
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
const
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
}, frameOrdinal ? "f" + frameOrdinal : "");
|
|
783
|
-
if (snapshotOrRetry === true)
|
|
784
|
-
return continuePolling;
|
|
785
|
-
return snapshotOrRetry;
|
|
786
|
-
} catch (e) {
|
|
787
|
-
if ((0, import_progress.isAbortError)(e) || (0, import_protocolError.isSessionClosedError)(e) || js.isJavaScriptErrorInEvaluate(e))
|
|
788
|
-
throw e;
|
|
779
|
+
async function snapshotFrameForAI(progress, frame, frameOrdinal, frameIds) {
|
|
780
|
+
const snapshot = await frame.retryWithProgressAndTimeouts(progress, [1e3, 2e3, 4e3, 8e3], async (continuePolling) => {
|
|
781
|
+
try {
|
|
782
|
+
const context = await progress.race(frame._utilityContext());
|
|
783
|
+
const injectedScript = await progress.race(context.injectedScript());
|
|
784
|
+
const snapshotOrRetry = await progress.race(injectedScript.evaluate((injected, refPrefix) => {
|
|
785
|
+
const node = injected.document.body;
|
|
786
|
+
if (!node)
|
|
787
|
+
return true;
|
|
788
|
+
return injected.ariaSnapshot(node, { forAI: true, refPrefix });
|
|
789
|
+
}, frameOrdinal ? "f" + frameOrdinal : ""));
|
|
790
|
+
if (snapshotOrRetry === true)
|
|
789
791
|
return continuePolling;
|
|
790
|
-
|
|
791
|
-
})
|
|
792
|
+
return snapshotOrRetry;
|
|
793
|
+
} catch (e) {
|
|
794
|
+
if (frame.isNonRetriableError(e))
|
|
795
|
+
throw e;
|
|
796
|
+
return continuePolling;
|
|
797
|
+
}
|
|
792
798
|
});
|
|
793
799
|
const lines = snapshot.split("\n");
|
|
794
800
|
const result = [];
|
|
@@ -802,7 +808,7 @@ async function snapshotFrameForAI(metadata, frame, frameOrdinal, frameIds) {
|
|
|
802
808
|
const ref = match[2];
|
|
803
809
|
const frameSelector = `aria-ref=${ref} >> internal:control=enter-frame`;
|
|
804
810
|
const frameBodySelector = `${frameSelector} >> body`;
|
|
805
|
-
const child = await frame.selectors.resolveFrameForSelector(frameBodySelector, { strict: true });
|
|
811
|
+
const child = await progress.race(frame.selectors.resolveFrameForSelector(frameBodySelector, { strict: true }));
|
|
806
812
|
if (!child) {
|
|
807
813
|
result.push(line);
|
|
808
814
|
continue;
|
|
@@ -810,7 +816,7 @@ async function snapshotFrameForAI(metadata, frame, frameOrdinal, frameIds) {
|
|
|
810
816
|
const frameOrdinal2 = frameIds.length + 1;
|
|
811
817
|
frameIds.push(child.frame._id);
|
|
812
818
|
try {
|
|
813
|
-
const childSnapshot = await snapshotFrameForAI(
|
|
819
|
+
const childSnapshot = await snapshotFrameForAI(progress, child.frame, frameOrdinal2, frameIds);
|
|
814
820
|
result.push(line + ":", ...childSnapshot.map((l) => leadingSpace + " " + l));
|
|
815
821
|
} catch {
|
|
816
822
|
result.push(line);
|
package/lib/server/playwright.js
CHANGED
|
@@ -50,8 +50,8 @@ class Playwright extends import_instrumentation.SdkObject {
|
|
|
50
50
|
}
|
|
51
51
|
}, null);
|
|
52
52
|
this.chromium = new import_chromium.Chromium(this);
|
|
53
|
-
this.
|
|
54
|
-
this.
|
|
53
|
+
this._bidiChromium = new import_bidiChromium.BidiChromium(this);
|
|
54
|
+
this._bidiFirefox = new import_bidiFirefox.BidiFirefox(this);
|
|
55
55
|
this.firefox = new import_firefox.Firefox(this);
|
|
56
56
|
this.webkit = new import_webkit.WebKit(this);
|
|
57
57
|
this.electron = new import_electron.Electron(this);
|
|
@@ -127,7 +127,7 @@ class RecorderApp extends import_events.EventEmitter {
|
|
|
127
127
|
timeout: 0
|
|
128
128
|
}
|
|
129
129
|
});
|
|
130
|
-
const controller = new import_progress.ProgressController((0, import_instrumentation.serverSideCallMetadata)(), context._browser);
|
|
130
|
+
const controller = new import_progress.ProgressController((0, import_instrumentation.serverSideCallMetadata)(), context._browser, "strict");
|
|
131
131
|
await controller.run(async (progress) => {
|
|
132
132
|
await context._browser._defaultContext._loadDefaultContextAsIs(progress);
|
|
133
133
|
});
|
|
@@ -399,7 +399,8 @@ const DOWNLOAD_PATHS = {
|
|
|
399
399
|
"win64": "builds/android/%s/android.zip"
|
|
400
400
|
},
|
|
401
401
|
// TODO(bidi): implement downloads.
|
|
402
|
-
"
|
|
402
|
+
"_bidiFirefox": {},
|
|
403
|
+
"_bidiChromium": {}
|
|
403
404
|
};
|
|
404
405
|
const registryDirectory = (() => {
|
|
405
406
|
let result;
|
|
@@ -654,8 +655,8 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
|
|
|
654
655
|
}));
|
|
655
656
|
this._executables.push({
|
|
656
657
|
type: "browser",
|
|
657
|
-
name: "
|
|
658
|
-
browserName: "
|
|
658
|
+
name: "_bidiChromium",
|
|
659
|
+
browserName: "_bidiChromium",
|
|
659
660
|
directory: chromium.dir,
|
|
660
661
|
executablePath: () => chromiumExecutable,
|
|
661
662
|
executablePathOrDie: (sdkLanguage) => executablePathOrDie("chromium", chromiumExecutable, chromium.installByDefault, sdkLanguage),
|
|
@@ -775,20 +776,6 @@ ${(0, import_ascii.wrapInASCIIBox)(prettyMessage, 1)}`);
|
|
|
775
776
|
_dependencyGroup: "tools",
|
|
776
777
|
_isHermeticInstallation: true
|
|
777
778
|
});
|
|
778
|
-
this._executables.push({
|
|
779
|
-
type: "browser",
|
|
780
|
-
name: "bidi",
|
|
781
|
-
browserName: "bidi",
|
|
782
|
-
directory: void 0,
|
|
783
|
-
executablePath: () => void 0,
|
|
784
|
-
executablePathOrDie: () => "",
|
|
785
|
-
installType: "none",
|
|
786
|
-
_validateHostRequirements: () => Promise.resolve(),
|
|
787
|
-
downloadURLs: [],
|
|
788
|
-
_install: () => Promise.resolve(),
|
|
789
|
-
_dependencyGroup: "tools",
|
|
790
|
-
_isHermeticInstallation: true
|
|
791
|
-
});
|
|
792
779
|
}
|
|
793
780
|
_createChromiumChannel(name, lookAt, install) {
|
|
794
781
|
const executablePath = (sdkLanguage, shouldThrow) => {
|
|
@@ -859,7 +846,7 @@ Run "${buildPlaywrightCLICommand(sdkLanguage, "install " + name)}"` : "";
|
|
|
859
846
|
return {
|
|
860
847
|
type: "channel",
|
|
861
848
|
name,
|
|
862
|
-
browserName: "
|
|
849
|
+
browserName: "_bidiFirefox",
|
|
863
850
|
directory: void 0,
|
|
864
851
|
executablePath: (sdkLanguage) => executablePath(sdkLanguage, false),
|
|
865
852
|
executablePathOrDie: (sdkLanguage) => executablePath(sdkLanguage, true),
|
|
@@ -874,7 +861,7 @@ Run "${buildPlaywrightCLICommand(sdkLanguage, "install " + name)}"` : "";
|
|
|
874
861
|
const suffix = lookAt[process.platform];
|
|
875
862
|
if (!suffix) {
|
|
876
863
|
if (shouldThrow)
|
|
877
|
-
throw new Error(`
|
|
864
|
+
throw new Error(`Chromium distribution '${name}' is not supported on ${process.platform}`);
|
|
878
865
|
return void 0;
|
|
879
866
|
}
|
|
880
867
|
const prefixes = process.platform === "win32" ? [
|
|
@@ -900,7 +887,7 @@ Run "${buildPlaywrightCLICommand(sdkLanguage, "install " + name)}"` : "";
|
|
|
900
887
|
return {
|
|
901
888
|
type: "channel",
|
|
902
889
|
name,
|
|
903
|
-
browserName: "
|
|
890
|
+
browserName: "_bidiChromium",
|
|
904
891
|
directory: void 0,
|
|
905
892
|
executablePath: (sdkLanguage) => executablePath(sdkLanguage, false),
|
|
906
893
|
executablePathOrDie: (sdkLanguage) => executablePath(sdkLanguage, true),
|
|
@@ -166,7 +166,6 @@ class Screenshotter {
|
|
|
166
166
|
progress.log("taking page screenshot");
|
|
167
167
|
const viewportSize = await this._originalViewportSize(progress);
|
|
168
168
|
await this._preparePageForScreenshot(progress, this._page.mainFrame(), options.style, options.caret !== "initial", options.animations === "disabled");
|
|
169
|
-
progress.throwIfAborted();
|
|
170
169
|
if (options.fullPage) {
|
|
171
170
|
const fullPageSize = await this._fullPageSize(progress);
|
|
172
171
|
let documentRect = { x: 0, y: 0, width: fullPageSize.width, height: fullPageSize.height };
|
|
@@ -174,13 +173,11 @@ class Screenshotter {
|
|
|
174
173
|
if (options.clip)
|
|
175
174
|
documentRect = trimClipToSize(options.clip, documentRect);
|
|
176
175
|
const buffer2 = await this._screenshot(progress, format, documentRect, void 0, fitsViewport, options);
|
|
177
|
-
progress.throwIfAborted();
|
|
178
176
|
await this._restorePageAfterScreenshot();
|
|
179
177
|
return buffer2;
|
|
180
178
|
}
|
|
181
179
|
const viewportRect = options.clip ? trimClipToSize(options.clip, viewportSize) : { x: 0, y: 0, ...viewportSize };
|
|
182
180
|
const buffer = await this._screenshot(progress, format, void 0, viewportRect, true, options);
|
|
183
|
-
progress.throwIfAborted();
|
|
184
181
|
await this._restorePageAfterScreenshot();
|
|
185
182
|
return buffer;
|
|
186
183
|
});
|
|
@@ -191,25 +188,21 @@ class Screenshotter {
|
|
|
191
188
|
progress.log("taking element screenshot");
|
|
192
189
|
const viewportSize = await this._originalViewportSize(progress);
|
|
193
190
|
await this._preparePageForScreenshot(progress, handle._frame, options.style, options.caret !== "initial", options.animations === "disabled");
|
|
194
|
-
progress.throwIfAborted();
|
|
195
191
|
await handle._waitAndScrollIntoViewIfNeeded(
|
|
196
192
|
progress,
|
|
197
193
|
true
|
|
198
194
|
/* waitForVisible */
|
|
199
195
|
);
|
|
200
|
-
progress.
|
|
201
|
-
const boundingBox = await handle.boundingBox();
|
|
196
|
+
const boundingBox = await progress.race(handle.boundingBox());
|
|
202
197
|
(0, import_utils.assert)(boundingBox, "Node is either not visible or not an HTMLElement");
|
|
203
198
|
(0, import_utils.assert)(boundingBox.width !== 0, "Node has 0 width.");
|
|
204
199
|
(0, import_utils.assert)(boundingBox.height !== 0, "Node has 0 height.");
|
|
205
200
|
const fitsViewport = boundingBox.width <= viewportSize.width && boundingBox.height <= viewportSize.height;
|
|
206
|
-
progress.throwIfAborted();
|
|
207
201
|
const scrollOffset = await this._page.mainFrame().waitForFunctionValueInUtility(progress, () => ({ x: window.scrollX, y: window.scrollY }));
|
|
208
202
|
const documentRect = { ...boundingBox };
|
|
209
203
|
documentRect.x += scrollOffset.x;
|
|
210
204
|
documentRect.y += scrollOffset.y;
|
|
211
205
|
const buffer = await this._screenshot(progress, format, import_helper.helper.enclosingIntRect(documentRect), void 0, fitsViewport, options);
|
|
212
|
-
progress.throwIfAborted();
|
|
213
206
|
await this._restorePageAfterScreenshot();
|
|
214
207
|
return buffer;
|
|
215
208
|
});
|
|
@@ -218,61 +211,54 @@ class Screenshotter {
|
|
|
218
211
|
if (disableAnimations)
|
|
219
212
|
progress.log(" disabled all CSS animations");
|
|
220
213
|
const syncAnimations = this._page.delegate.shouldToggleStyleSheetToSyncAnimations();
|
|
221
|
-
|
|
214
|
+
progress.cleanupWhenAborted(() => this._restorePageAfterScreenshot());
|
|
215
|
+
await progress.race(this._page.safeNonStallingEvaluateInAllFrames("(" + inPagePrepareForScreenshots.toString() + `)(${JSON.stringify(screenshotStyle)}, ${hideCaret}, ${disableAnimations}, ${syncAnimations})`, "utility"));
|
|
222
216
|
if (!process.env.PW_TEST_SCREENSHOT_NO_FONTS_READY) {
|
|
223
217
|
progress.log("waiting for fonts to load...");
|
|
224
|
-
await frame.nonStallingEvaluateInExistingContext("document.fonts.ready", "utility").catch(() => {
|
|
225
|
-
});
|
|
218
|
+
await progress.race(frame.nonStallingEvaluateInExistingContext("document.fonts.ready", "utility").catch(() => {
|
|
219
|
+
}));
|
|
226
220
|
progress.log("fonts loaded");
|
|
227
221
|
}
|
|
228
|
-
progress.cleanupWhenAborted(() => this._restorePageAfterScreenshot());
|
|
229
222
|
}
|
|
230
223
|
async _restorePageAfterScreenshot() {
|
|
231
224
|
await this._page.safeNonStallingEvaluateInAllFrames("window.__pwCleanupScreenshot && window.__pwCleanupScreenshot()", "utility");
|
|
232
225
|
}
|
|
233
226
|
async _maskElements(progress, options) {
|
|
227
|
+
if (!options.mask || !options.mask.length)
|
|
228
|
+
return () => Promise.resolve();
|
|
234
229
|
const framesToParsedSelectors = new import_multimap.MultiMap();
|
|
235
230
|
const cleanup = async () => {
|
|
236
231
|
await Promise.all([...framesToParsedSelectors.keys()].map(async (frame) => {
|
|
237
232
|
await frame.hideHighlight();
|
|
238
233
|
}));
|
|
239
234
|
};
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
await Promise.all((options.mask || []).map(async ({ frame, selector }) => {
|
|
235
|
+
progress.cleanupWhenAborted(cleanup);
|
|
236
|
+
await progress.race(Promise.all((options.mask || []).map(async ({ frame, selector }) => {
|
|
243
237
|
const pair = await frame.selectors.resolveFrameForSelector(selector);
|
|
244
238
|
if (pair)
|
|
245
239
|
framesToParsedSelectors.set(pair.frame, pair.info.parsed);
|
|
246
|
-
}));
|
|
247
|
-
progress.
|
|
248
|
-
await Promise.all([...framesToParsedSelectors.keys()].map(async (frame) => {
|
|
240
|
+
})));
|
|
241
|
+
await progress.race(Promise.all([...framesToParsedSelectors.keys()].map(async (frame) => {
|
|
249
242
|
await frame.maskSelectors(framesToParsedSelectors.get(frame), options.maskColor || "#F0F");
|
|
250
|
-
}));
|
|
251
|
-
progress.cleanupWhenAborted(cleanup);
|
|
243
|
+
})));
|
|
252
244
|
return cleanup;
|
|
253
245
|
}
|
|
254
246
|
async _screenshot(progress, format, documentRect, viewportRect, fitsViewport, options) {
|
|
255
247
|
if (options.__testHookBeforeScreenshot)
|
|
256
|
-
await options.__testHookBeforeScreenshot();
|
|
257
|
-
progress.throwIfAborted();
|
|
248
|
+
await progress.race(options.__testHookBeforeScreenshot());
|
|
258
249
|
const shouldSetDefaultBackground = options.omitBackground && format === "png";
|
|
259
250
|
if (shouldSetDefaultBackground) {
|
|
260
|
-
await this._page.delegate.setBackgroundColor({ r: 0, g: 0, b: 0, a: 0 });
|
|
261
251
|
progress.cleanupWhenAborted(() => this._page.delegate.setBackgroundColor());
|
|
252
|
+
await progress.race(this._page.delegate.setBackgroundColor({ r: 0, g: 0, b: 0, a: 0 }));
|
|
262
253
|
}
|
|
263
|
-
progress.throwIfAborted();
|
|
264
254
|
const cleanupHighlight = await this._maskElements(progress, options);
|
|
265
|
-
progress.throwIfAborted();
|
|
266
255
|
const quality = format === "jpeg" ? options.quality ?? 80 : void 0;
|
|
267
|
-
const buffer = await this._page.delegate.takeScreenshot(progress, format, documentRect, viewportRect, quality, fitsViewport, options.scale || "device");
|
|
268
|
-
progress.throwIfAborted();
|
|
256
|
+
const buffer = await progress.race(this._page.delegate.takeScreenshot(progress, format, documentRect, viewportRect, quality, fitsViewport, options.scale || "device"));
|
|
269
257
|
await cleanupHighlight();
|
|
270
|
-
progress.throwIfAborted();
|
|
271
258
|
if (shouldSetDefaultBackground)
|
|
272
|
-
await this._page.delegate.setBackgroundColor();
|
|
273
|
-
progress.throwIfAborted();
|
|
259
|
+
await progress.race(this._page.delegate.setBackgroundColor());
|
|
274
260
|
if (options.__testHookAfterScreenshot)
|
|
275
|
-
await options.__testHookAfterScreenshot();
|
|
261
|
+
await progress.race(options.__testHookAfterScreenshot());
|
|
276
262
|
return buffer;
|
|
277
263
|
}
|
|
278
264
|
}
|
|
@@ -261,9 +261,13 @@ class ClientCertificatesProxy {
|
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
263
|
}
|
|
264
|
-
async
|
|
265
|
-
const
|
|
266
|
-
|
|
264
|
+
static async create(contextOptions) {
|
|
265
|
+
const proxy = new ClientCertificatesProxy(contextOptions);
|
|
266
|
+
await proxy._socksProxy.listen(0, "127.0.0.1");
|
|
267
|
+
return proxy;
|
|
268
|
+
}
|
|
269
|
+
proxySettings() {
|
|
270
|
+
return { server: `socks5://127.0.0.1:${this._socksProxy.port()}` };
|
|
267
271
|
}
|
|
268
272
|
async close() {
|
|
269
273
|
await this._socksProxy.close();
|
|
@@ -158,7 +158,7 @@ async function openTraceViewerApp(url, browserName, options) {
|
|
|
158
158
|
timeout: 0
|
|
159
159
|
}
|
|
160
160
|
});
|
|
161
|
-
const controller = new import_progress.ProgressController((0, import_instrumentation.serverSideCallMetadata)(), context._browser);
|
|
161
|
+
const controller = new import_progress.ProgressController((0, import_instrumentation.serverSideCallMetadata)(), context._browser, "strict");
|
|
162
162
|
await controller.run(async (progress) => {
|
|
163
163
|
await context._browser._defaultContext._loadDefaultContextAsIs(progress);
|
|
164
164
|
});
|
package/lib/server/transport.js
CHANGED
|
@@ -99,12 +99,8 @@ class WebSocketTransport {
|
|
|
99
99
|
const logUrl = stripQueryParams(url);
|
|
100
100
|
progress?.log(`<ws connecting> ${logUrl}`);
|
|
101
101
|
const transport = new WebSocketTransport(progress, url, logUrl, { ...options, followRedirects: !!options.followRedirects && hadRedirects });
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (!success)
|
|
105
|
-
await transport.closeAndWait().catch((e) => null);
|
|
106
|
-
});
|
|
107
|
-
const result = await new Promise((fulfill, reject) => {
|
|
102
|
+
progress?.cleanupWhenAborted(() => transport.closeAndWait());
|
|
103
|
+
const resultPromise = new Promise((fulfill, reject) => {
|
|
108
104
|
transport._ws.on("open", async () => {
|
|
109
105
|
progress?.log(`<ws connected> ${logUrl}`);
|
|
110
106
|
fulfill({ transport });
|
|
@@ -136,6 +132,7 @@ ${Buffer.concat(chunks)}` : errorPrefix;
|
|
|
136
132
|
});
|
|
137
133
|
});
|
|
138
134
|
});
|
|
135
|
+
const result = progress ? await progress.race(resultPromise) : await resultPromise;
|
|
139
136
|
if (result.redirect) {
|
|
140
137
|
const newHeaders = Object.fromEntries(Object.entries(options.headers || {}).filter(([name]) => {
|
|
141
138
|
return !name.includes("access-key") && name.toLowerCase() !== "authorization";
|
|
@@ -148,7 +145,6 @@ ${Buffer.concat(chunks)}` : errorPrefix;
|
|
|
148
145
|
/* hadRedirects */
|
|
149
146
|
);
|
|
150
147
|
}
|
|
151
|
-
success = true;
|
|
152
148
|
return transport;
|
|
153
149
|
}
|
|
154
150
|
send(message) {
|
|
@@ -132,7 +132,7 @@ async function launchProcess(options) {
|
|
|
132
132
|
spawnedProcess.once("error", (error) => {
|
|
133
133
|
failed(new Error("Failed to launch: " + error));
|
|
134
134
|
});
|
|
135
|
-
return
|
|
135
|
+
return failedPromise.then((e) => Promise.reject(e));
|
|
136
136
|
}
|
|
137
137
|
options.log(`<launched> pid=${spawnedProcess.pid}`);
|
|
138
138
|
const stdout = readline.createInterface({ input: spawnedProcess.stdout });
|