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.
Files changed (38) hide show
  1. package/lib/client/playwright.js +2 -2
  2. package/lib/inProcessFactory.js +2 -2
  3. package/lib/protocol/validator.js +2 -2
  4. package/lib/remote/playwrightConnection.js +27 -168
  5. package/lib/remote/playwrightServer.js +173 -27
  6. package/lib/server/android/android.js +31 -25
  7. package/lib/server/bidi/bidiChromium.js +1 -1
  8. package/lib/server/bidi/bidiFirefox.js +4 -1
  9. package/lib/server/browser.js +13 -12
  10. package/lib/server/browserContext.js +49 -46
  11. package/lib/server/browserType.js +26 -19
  12. package/lib/server/chromium/chromium.js +9 -7
  13. package/lib/server/chromium/videoRecorder.js +2 -1
  14. package/lib/server/debugController.js +1 -1
  15. package/lib/server/dispatchers/androidDispatcher.js +4 -4
  16. package/lib/server/dispatchers/browserContextDispatcher.js +1 -1
  17. package/lib/server/dispatchers/browserDispatcher.js +2 -2
  18. package/lib/server/dispatchers/electronDispatcher.js +2 -2
  19. package/lib/server/dispatchers/frameDispatcher.js +1 -1
  20. package/lib/server/dispatchers/localUtilsDispatcher.js +1 -2
  21. package/lib/server/dispatchers/playwrightDispatcher.js +5 -21
  22. package/lib/server/dom.js +3 -4
  23. package/lib/server/electron/electron.js +15 -16
  24. package/lib/server/fetch.js +12 -26
  25. package/lib/server/firefox/ffPage.js +0 -1
  26. package/lib/server/frames.js +93 -92
  27. package/lib/server/helper.js +1 -1
  28. package/lib/server/page.js +48 -42
  29. package/lib/server/playwright.js +2 -2
  30. package/lib/server/recorder/recorderApp.js +1 -1
  31. package/lib/server/registry/index.js +7 -20
  32. package/lib/server/screenshotter.js +17 -31
  33. package/lib/server/socksClientCertificatesInterceptor.js +7 -3
  34. package/lib/server/trace/viewer/traceViewer.js +1 -1
  35. package/lib/server/transport.js +3 -7
  36. package/lib/server/utils/processLauncher.js +1 -1
  37. package/lib/vite/htmlReport/index.html +9 -9
  38. package/package.json +1 -1
@@ -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, options, async () => {
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, options, async () => {
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, options, async () => {
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
- async snapshotForAI(metadata) {
627
- this.lastSnapshotFrameIds = [];
628
- const snapshot = await snapshotFrameForAI(metadata, this.mainFrame(), 0, this.lastSnapshotFrameIds);
629
- return snapshot.join("\n");
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(metadata, frame, frameOrdinal, frameIds) {
771
- const controller = new import_progress.ProgressController(metadata, frame);
772
- const snapshot = await controller.run((progress) => {
773
- return frame.retryWithProgressAndTimeouts(progress, [1e3, 2e3, 4e3, 8e3], async (continuePolling) => {
774
- try {
775
- const context = await frame._utilityContext();
776
- const injectedScript = await context.injectedScript();
777
- const snapshotOrRetry = await injectedScript.evaluate((injected, refPrefix) => {
778
- const node = injected.document.body;
779
- if (!node)
780
- return true;
781
- return injected.ariaSnapshot(node, { forAI: true, refPrefix });
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(metadata, child.frame, frameOrdinal2, frameIds);
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);
@@ -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.bidiChromium = new import_bidiChromium.BidiChromium(this);
54
- this.bidiFirefox = new import_bidiFirefox.BidiFirefox(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
- "bidi": {}
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: "bidi-chromium",
658
- browserName: "bidi",
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: "bidi",
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(`Firefox distribution '${name}' is not supported on ${process.platform}`);
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: "bidi",
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.throwIfAborted();
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
- await this._page.safeNonStallingEvaluateInAllFrames("(" + inPagePrepareForScreenshots.toString() + `)(${JSON.stringify(screenshotStyle)}, ${hideCaret}, ${disableAnimations}, ${syncAnimations})`, "utility");
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
- if (!options.mask || !options.mask.length)
241
- return cleanup;
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.throwIfAborted();
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 listen() {
265
- const port = await this._socksProxy.listen(0, "127.0.0.1");
266
- return { server: `socks5://127.0.0.1:${port}` };
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
  });
@@ -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
- let success = false;
103
- progress?.cleanupWhenAborted(async () => {
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 cleanup().then(() => failedPromise).then((e) => Promise.reject(e));
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 });