playwright-core 1.55.0-alpha-2025-07-29 → 1.55.0-alpha-2025-07-30

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 (37) hide show
  1. package/lib/generated/injectedScriptSource.js +1 -1
  2. package/lib/generated/pollingRecorderSource.js +1 -1
  3. package/lib/protocol/validator.js +0 -16
  4. package/lib/server/android/android.js +54 -43
  5. package/lib/server/bidi/bidiPage.js +4 -0
  6. package/lib/server/browser.js +22 -18
  7. package/lib/server/browserContext.js +73 -46
  8. package/lib/server/browserType.js +67 -48
  9. package/lib/server/chromium/chromium.js +34 -28
  10. package/lib/server/chromium/crCoverage.js +3 -4
  11. package/lib/server/chromium/videoRecorder.js +10 -19
  12. package/lib/server/codegen/jsonl.js +2 -1
  13. package/lib/server/debugController.js +2 -18
  14. package/lib/server/dispatchers/debugControllerDispatcher.js +0 -9
  15. package/lib/server/dispatchers/localUtilsDispatcher.js +0 -5
  16. package/lib/server/frames.js +6 -6
  17. package/lib/server/localUtils.js +12 -7
  18. package/lib/server/playwright.js +0 -4
  19. package/lib/server/progress.js +17 -11
  20. package/lib/server/recorder/recorderUtils.js +5 -0
  21. package/lib/server/recorder.js +61 -1
  22. package/lib/server/socksClientCertificatesInterceptor.js +21 -6
  23. package/lib/server/utils/processLauncher.js +4 -1
  24. package/lib/utils/isomorphic/ariaSnapshot.js +58 -4
  25. package/lib/utils/isomorphic/protocolMetainfo.js +1 -5
  26. package/lib/utils/isomorphic/urlMatch.js +0 -2
  27. package/lib/vite/htmlReport/index.html +16 -16
  28. package/lib/vite/recorder/assets/{codeMirrorModule-cgtwtYOb.js → codeMirrorModule-BAFWw0fz.js} +1 -1
  29. package/lib/vite/recorder/assets/{index-KWWSfrzB.js → index-DyMqECqY.js} +28 -28
  30. package/lib/vite/recorder/index.html +1 -1
  31. package/lib/vite/traceViewer/assets/{codeMirrorModule-k_7BpzGX.js → codeMirrorModule-BOjqK4ng.js} +1 -1
  32. package/lib/vite/traceViewer/assets/{defaultSettingsView-CKM53V_K.js → defaultSettingsView-B-LNxb2i.js} +103 -103
  33. package/lib/vite/traceViewer/{index.CCXGYfh2.js → index.CWlPEVCA.js} +1 -1
  34. package/lib/vite/traceViewer/index.html +2 -2
  35. package/lib/vite/traceViewer/{uiMode.CNa3x5Xj.js → uiMode.NUAVc1od.js} +1 -1
  36. package/lib/vite/traceViewer/uiMode.html +2 -2
  37. package/package.json +1 -1
@@ -258,10 +258,14 @@ if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { co
258
258
  const binding = new import_page2.PageBinding(name, playwrightBinding, needsHandle);
259
259
  binding.forClient = forClient;
260
260
  this._pageBindings.set(name, binding);
261
- progress.cleanupWhenAborted(() => this._pageBindings.delete(name));
262
- await progress.race(this.doAddInitScript(binding.initScript));
263
- await progress.race(this.safeNonStallingEvaluateInAllFrames(binding.initScript.source, "main"));
264
- return binding;
261
+ try {
262
+ await progress.race(this.doAddInitScript(binding.initScript));
263
+ await progress.race(this.safeNonStallingEvaluateInAllFrames(binding.initScript.source, "main"));
264
+ return binding;
265
+ } catch (error) {
266
+ this._pageBindings.delete(name);
267
+ throw error;
268
+ }
265
269
  }
266
270
  async removeExposedBindings(bindings) {
267
271
  bindings = bindings.filter((binding) => this._pageBindings.get(binding.name) === binding);
@@ -291,20 +295,26 @@ if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { co
291
295
  async setExtraHTTPHeaders(progress, headers) {
292
296
  const oldHeaders = this._options.extraHTTPHeaders;
293
297
  this._options.extraHTTPHeaders = headers;
294
- progress.cleanupWhenAborted(async () => {
298
+ try {
299
+ await progress.race(this.doUpdateExtraHTTPHeaders());
300
+ } catch (error) {
295
301
  this._options.extraHTTPHeaders = oldHeaders;
296
- await this.doUpdateExtraHTTPHeaders();
297
- });
298
- await progress.race(this.doUpdateExtraHTTPHeaders());
302
+ this.doUpdateExtraHTTPHeaders().catch(() => {
303
+ });
304
+ throw error;
305
+ }
299
306
  }
300
307
  async setOffline(progress, offline) {
301
308
  const oldOffline = this._options.offline;
302
309
  this._options.offline = offline;
303
- progress.cleanupWhenAborted(async () => {
310
+ try {
311
+ await progress.race(this.doUpdateOffline());
312
+ } catch (error) {
304
313
  this._options.offline = oldOffline;
305
- await this.doUpdateOffline();
306
- });
307
- await progress.race(this.doUpdateOffline());
314
+ this.doUpdateOffline().catch(() => {
315
+ });
316
+ throw error;
317
+ }
308
318
  }
309
319
  async _loadDefaultContextAsIs(progress) {
310
320
  if (!this.possiblyUninitializedPages().length) {
@@ -353,13 +363,18 @@ if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { co
353
363
  async addInitScript(progress, source) {
354
364
  const initScript = new import_page.InitScript(source);
355
365
  this.initScripts.push(initScript);
356
- progress?.cleanupWhenAborted(() => this.removeInitScripts([initScript]));
357
- const promise = this.doAddInitScript(initScript);
358
- if (progress)
359
- await progress.race(promise);
360
- else
361
- await promise;
362
- return initScript;
366
+ try {
367
+ const promise = this.doAddInitScript(initScript);
368
+ if (progress)
369
+ await progress.race(promise);
370
+ else
371
+ await promise;
372
+ return initScript;
373
+ } catch (error) {
374
+ this.removeInitScripts([initScript]).catch(() => {
375
+ });
376
+ throw error;
377
+ }
363
378
  }
364
379
  async removeInitScripts(initScripts) {
365
380
  const set = new Set(initScripts);
@@ -419,14 +434,20 @@ if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { co
419
434
  await this._closePromise;
420
435
  }
421
436
  async newPage(progress, isServerSide) {
422
- const page = await progress.raceWithCleanup(this.doCreateNewPage(isServerSide), (page2) => page2.close());
423
- const pageOrError = await progress.race(page.waitForInitializedOrError());
424
- if (pageOrError instanceof import_page2.Page) {
425
- if (pageOrError.isClosed())
426
- throw new Error("Page has been closed.");
427
- return pageOrError;
437
+ const page = await progress.race(this.doCreateNewPage(isServerSide));
438
+ try {
439
+ const pageOrError = await progress.race(page.waitForInitializedOrError());
440
+ if (pageOrError instanceof import_page2.Page) {
441
+ if (pageOrError.isClosed())
442
+ throw new Error("Page has been closed.");
443
+ return pageOrError;
444
+ }
445
+ throw pageOrError;
446
+ } catch (error) {
447
+ await page.close({ reason: "Failed to create page" }).catch(() => {
448
+ });
449
+ throw error;
428
450
  }
429
- throw pageOrError;
430
451
  }
431
452
  addVisitedOrigin(origin) {
432
453
  this._origins.add(origin);
@@ -457,18 +478,21 @@ if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { co
457
478
  }
458
479
  if (originsToSave.size) {
459
480
  const page = await this.newPage(progress, true);
460
- await page.addRequestInterceptor(progress, (route) => {
461
- route.fulfill({ body: "<html></html>" }).catch(() => {
462
- });
463
- }, "prepend");
464
- for (const origin of originsToSave) {
465
- const frame = page.mainFrame();
466
- await frame.gotoImpl(progress, origin, {});
467
- const storage = await progress.race(frame.evaluateExpression(collectScript, { world: "utility" }));
468
- if (storage.localStorage.length || storage.indexedDB?.length)
469
- result.origins.push({ origin, localStorage: storage.localStorage, indexedDB: storage.indexedDB });
481
+ try {
482
+ await page.addRequestInterceptor(progress, (route) => {
483
+ route.fulfill({ body: "<html></html>" }).catch(() => {
484
+ });
485
+ }, "prepend");
486
+ for (const origin of originsToSave) {
487
+ const frame = page.mainFrame();
488
+ await frame.gotoImpl(progress, origin, {});
489
+ const storage = await progress.race(frame.evaluateExpression(collectScript, { world: "utility" }));
490
+ if (storage.localStorage.length || storage.indexedDB?.length)
491
+ result.origins.push({ origin, localStorage: storage.localStorage, indexedDB: storage.indexedDB });
492
+ }
493
+ } finally {
494
+ await page.close();
470
495
  }
471
- await page.close();
472
496
  }
473
497
  return result;
474
498
  }
@@ -483,26 +507,29 @@ if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { co
483
507
  route.fulfill({ body: "<html></html>" }).catch(() => {
484
508
  });
485
509
  };
486
- progress.cleanupWhenAborted(() => page.removeRequestInterceptor(interceptor));
487
510
  await page.addRequestInterceptor(progress, interceptor, "prepend");
488
- for (const origin of /* @__PURE__ */ new Set([...oldOrigins, ...newOrigins.keys()])) {
489
- const frame = page.mainFrame();
490
- await frame.gotoImpl(progress, origin, {});
491
- await progress.race(frame.resetStorageForCurrentOriginBestEffort(newOrigins.get(origin)));
511
+ try {
512
+ for (const origin of /* @__PURE__ */ new Set([...oldOrigins, ...newOrigins.keys()])) {
513
+ const frame = page.mainFrame();
514
+ await frame.gotoImpl(progress, origin, {});
515
+ await progress.race(frame.resetStorageForCurrentOriginBestEffort(newOrigins.get(origin)));
516
+ }
517
+ this._origins = /* @__PURE__ */ new Set([...newOrigins.keys()]);
518
+ } finally {
519
+ await page.removeRequestInterceptor(interceptor);
492
520
  }
493
- await page.removeRequestInterceptor(interceptor);
494
- this._origins = /* @__PURE__ */ new Set([...newOrigins.keys()]);
495
521
  }
496
522
  isSettingStorageState() {
497
523
  return this._settingStorageState;
498
524
  }
499
525
  async setStorageState(progress, state) {
526
+ let page;
500
527
  this._settingStorageState = true;
501
528
  try {
502
529
  if (state.cookies)
503
530
  await progress.race(this.addCookies(state.cookies));
504
531
  if (state.origins && state.origins.length) {
505
- const page = await this.newPage(progress, true);
532
+ page = await this.newPage(progress, true);
506
533
  await page.addRequestInterceptor(progress, (route) => {
507
534
  route.fulfill({ body: "<html></html>" }).catch(() => {
508
535
  });
@@ -518,13 +545,13 @@ if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { co
518
545
  })()`;
519
546
  await progress.race(frame.evaluateExpression(restoreScript, { world: "utility" }));
520
547
  }
521
- await page.close();
522
548
  }
523
549
  } catch (error) {
524
550
  (0, import_stackTrace.rewriteErrorMessage)(error, `Error setting storage state:
525
551
  ` + error.message);
526
552
  throw error;
527
553
  } finally {
554
+ await page?.close();
528
555
  this._settingStorageState = false;
529
556
  }
530
557
  }
@@ -77,16 +77,22 @@ class BrowserType extends import_instrumentation.SdkObject {
77
77
  const launchOptions = this._validateLaunchOptions(options);
78
78
  let clientCertificatesProxy;
79
79
  if (options.clientCertificates?.length) {
80
- clientCertificatesProxy = await progress.raceWithCleanup(import_socksClientCertificatesInterceptor.ClientCertificatesProxy.create(options), (proxy) => proxy.close());
80
+ clientCertificatesProxy = await import_socksClientCertificatesInterceptor.ClientCertificatesProxy.create(progress, options);
81
81
  launchOptions.proxyOverride = clientCertificatesProxy.proxySettings();
82
82
  options = { ...options };
83
83
  options.internalIgnoreHTTPSErrors = true;
84
84
  }
85
- const browser = await this._innerLaunchWithRetries(progress, launchOptions, options, import_helper.helper.debugProtocolLogger(), userDataDir).catch((e) => {
86
- throw this._rewriteStartupLog(e);
87
- });
88
- browser._defaultContext._clientCertificatesProxy = clientCertificatesProxy;
89
- return browser._defaultContext;
85
+ try {
86
+ const browser = await this._innerLaunchWithRetries(progress, launchOptions, options, import_helper.helper.debugProtocolLogger(), userDataDir).catch((e) => {
87
+ throw this._rewriteStartupLog(e);
88
+ });
89
+ browser._defaultContext._clientCertificatesProxy = clientCertificatesProxy;
90
+ return browser._defaultContext;
91
+ } catch (error) {
92
+ await clientCertificatesProxy?.close().catch(() => {
93
+ });
94
+ throw error;
95
+ }
90
96
  }
91
97
  async _innerLaunchWithRetries(progress, options, persistent, protocolLogger, userDataDir) {
92
98
  try {
@@ -104,34 +110,40 @@ class BrowserType extends import_instrumentation.SdkObject {
104
110
  options.proxy = options.proxy ? (0, import_browserContext.normalizeProxySettings)(options.proxy) : void 0;
105
111
  const browserLogsCollector = new import_debugLogger.RecentLogsCollector();
106
112
  const { browserProcess, userDataDir, artifactsDir, transport } = await this._launchProcess(progress, options, !!persistent, browserLogsCollector, maybeUserDataDir);
107
- if (options.__testHookBeforeCreateBrowser)
108
- await progress.race(options.__testHookBeforeCreateBrowser());
109
- const browserOptions = {
110
- name: this._name,
111
- isChromium: this._name === "chromium",
112
- channel: options.channel,
113
- slowMo: options.slowMo,
114
- persistent,
115
- headful: !options.headless,
116
- artifactsDir,
117
- downloadsPath: options.downloadsPath || artifactsDir,
118
- tracesDir: options.tracesDir || artifactsDir,
119
- browserProcess,
120
- customExecutablePath: options.executablePath,
121
- proxy: options.proxy,
122
- protocolLogger,
123
- browserLogsCollector,
124
- wsEndpoint: transport instanceof import_transport.WebSocketTransport ? transport.wsEndpoint : void 0,
125
- originalLaunchOptions: options
126
- };
127
- if (persistent)
128
- (0, import_browserContext.validateBrowserContextOptions)(persistent, browserOptions);
129
- copyTestHooks(options, browserOptions);
130
- const browser = await progress.race(this.connectToTransport(transport, browserOptions, browserLogsCollector));
131
- browser._userDataDirForTest = userDataDir;
132
- if (persistent && !options.ignoreAllDefaultArgs)
133
- await browser._defaultContext._loadDefaultContext(progress);
134
- return browser;
113
+ try {
114
+ if (options.__testHookBeforeCreateBrowser)
115
+ await progress.race(options.__testHookBeforeCreateBrowser());
116
+ const browserOptions = {
117
+ name: this._name,
118
+ isChromium: this._name === "chromium",
119
+ channel: options.channel,
120
+ slowMo: options.slowMo,
121
+ persistent,
122
+ headful: !options.headless,
123
+ artifactsDir,
124
+ downloadsPath: options.downloadsPath || artifactsDir,
125
+ tracesDir: options.tracesDir || artifactsDir,
126
+ browserProcess,
127
+ customExecutablePath: options.executablePath,
128
+ proxy: options.proxy,
129
+ protocolLogger,
130
+ browserLogsCollector,
131
+ wsEndpoint: transport instanceof import_transport.WebSocketTransport ? transport.wsEndpoint : void 0,
132
+ originalLaunchOptions: options
133
+ };
134
+ if (persistent)
135
+ (0, import_browserContext.validateBrowserContextOptions)(persistent, browserOptions);
136
+ copyTestHooks(options, browserOptions);
137
+ const browser = await progress.race(this.connectToTransport(transport, browserOptions, browserLogsCollector));
138
+ browser._userDataDirForTest = userDataDir;
139
+ if (persistent && !options.ignoreAllDefaultArgs)
140
+ await browser._defaultContext._loadDefaultContext(progress);
141
+ return browser;
142
+ } catch (error) {
143
+ await browserProcess.close().catch(() => {
144
+ });
145
+ throw error;
146
+ }
135
147
  }
136
148
  async _prepareToLaunch(options, isPersistent, userDataDir) {
137
149
  const {
@@ -182,7 +194,6 @@ class BrowserType extends import_instrumentation.SdkObject {
182
194
  } = options;
183
195
  const env = options.env ? (0, import_processLauncher.envArrayToObject)(options.env) : process.env;
184
196
  const prepared = await progress.race(this._prepareToLaunch(options, isPersistent, userDataDir));
185
- progress.cleanupWhenAborted(() => (0, import_fileUtils.removeFolders)(prepared.tempDirectories));
186
197
  let transport = void 0;
187
198
  let browserProcess = void 0;
188
199
  const exitPromise = new import_manualPromise.ManualPromise();
@@ -202,7 +213,11 @@ class BrowserType extends import_instrumentation.SdkObject {
202
213
  attemptToGracefullyClose: async () => {
203
214
  if (options.__testHookGracefullyClose)
204
215
  await options.__testHookGracefullyClose();
205
- this.attemptToGracefullyCloseBrowser(transport);
216
+ if (transport) {
217
+ this.attemptToGracefullyCloseBrowser(transport);
218
+ } else {
219
+ throw new Error("Force-killing the browser because no transport is available to gracefully close it.");
220
+ }
206
221
  },
207
222
  onExit: (exitCode, signal) => {
208
223
  exitPromise.resolve();
@@ -230,19 +245,23 @@ class BrowserType extends import_instrumentation.SdkObject {
230
245
  close: () => closeOrKill(options.__testHookBrowserCloseTimeout || import_time.DEFAULT_PLAYWRIGHT_TIMEOUT),
231
246
  kill
232
247
  };
233
- progress.cleanupWhenAborted(() => closeOrKill(import_time.DEFAULT_PLAYWRIGHT_TIMEOUT));
234
- const { wsEndpoint } = await progress.race([
235
- this.waitForReadyState(options, browserLogsCollector),
236
- exitPromise.then(() => ({ wsEndpoint: void 0 }))
237
- ]);
238
- if (options.cdpPort !== void 0 || !this.supportsPipeTransport()) {
239
- transport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint);
240
- } else {
241
- const stdio = launchedProcess.stdio;
242
- transport = new import_pipeTransport.PipeTransport(stdio[3], stdio[4]);
248
+ try {
249
+ const { wsEndpoint } = await progress.race([
250
+ this.waitForReadyState(options, browserLogsCollector),
251
+ exitPromise.then(() => ({ wsEndpoint: void 0 }))
252
+ ]);
253
+ if (options.cdpPort !== void 0 || !this.supportsPipeTransport()) {
254
+ transport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint);
255
+ } else {
256
+ const stdio = launchedProcess.stdio;
257
+ transport = new import_pipeTransport.PipeTransport(stdio[3], stdio[4]);
258
+ }
259
+ return { browserProcess, artifactsDir: prepared.artifactsDir, userDataDir: prepared.userDataDir, transport };
260
+ } catch (error) {
261
+ await closeOrKill(import_time.DEFAULT_PLAYWRIGHT_TIMEOUT).catch(() => {
262
+ });
263
+ throw error;
243
264
  }
244
- progress.cleanupWhenAborted(() => transport.close());
245
- return { browserProcess, artifactsDir: prepared.artifactsDir, userDataDir: prepared.userDataDir, transport };
246
265
  }
247
266
  async _createArtifactDirs(options) {
248
267
  if (options.downloadsPath)
@@ -72,39 +72,45 @@ class Chromium extends import_browserType.BrowserType {
72
72
  else if (headersMap && !Object.keys(headersMap).some((key) => key.toLowerCase() === "user-agent"))
73
73
  headersMap["User-Agent"] = (0, import_userAgent.getUserAgent)();
74
74
  const artifactsDir = await progress.race(import_fs.default.promises.mkdtemp(ARTIFACTS_FOLDER));
75
- const wsEndpoint = await urlToWSEndpoint(progress, endpointURL, headersMap);
76
- const chromeTransport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint, { headers: headersMap });
77
- progress.cleanupWhenAborted(() => chromeTransport.close());
78
- const cleanedUp = new import_manualPromise.ManualPromise();
79
75
  const doCleanup = async () => {
80
76
  await (0, import_fileUtils.removeFolders)([artifactsDir]);
81
- await onClose?.();
82
- cleanedUp.resolve();
77
+ const cb = onClose;
78
+ onClose = void 0;
79
+ await cb?.();
83
80
  };
81
+ let chromeTransport;
84
82
  const doClose = async () => {
85
- await chromeTransport.closeAndWait();
86
- await cleanedUp;
83
+ await chromeTransport?.closeAndWait();
84
+ await doCleanup();
87
85
  };
88
- const browserProcess = { close: doClose, kill: doClose };
89
- const persistent = { noDefaultViewport: true };
90
- const browserOptions = {
91
- slowMo: options.slowMo,
92
- name: "chromium",
93
- isChromium: true,
94
- persistent,
95
- browserProcess,
96
- protocolLogger: import_helper.helper.debugProtocolLogger(),
97
- browserLogsCollector: new import_debugLogger.RecentLogsCollector(),
98
- artifactsDir,
99
- downloadsPath: options.downloadsPath || artifactsDir,
100
- tracesDir: options.tracesDir || artifactsDir,
101
- originalLaunchOptions: {}
102
- };
103
- (0, import_browserContext.validateBrowserContextOptions)(persistent, browserOptions);
104
- const browser = await progress.race(import_crBrowser.CRBrowser.connect(this.attribution.playwright, chromeTransport, browserOptions));
105
- browser._isCollocatedWithServer = false;
106
- browser.on(import_browser.Browser.Events.Disconnected, doCleanup);
107
- return browser;
86
+ try {
87
+ const wsEndpoint = await urlToWSEndpoint(progress, endpointURL, headersMap);
88
+ chromeTransport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint, { headers: headersMap });
89
+ const browserProcess = { close: doClose, kill: doClose };
90
+ const persistent = { noDefaultViewport: true };
91
+ const browserOptions = {
92
+ slowMo: options.slowMo,
93
+ name: "chromium",
94
+ isChromium: true,
95
+ persistent,
96
+ browserProcess,
97
+ protocolLogger: import_helper.helper.debugProtocolLogger(),
98
+ browserLogsCollector: new import_debugLogger.RecentLogsCollector(),
99
+ artifactsDir,
100
+ downloadsPath: options.downloadsPath || artifactsDir,
101
+ tracesDir: options.tracesDir || artifactsDir,
102
+ originalLaunchOptions: {}
103
+ };
104
+ (0, import_browserContext.validateBrowserContextOptions)(persistent, browserOptions);
105
+ const browser = await progress.race(import_crBrowser.CRBrowser.connect(this.attribution.playwright, chromeTransport, browserOptions));
106
+ browser._isCollocatedWithServer = false;
107
+ browser.on(import_browser.Browser.Events.Disconnected, doCleanup);
108
+ return browser;
109
+ } catch (error) {
110
+ await doClose().catch(() => {
111
+ });
112
+ throw error;
113
+ }
108
114
  }
109
115
  _createDevTools() {
110
116
  const directory = import_registry.registry.findExecutable("chromium").directory;
@@ -23,21 +23,20 @@ __export(crCoverage_exports, {
23
23
  module.exports = __toCommonJS(crCoverage_exports);
24
24
  var import_utils = require("../../utils");
25
25
  var import_eventsHelper = require("../utils/eventsHelper");
26
+ var import_progress = require("../progress");
26
27
  class CRCoverage {
27
28
  constructor(client) {
28
29
  this._jsCoverage = new JSCoverage(client);
29
30
  this._cssCoverage = new CSSCoverage(client);
30
31
  }
31
32
  async startJSCoverage(progress, options) {
32
- progress.cleanupWhenAborted(() => this._jsCoverage.stop());
33
- await progress.race(this._jsCoverage.start(options));
33
+ await (0, import_progress.raceUncancellableOperationWithCleanup)(progress, () => this._jsCoverage.start(options), () => this._jsCoverage.stop());
34
34
  }
35
35
  async stopJSCoverage() {
36
36
  return await this._jsCoverage.stop();
37
37
  }
38
38
  async startCSSCoverage(progress, options) {
39
- progress.cleanupWhenAborted(() => this._cssCoverage.stop());
40
- await progress.race(this._cssCoverage.start(options));
39
+ await (0, import_progress.raceUncancellableOperationWithCleanup)(progress, () => this._cssCoverage.start(options), () => this._cssCoverage.stop());
41
40
  }
42
41
  async stopCSSCoverage() {
43
42
  return await this._cssCoverage.stop();
@@ -22,13 +22,11 @@ __export(videoRecorder_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(videoRecorder_exports);
24
24
  var import_utils = require("../../utils");
25
- var import_instrumentation = require("../instrumentation");
26
25
  var import_page = require("../page");
27
26
  var import_processLauncher = require("../utils/processLauncher");
28
- var import_progress = require("../progress");
29
27
  const fps = 25;
30
28
  class VideoRecorder {
31
- constructor(page, ffmpegPath, progress) {
29
+ constructor(page, ffmpegPath) {
32
30
  this._process = null;
33
31
  this._gracefullyClose = null;
34
32
  this._lastWritePromise = Promise.resolve();
@@ -37,47 +35,40 @@ class VideoRecorder {
37
35
  this._lastWriteTimestamp = 0;
38
36
  this._frameQueue = [];
39
37
  this._isStopped = false;
40
- this._progress = progress;
41
38
  this._ffmpegPath = ffmpegPath;
42
39
  page.on(import_page.Page.Events.ScreencastFrame, (frame) => this.writeFrame(frame.buffer, frame.frameSwapWallTime / 1e3));
43
40
  }
44
41
  static async launch(page, ffmpegPath, options) {
45
42
  if (!options.outputFile.endsWith(".webm"))
46
43
  throw new Error("File must have .webm extension");
47
- const controller = new import_progress.ProgressController((0, import_instrumentation.serverSideCallMetadata)(), page);
48
- controller.setLogName("browser");
49
- return await controller.run(async (progress) => {
50
- const recorder = new VideoRecorder(page, ffmpegPath, progress);
51
- progress.cleanupWhenAborted(() => recorder.stop());
52
- await recorder._launch(options);
53
- return recorder;
54
- });
44
+ const recorder = new VideoRecorder(page, ffmpegPath);
45
+ await recorder._launch(options);
46
+ return recorder;
55
47
  }
56
48
  async _launch(options) {
57
49
  const w = options.width;
58
50
  const h = options.height;
59
51
  const args = `-loglevel error -f image2pipe -avioflags direct -fpsprobesize 0 -probesize 32 -analyzeduration 0 -c:v mjpeg -i pipe:0 -y -an -r ${fps} -c:v vp8 -qmin 0 -qmax 50 -crf 8 -deadline realtime -speed 8 -b:v 1M -threads 1 -vf pad=${w}:${h}:0:0:gray,crop=${w}:${h}:0:0`.split(" ");
60
52
  args.push(options.outputFile);
61
- const progress = this._progress;
62
53
  const { launchedProcess, gracefullyClose } = await (0, import_processLauncher.launchProcess)({
63
54
  command: this._ffmpegPath,
64
55
  args,
65
56
  stdio: "stdin",
66
- log: (message) => progress.log(message),
57
+ log: (message) => import_utils.debugLogger.log("browser", message),
67
58
  tempDirectories: [],
68
59
  attemptToGracefullyClose: async () => {
69
- progress.log("Closing stdin...");
60
+ import_utils.debugLogger.log("browser", "Closing stdin...");
70
61
  launchedProcess.stdin.end();
71
62
  },
72
63
  onExit: (exitCode, signal) => {
73
- progress.log(`ffmpeg onkill exitCode=${exitCode} signal=${signal}`);
64
+ import_utils.debugLogger.log("browser", `ffmpeg onkill exitCode=${exitCode} signal=${signal}`);
74
65
  }
75
66
  });
76
67
  launchedProcess.stdin.on("finish", () => {
77
- progress.log("ffmpeg finished input.");
68
+ import_utils.debugLogger.log("browser", "ffmpeg finished input.");
78
69
  });
79
70
  launchedProcess.stdin.on("error", () => {
80
- progress.log("ffmpeg error.");
71
+ import_utils.debugLogger.log("browser", "ffmpeg error.");
81
72
  });
82
73
  this._process = launchedProcess;
83
74
  this._gracefullyClose = gracefullyClose;
@@ -104,7 +95,7 @@ class VideoRecorder {
104
95
  async _sendFrame(frame) {
105
96
  return new Promise((f) => this._process.stdin.write(frame, f)).then((error) => {
106
97
  if (error)
107
- this._progress.log(`ffmpeg failed to write: ${String(error)}`);
98
+ import_utils.debugLogger.log("browser", `ffmpeg failed to write: ${String(error)}`);
108
99
  });
109
100
  }
110
101
  async stop() {
@@ -34,7 +34,8 @@ class JsonlLanguageGenerator {
34
34
  const entry = {
35
35
  ...actionInContext.action,
36
36
  ...actionInContext.frame,
37
- locator
37
+ locator,
38
+ ariaSnapshot: void 0
38
39
  };
39
40
  return JSON.stringify(entry);
40
41
  }
@@ -65,17 +65,6 @@ class DebugController extends import_instrumentation.SdkObject {
65
65
  this._trackHierarchyListener = void 0;
66
66
  }
67
67
  }
68
- async resetForReuse(progress) {
69
- const contexts = /* @__PURE__ */ new Set();
70
- for (const page of this._playwright.allPages())
71
- contexts.add(page.browserContext);
72
- for (const context of contexts)
73
- await context.resetForReuse(progress, null);
74
- }
75
- async navigate(progress, url) {
76
- for (const p of this._playwright.allPages())
77
- await p.mainFrame().goto(progress, url);
78
- }
79
68
  async setRecorderMode(progress, params) {
80
69
  await progress.race(this._closeBrowsersWithoutPages());
81
70
  if (params.mode === "none") {
@@ -120,10 +109,8 @@ class DebugController extends import_instrumentation.SdkObject {
120
109
  async hideHighlight(progress) {
121
110
  for (const recorder of await progress.race(this._allRecorders()))
122
111
  recorder.hideHighlightedSelector();
123
- await this._playwright.hideHighlight();
124
- }
125
- allBrowsers() {
126
- return [...this._playwright.allBrowsers()];
112
+ await Promise.all(this._playwright.allPages().map((p) => p.hideHighlight().catch(() => {
113
+ })));
127
114
  }
128
115
  async resume(progress) {
129
116
  for (const recorder of await progress.race(this._allRecorders()))
@@ -132,9 +119,6 @@ class DebugController extends import_instrumentation.SdkObject {
132
119
  kill() {
133
120
  (0, import_processLauncher.gracefullyProcessExitDoNotHang)(0);
134
121
  }
135
- async closeAllBrowsers() {
136
- await Promise.all(this.allBrowsers().map((browser) => browser.close({ reason: "Close all browsers requested" })));
137
- }
138
122
  _emitSnapshot(initial) {
139
123
  const pageCount = this._playwright.allPages().length;
140
124
  if (initial && !pageCount)
@@ -52,12 +52,6 @@ class DebugControllerDispatcher extends import_dispatcher.Dispatcher {
52
52
  async setReportStateChanged(params, progress) {
53
53
  this._object.setReportStateChanged(params.enabled);
54
54
  }
55
- async resetForReuse(params, progress) {
56
- await this._object.resetForReuse(progress);
57
- }
58
- async navigate(params, progress) {
59
- await this._object.navigate(progress, params.url);
60
- }
61
55
  async setRecorderMode(params, progress) {
62
56
  await this._object.setRecorderMode(progress, params);
63
57
  }
@@ -73,9 +67,6 @@ class DebugControllerDispatcher extends import_dispatcher.Dispatcher {
73
67
  async kill(params, progress) {
74
68
  this._object.kill();
75
69
  }
76
- async closeAllBrowsers(params, progress) {
77
- await this._object.closeAllBrowsers();
78
- }
79
70
  _onDispose() {
80
71
  import_utils.eventsHelper.removeEventListeners(this._listeners);
81
72
  this._object.dispose();
@@ -40,7 +40,6 @@ var import_jsonPipeDispatcher = require("../dispatchers/jsonPipeDispatcher");
40
40
  var import_socksInterceptor = require("../socksInterceptor");
41
41
  var import_transport = require("../transport");
42
42
  var import_network = require("../utils/network");
43
- var import_urlMatch = require("../../utils/isomorphic/urlMatch");
44
43
  class LocalUtilsDispatcher extends import_dispatcher.Dispatcher {
45
44
  constructor(scope, playwright) {
46
45
  const localUtils2 = new import_instrumentation.SdkObject(playwright, "localUtils", "localUtils");
@@ -112,10 +111,6 @@ class LocalUtilsDispatcher extends import_dispatcher.Dispatcher {
112
111
  pipe.on("close", () => transport.close());
113
112
  return { pipe, headers: transport.headers };
114
113
  }
115
- async globToRegex(params, progress) {
116
- const regex = (0, import_urlMatch.resolveGlobToRegexPattern)(params.baseURL, params.glob, params.webSocketUrl);
117
- return { regex };
118
- }
119
114
  }
120
115
  async function urlToWSEndpoint(progress, endpointURL) {
121
116
  if (endpointURL.startsWith("ws"))