playwright-core 1.55.0-alpha-2025-07-31 → 1.55.0-alpha-1754048396000

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 (39) hide show
  1. package/browsers.json +4 -4
  2. package/lib/client/browserContext.js +9 -6
  3. package/lib/client/clock.js +3 -0
  4. package/lib/generated/injectedScriptSource.js +1 -1
  5. package/lib/generated/pollingRecorderSource.js +1 -1
  6. package/lib/generated/storageScriptSource.js +1 -1
  7. package/lib/protocol/validator.js +288 -280
  8. package/lib/protocol/validatorPrimitives.js +18 -4
  9. package/lib/server/bidi/bidiBrowser.js +9 -3
  10. package/lib/server/bidi/bidiNetworkManager.js +1 -4
  11. package/lib/server/bidi/bidiPage.js +4 -20
  12. package/lib/server/bidi/third_party/bidiProtocolCore.js +33 -6
  13. package/lib/server/browser.js +1 -2
  14. package/lib/server/browserContext.js +36 -44
  15. package/lib/server/chromium/chromiumSwitches.js +2 -0
  16. package/lib/server/chromium/crPage.js +1 -1
  17. package/lib/server/clock.js +2 -2
  18. package/lib/server/dispatchers/browserContextDispatcher.js +6 -0
  19. package/lib/server/dispatchers/frameDispatcher.js +1 -1
  20. package/lib/server/dom.js +2 -2
  21. package/lib/server/frames.js +2 -25
  22. package/lib/server/instrumentation.js +1 -2
  23. package/lib/server/launchApp.js +23 -10
  24. package/lib/server/page.js +1 -1
  25. package/lib/server/registry/index.js +3 -3
  26. package/lib/server/socksClientCertificatesInterceptor.js +164 -121
  27. package/lib/server/trace/recorder/tracing.js +3 -1
  28. package/lib/server/webkit/wkPage.js +2 -2
  29. package/lib/utils/isomorphic/protocolMetainfo.js +2 -0
  30. package/lib/utils.js +4 -2
  31. package/lib/vite/traceViewer/assets/{codeMirrorModule-3XE5WU2G.js → codeMirrorModule-Chakc5qh.js} +1 -1
  32. package/lib/vite/traceViewer/assets/defaultSettingsView-COxW9YdO.js +256 -0
  33. package/lib/vite/traceViewer/{index.CycYDQ3P.js → index.BRvvuaPn.js} +1 -1
  34. package/lib/vite/traceViewer/index.html +2 -2
  35. package/lib/vite/traceViewer/{uiMode.DeaA8YiP.js → uiMode.CBXoasNF.js} +1 -1
  36. package/lib/vite/traceViewer/uiMode.html +2 -2
  37. package/package.json +1 -1
  38. package/types/types.d.ts +64 -0
  39. package/lib/vite/traceViewer/assets/defaultSettingsView-u5uZPktL.js +0 -256
@@ -29,7 +29,8 @@ __export(validatorPrimitives_exports, {
29
29
  tBoolean: () => tBoolean,
30
30
  tChannel: () => tChannel,
31
31
  tEnum: () => tEnum,
32
- tNumber: () => tNumber,
32
+ tFloat: () => tFloat,
33
+ tInt: () => tInt,
33
34
  tObject: () => tObject,
34
35
  tOptional: () => tOptional,
35
36
  tString: () => tString,
@@ -53,12 +54,24 @@ function maybeFindValidator(type, method, kind) {
53
54
  function createMetadataValidator() {
54
55
  return tOptional(scheme["Metadata"]);
55
56
  }
56
- const tNumber = (arg, path, context) => {
57
+ const tFloat = (arg, path, context) => {
57
58
  if (arg instanceof Number)
58
59
  return arg.valueOf();
59
60
  if (typeof arg === "number")
60
61
  return arg;
61
- throw new ValidationError(`${path}: expected number, got ${typeof arg}`);
62
+ throw new ValidationError(`${path}: expected float, got ${typeof arg}`);
63
+ };
64
+ const tInt = (arg, path, context) => {
65
+ let value;
66
+ if (arg instanceof Number)
67
+ value = arg.valueOf();
68
+ else if (typeof arg === "number")
69
+ value = arg;
70
+ else
71
+ throw new ValidationError(`${path}: expected integer, got ${typeof arg}`);
72
+ if (!Number.isInteger(value))
73
+ throw new ValidationError(`${path}: expected integer, got float ${value}`);
74
+ return value;
62
75
  };
63
76
  const tBoolean = (arg, path, context) => {
64
77
  if (arg instanceof Boolean)
@@ -170,7 +183,8 @@ const tType = (name) => {
170
183
  tBoolean,
171
184
  tChannel,
172
185
  tEnum,
173
- tNumber,
186
+ tFloat,
187
+ tInt,
174
188
  tObject,
175
189
  tOptional,
176
190
  tString,
@@ -183,6 +183,12 @@ class BidiBrowserContext extends import_browserContext.BrowserContext {
183
183
  promises.push(this.doUpdateDefaultViewport());
184
184
  if (this._options.geolocation)
185
185
  promises.push(this.setGeolocation(this._options.geolocation));
186
+ if (this._options.locale) {
187
+ promises.push(this._browser._browserSession.send("emulation.setLocaleOverride", {
188
+ locale: this._options.locale,
189
+ userContexts: [this._userContextId()]
190
+ }));
191
+ }
186
192
  await Promise.all(promises);
187
193
  }
188
194
  possiblyUninitializedPages() {
@@ -277,7 +283,7 @@ class BidiBrowserContext extends import_browserContext.BrowserContext {
277
283
  },
278
284
  state,
279
285
  origin,
280
- userContext: this._browserContextId || "default"
286
+ userContext: this._userContextId()
281
287
  });
282
288
  }
283
289
  async setGeolocation(geolocation) {
@@ -289,7 +295,7 @@ class BidiBrowserContext extends import_browserContext.BrowserContext {
289
295
  longitude: geolocation.longitude,
290
296
  accuracy: geolocation.accuracy
291
297
  } : null,
292
- userContexts: [this._browserContextId || "default"]
298
+ userContexts: [this._userContextId()]
293
299
  });
294
300
  }
295
301
  async doUpdateExtraHTTPHeaders() {
@@ -307,7 +313,7 @@ class BidiBrowserContext extends import_browserContext.BrowserContext {
307
313
  const { script } = await this._browser._browserSession.send("script.addPreloadScript", {
308
314
  // TODO: remove function call from the source.
309
315
  functionDeclaration: `() => { return ${initScript.source} }`,
310
- userContexts: [this._browserContextId || "default"]
316
+ userContexts: [this._userContextId()]
311
317
  });
312
318
  this._initScriptIds.set(initScript, script);
313
319
  }
@@ -37,13 +37,12 @@ var import_cookieStore = require("../cookieStore");
37
37
  var network = __toESM(require("../network"));
38
38
  var bidi = __toESM(require("./third_party/bidiProtocol"));
39
39
  class BidiNetworkManager {
40
- constructor(bidiSession, page, onNavigationResponseStarted) {
40
+ constructor(bidiSession, page) {
41
41
  this._userRequestInterceptionEnabled = false;
42
42
  this._protocolRequestInterceptionEnabled = false;
43
43
  this._session = bidiSession;
44
44
  this._requests = /* @__PURE__ */ new Map();
45
45
  this._page = page;
46
- this._onNavigationResponseStarted = onNavigationResponseStarted;
47
46
  this._eventListeners = [
48
47
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "network.beforeRequestSent", this._onBeforeRequestSent.bind(this)),
49
48
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "network.responseStarted", this._onResponseStarted.bind(this)),
@@ -112,8 +111,6 @@ class BidiNetworkManager {
112
111
  response.setRawResponseHeaders(null);
113
112
  response.setResponseHeadersSize(params.response.headersSize);
114
113
  this._page.frameManager.requestReceivedResponse(response);
115
- if (params.navigation)
116
- this._onNavigationResponseStarted(params);
117
114
  }
118
115
  _onResponseCompleted(params) {
119
116
  const request = this._requests.get(params.request.request);
@@ -32,7 +32,6 @@ __export(bidiPage_exports, {
32
32
  kPlaywrightBindingChannel: () => kPlaywrightBindingChannel
33
33
  });
34
34
  module.exports = __toCommonJS(bidiPage_exports);
35
- var import_utils = require("../../utils");
36
35
  var import_eventsHelper = require("../utils/eventsHelper");
37
36
  var dialog = __toESM(require("../dialog"));
38
37
  var dom = __toESM(require("../dom"));
@@ -56,7 +55,7 @@ class BidiPage {
56
55
  this._realmToContext = /* @__PURE__ */ new Map();
57
56
  this._page = new import_page.Page(this, browserContext);
58
57
  this._browserContext = browserContext;
59
- this._networkManager = new import_bidiNetworkManager.BidiNetworkManager(this._session, this._page, this._onNavigationResponseStarted.bind(this));
58
+ this._networkManager = new import_bidiNetworkManager.BidiNetworkManager(this._session, this._page);
60
59
  this._pdf = new import_bidiPdf.BidiPDF(this._session);
61
60
  this._page.on(import_page.Page.Events.FrameDetached, (frame) => this._removeContextsForFrame(frame, false));
62
61
  this._sessionListeners = [
@@ -64,6 +63,7 @@ class BidiPage {
64
63
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "script.message", this._onScriptMessage.bind(this)),
65
64
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.contextDestroyed", this._onBrowsingContextDestroyed.bind(this)),
66
65
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.navigationStarted", this._onNavigationStarted.bind(this)),
66
+ import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.navigationCommitted", this._onNavigationCommitted.bind(this)),
67
67
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.navigationAborted", this._onNavigationAborted.bind(this)),
68
68
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.navigationFailed", this._onNavigationFailed.bind(this)),
69
69
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.fragmentNavigated", this._onFragmentNavigated.bind(this)),
@@ -160,28 +160,12 @@ class BidiPage {
160
160
  _onNavigationStarted(params) {
161
161
  const frameId = params.context;
162
162
  this._page.frameManager.frameRequestedNavigation(frameId, params.navigation);
163
- const url = params.url.toLowerCase();
164
- if (url.startsWith("file:") || url.startsWith("data:") || url === "about:blank") {
165
- const frame = this._page.frameManager.frame(frameId);
166
- if (frame)
167
- this._page.frameManager.frameCommittedNewDocumentNavigation(
168
- frameId,
169
- params.url,
170
- "",
171
- params.navigation,
172
- /* initial */
173
- false
174
- );
175
- }
176
163
  }
177
- // TODO: there is no separate event for committed navigation, so we approximate it with responseStarted.
178
- _onNavigationResponseStarted(params) {
164
+ _onNavigationCommitted(params) {
179
165
  const frameId = params.context;
180
- const frame = this._page.frameManager.frame(frameId);
181
- (0, import_utils.assert)(frame);
182
166
  this._page.frameManager.frameCommittedNewDocumentNavigation(
183
167
  frameId,
184
- params.response.url,
168
+ params.url,
185
169
  "",
186
170
  params.navigation,
187
171
  /* initial */
@@ -19,6 +19,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var bidiProtocolCore_exports = {};
20
20
  __export(bidiProtocolCore_exports, {
21
21
  BrowsingContext: () => BrowsingContext,
22
+ Emulation: () => Emulation,
22
23
  ErrorCode: () => ErrorCode,
23
24
  Input: () => Input,
24
25
  Log: () => Log,
@@ -27,12 +28,6 @@ __export(bidiProtocolCore_exports, {
27
28
  Session: () => Session
28
29
  });
29
30
  module.exports = __toCommonJS(bidiProtocolCore_exports);
30
- /**
31
- * @license
32
- * Copyright 2024 Google Inc.
33
- * Modifications copyright (c) Microsoft Corporation.
34
- * SPDX-License-Identifier: Apache-2.0
35
- */
36
31
  var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
37
32
  ErrorCode2["InvalidArgument"] = "invalid argument";
38
33
  ErrorCode2["InvalidSelector"] = "invalid selector";
@@ -40,11 +35,13 @@ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
40
35
  ErrorCode2["InvalidWebExtension"] = "invalid web extension";
41
36
  ErrorCode2["MoveTargetOutOfBounds"] = "move target out of bounds";
42
37
  ErrorCode2["NoSuchAlert"] = "no such alert";
38
+ ErrorCode2["NoSuchNetworkCollector"] = "no such network collector";
43
39
  ErrorCode2["NoSuchElement"] = "no such element";
44
40
  ErrorCode2["NoSuchFrame"] = "no such frame";
45
41
  ErrorCode2["NoSuchHandle"] = "no such handle";
46
42
  ErrorCode2["NoSuchHistoryEntry"] = "no such history entry";
47
43
  ErrorCode2["NoSuchIntercept"] = "no such intercept";
44
+ ErrorCode2["NoSuchNetworkData"] = "no such network data";
48
45
  ErrorCode2["NoSuchNode"] = "no such node";
49
46
  ErrorCode2["NoSuchRequest"] = "no such request";
50
47
  ErrorCode2["NoSuchScript"] = "no such script";
@@ -56,6 +53,7 @@ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
56
53
  ErrorCode2["UnableToCloseBrowser"] = "unable to close browser";
57
54
  ErrorCode2["UnableToSetCookie"] = "unable to set cookie";
58
55
  ErrorCode2["UnableToSetFileInput"] = "unable to set file input";
56
+ ErrorCode2["UnavailableNetworkData"] = "unavailable network data";
59
57
  ErrorCode2["UnderspecifiedStoragePartition"] = "underspecified storage partition";
60
58
  ErrorCode2["UnknownCommand"] = "unknown command";
61
59
  ErrorCode2["UnknownError"] = "unknown error";
@@ -96,15 +94,43 @@ var BrowsingContext;
96
94
  CreateType2["Window"] = "window";
97
95
  })(CreateType = BrowsingContext2.CreateType || (BrowsingContext2.CreateType = {}));
98
96
  })(BrowsingContext || (BrowsingContext = {}));
97
+ var Emulation;
98
+ ((Emulation2) => {
99
+ let ForcedColorsModeTheme;
100
+ ((ForcedColorsModeTheme2) => {
101
+ ForcedColorsModeTheme2["Light"] = "light";
102
+ ForcedColorsModeTheme2["Dark"] = "dark";
103
+ })(ForcedColorsModeTheme = Emulation2.ForcedColorsModeTheme || (Emulation2.ForcedColorsModeTheme = {}));
104
+ })(Emulation || (Emulation = {}));
105
+ ((Emulation2) => {
106
+ let ScreenOrientationNatural;
107
+ ((ScreenOrientationNatural2) => {
108
+ ScreenOrientationNatural2["Portrait"] = "portrait";
109
+ ScreenOrientationNatural2["Landscape"] = "landscape";
110
+ })(ScreenOrientationNatural = Emulation2.ScreenOrientationNatural || (Emulation2.ScreenOrientationNatural = {}));
111
+ })(Emulation || (Emulation = {}));
99
112
  var Network;
113
+ ((Network2) => {
114
+ let CollectorType;
115
+ ((CollectorType2) => {
116
+ CollectorType2["Blob"] = "blob";
117
+ })(CollectorType = Network2.CollectorType || (Network2.CollectorType = {}));
118
+ })(Network || (Network = {}));
100
119
  ((Network2) => {
101
120
  let SameSite;
102
121
  ((SameSite2) => {
103
122
  SameSite2["Strict"] = "strict";
104
123
  SameSite2["Lax"] = "lax";
105
124
  SameSite2["None"] = "none";
125
+ SameSite2["Default"] = "default";
106
126
  })(SameSite = Network2.SameSite || (Network2.SameSite = {}));
107
127
  })(Network || (Network = {}));
128
+ ((Network2) => {
129
+ let DataType;
130
+ ((DataType2) => {
131
+ DataType2["Response"] = "response";
132
+ })(DataType = Network2.DataType || (Network2.DataType = {}));
133
+ })(Network || (Network = {}));
108
134
  ((Network2) => {
109
135
  let InterceptPhase;
110
136
  ((InterceptPhase2) => {
@@ -143,6 +169,7 @@ var Input;
143
169
  // Annotate the CommonJS export names for ESM import in node:
144
170
  0 && (module.exports = {
145
171
  BrowsingContext,
172
+ Emulation,
146
173
  ErrorCode,
147
174
  Input,
148
175
  Log,
@@ -63,8 +63,7 @@ class Browser extends import_instrumentation.SdkObject {
63
63
  context._clientCertificatesProxy = clientCertificatesProxy;
64
64
  if (options.__testHookBeforeSetStorageState)
65
65
  await progress.race(options.__testHookBeforeSetStorageState());
66
- if (options.storageState)
67
- await context.setStorageState(progress, options.storageState);
66
+ await context.setStorageState(progress, options.storageState, "initial");
68
67
  this.emit(Browser.Events.Context, context);
69
68
  return context;
70
69
  } catch (error) {
@@ -66,7 +66,7 @@ class BrowserContext extends import_instrumentation.SdkObject {
66
66
  this._origins = /* @__PURE__ */ new Set();
67
67
  this._harRecorders = /* @__PURE__ */ new Map();
68
68
  this._tempDirs = [];
69
- this._settingStorageState = false;
69
+ this._creatingStorageStatePage = false;
70
70
  this.initScripts = [];
71
71
  this._routesInFlight = /* @__PURE__ */ new Set();
72
72
  this._playwrightBindingExposed = false;
@@ -175,15 +175,11 @@ if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { co
175
175
  page = void 0;
176
176
  }
177
177
  await page?.mainFrame().gotoImpl(progress, "about:blank", {});
178
- await this._resetStorage(progress);
179
- await progress.race(this.clock.resetForReuse());
178
+ await this.clock.uninstall(progress);
180
179
  await progress.race(this.setUserAgent(this._options.userAgent));
181
- await progress.race(this.clearCache());
182
- await progress.race(this.doClearCookies());
183
180
  await progress.race(this.doUpdateDefaultEmulatedMedia());
184
181
  await progress.race(this.doUpdateDefaultViewport());
185
- if (this._options.storageState?.cookies)
186
- await progress.race(this.addCookies(this._options.storageState?.cookies));
182
+ await this.setStorageState(progress, this._options.storageState, "resetForReuse");
187
183
  await page?.resetForReuse(progress);
188
184
  }
189
185
  _browserClosed() {
@@ -496,63 +492,59 @@ if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { co
496
492
  }
497
493
  return result;
498
494
  }
499
- async _resetStorage(progress) {
500
- const oldOrigins = this._origins;
501
- const newOrigins = new Map(this._options.storageState?.origins?.map((p) => [p.origin, p]) || []);
502
- if (!oldOrigins.size && !newOrigins.size)
503
- return;
504
- let page = this.pages()[0];
505
- page = page || await this.newPage(progress, false);
506
- const interceptor = (route) => {
507
- route.fulfill({ body: "<html></html>" }).catch(() => {
508
- });
509
- };
510
- await page.addRequestInterceptor(progress, interceptor, "prepend");
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);
520
- }
495
+ isCreatingStorageStatePage() {
496
+ return this._creatingStorageStatePage;
521
497
  }
522
- isSettingStorageState() {
523
- return this._settingStorageState;
524
- }
525
- async setStorageState(progress, state) {
498
+ async setStorageState(progress, state, mode) {
526
499
  let page;
527
- this._settingStorageState = true;
500
+ let interceptor;
528
501
  try {
529
- if (state.cookies)
502
+ if (mode !== "initial") {
503
+ await progress.race(this.clearCache());
504
+ await progress.race(this.doClearCookies());
505
+ }
506
+ if (state?.cookies)
530
507
  await progress.race(this.addCookies(state.cookies));
531
- if (state.origins && state.origins.length) {
532
- page = await this.newPage(progress, true);
533
- await page.addRequestInterceptor(progress, (route) => {
508
+ const newOrigins = new Map(state?.origins?.map((p) => [p.origin, p]) || []);
509
+ const allOrigins = /* @__PURE__ */ new Set([...this._origins, ...newOrigins.keys()]);
510
+ if (allOrigins.size) {
511
+ if (mode === "resetForReuse")
512
+ page = this.pages()[0];
513
+ if (!page) {
514
+ try {
515
+ this._creatingStorageStatePage = mode !== "resetForReuse";
516
+ page = await this.newPage(progress, this._creatingStorageStatePage);
517
+ } finally {
518
+ this._creatingStorageStatePage = false;
519
+ }
520
+ }
521
+ interceptor = (route) => {
534
522
  route.fulfill({ body: "<html></html>" }).catch(() => {
535
523
  });
536
- }, "prepend");
537
- for (const originState of state.origins) {
524
+ };
525
+ await page.addRequestInterceptor(progress, interceptor, "prepend");
526
+ for (const origin of allOrigins) {
538
527
  const frame = page.mainFrame();
539
- await frame.gotoImpl(progress, originState.origin, {});
528
+ await frame.gotoImpl(progress, origin, {});
540
529
  const restoreScript = `(() => {
541
530
  const module = {};
542
531
  ${rawStorageSource.source}
543
532
  const script = new (module.exports.StorageScript())(${this._browser.options.name === "firefox"});
544
- return script.restore(${JSON.stringify(originState)});
533
+ return script.restore(${JSON.stringify(newOrigins.get(origin))});
545
534
  })()`;
546
535
  await progress.race(frame.evaluateExpression(restoreScript, { world: "utility" }));
547
536
  }
548
537
  }
538
+ this._origins = /* @__PURE__ */ new Set([...newOrigins.keys()]);
549
539
  } catch (error) {
550
540
  (0, import_stackTrace.rewriteErrorMessage)(error, `Error setting storage state:
551
541
  ` + error.message);
552
542
  throw error;
553
543
  } finally {
554
- await page?.close();
555
- this._settingStorageState = false;
544
+ if (mode !== "resetForReuse")
545
+ await page?.close();
546
+ else if (interceptor)
547
+ await page?.removeRequestInterceptor(interceptor);
556
548
  }
557
549
  }
558
550
  async extendInjectedScript(source, arg) {
@@ -42,6 +42,8 @@ const disabledFeatures = (assistantMode) => [
42
42
  "ThirdPartyStoragePartitioning",
43
43
  // See https://github.com/microsoft/playwright/issues/16126
44
44
  "Translate",
45
+ // See https://issues.chromium.org/u/1/issues/435410220
46
+ "AutoDeElevate",
45
47
  assistantMode ? "AutomationControlled" : ""
46
48
  ].filter(Boolean);
47
49
  const chromiumSwitches = (assistantMode, channel) => [
@@ -369,7 +369,7 @@ class FrameSession {
369
369
  ]);
370
370
  }
371
371
  async _initialize(hasUIWindow) {
372
- const isSettingStorageState = this._page.browserContext.isSettingStorageState();
372
+ const isSettingStorageState = this._page.browserContext.isCreatingStorageStatePage();
373
373
  if (!isSettingStorageState && hasUIWindow && !this._crPage._browserContext._browser.isClank() && !this._crPage._browserContext._options.noDefaultViewport) {
374
374
  const { windowId } = await this._client.send("Browser.getWindowForTarget");
375
375
  this._windowId = windowId;
@@ -37,8 +37,8 @@ class Clock {
37
37
  this._initScripts = [];
38
38
  this._browserContext = browserContext;
39
39
  }
40
- async resetForReuse() {
41
- await this._browserContext.removeInitScripts(this._initScripts);
40
+ async uninstall(progress) {
41
+ await progress.race(this._browserContext.removeInitScripts(this._initScripts));
42
42
  this._initScripts = [];
43
43
  }
44
44
  async fastForward(progress, ticks) {
@@ -287,6 +287,9 @@ class BrowserContextDispatcher extends import_dispatcher.Dispatcher {
287
287
  async storageState(params, progress) {
288
288
  return await progress.race(this._context.storageState(progress, params.indexedDB));
289
289
  }
290
+ async setStorageState(params, progress) {
291
+ await this._context.setStorageState(progress, params.storageState, "update");
292
+ }
290
293
  async close(params, progress) {
291
294
  progress.metadata.potentiallyClosesScope = true;
292
295
  await this._context.close(params);
@@ -342,6 +345,9 @@ class BrowserContextDispatcher extends import_dispatcher.Dispatcher {
342
345
  async clockSetSystemTime(params, progress) {
343
346
  await this._context.clock.setSystemTime(progress, params.timeString ?? params.timeNumber ?? 0);
344
347
  }
348
+ async clockUninstall(params, progress) {
349
+ await this._context.clock.uninstall(progress);
350
+ }
345
351
  async updateSubscription(params, progress) {
346
352
  if (params.enabled)
347
353
  this._subscriptions.add(params.event);
@@ -218,7 +218,7 @@ class FrameDispatcher extends import_dispatcher.Dispatcher {
218
218
  return result;
219
219
  }
220
220
  async ariaSnapshot(params, progress) {
221
- return { snapshot: await this._frame.ariaSnapshot(progress, params.selector, params) };
221
+ return { snapshot: await this._frame.ariaSnapshot(progress, params.selector) };
222
222
  }
223
223
  }
224
224
  // Annotate the CommonJS export names for ESM import in node:
package/lib/server/dom.js CHANGED
@@ -653,8 +653,8 @@ class ElementHandle extends js.JSHandle {
653
653
  async boundingBox() {
654
654
  return this._page.delegate.getBoundingBox(this);
655
655
  }
656
- async ariaSnapshot(options) {
657
- return await this.evaluateInUtility(([injected, element, options2]) => injected.ariaSnapshot(element, options2), options);
656
+ async ariaSnapshot() {
657
+ return await this.evaluateInUtility(([injected, element]) => injected.ariaSnapshot(element, { mode: "expect" }), {});
658
658
  }
659
659
  async screenshot(progress, options) {
660
660
  return await this._page.screenshotter.screenshotElement(progress, this, options);
@@ -1118,8 +1118,8 @@ class Frame extends import_instrumentation.SdkObject {
1118
1118
  async waitForTimeout(progress, timeout) {
1119
1119
  return progress.wait(timeout);
1120
1120
  }
1121
- async ariaSnapshot(progress, selector, options) {
1122
- return await this._retryWithProgressIfNotConnected(progress, selector, true, true, (handle) => progress.race(handle.ariaSnapshot(options)));
1121
+ async ariaSnapshot(progress, selector) {
1122
+ return await this._retryWithProgressIfNotConnected(progress, selector, true, true, (handle) => progress.race(handle.ariaSnapshot()));
1123
1123
  }
1124
1124
  async expect(progress, selector, options, timeout) {
1125
1125
  progress.log(`${(0, import_utils.renderTitleForCall)(progress.metadata)}${timeout ? ` with timeout ${timeout}ms` : ""}`);
@@ -1358,29 +1358,6 @@ class Frame extends import_instrumentation.SdkObject {
1358
1358
  return injectedScript.extend(source2, arg2);
1359
1359
  }, { source, arg });
1360
1360
  }
1361
- async resetStorageForCurrentOriginBestEffort(newStorage) {
1362
- const context = await this._utilityContext();
1363
- await context.evaluate(async ({ ls }) => {
1364
- sessionStorage.clear();
1365
- localStorage.clear();
1366
- for (const entry of ls || [])
1367
- localStorage[entry.name] = entry.value;
1368
- const registrations = navigator.serviceWorker ? await navigator.serviceWorker.getRegistrations() : [];
1369
- await Promise.all(registrations.map(async (r) => {
1370
- if (!r.installing && !r.waiting && !r.active)
1371
- r.unregister().catch(() => {
1372
- });
1373
- else
1374
- await r.unregister().catch(() => {
1375
- });
1376
- }));
1377
- for (const db of await indexedDB.databases?.() || []) {
1378
- if (db.name)
1379
- indexedDB.deleteDatabase(db.name);
1380
- }
1381
- }, { ls: newStorage?.localStorage }).catch(() => {
1382
- });
1383
- }
1384
1361
  _asLocator(selector) {
1385
1362
  return (0, import_utils.asLocator)(this._page.browserContext._browser.sdkLanguage(), selector);
1386
1363
  }
@@ -70,8 +70,7 @@ function serverSideCallMetadata() {
70
70
  type: "Internal",
71
71
  method: "",
72
72
  params: {},
73
- log: [],
74
- isServerSide: true
73
+ log: []
75
74
  };
76
75
  }
77
76
  // Annotate the CommonJS export names for ESM import in node:
@@ -50,18 +50,31 @@ async function launchApp(browserType, options) {
50
50
  "--test-type="
51
51
  );
52
52
  if (!channel && !options.persistentContextOptions?.executablePath)
53
- channel = (0, import_registry.findChromiumChannel)(options.sdkLanguage);
53
+ channel = (0, import_registry.findChromiumChannelBestEffort)(options.sdkLanguage);
54
54
  }
55
55
  const controller = new import_progress.ProgressController((0, import_instrumentation.serverSideCallMetadata)(), browserType);
56
- const context = await controller.run((progress) => browserType.launchPersistentContext(progress, "", {
57
- ignoreDefaultArgs: ["--enable-automation"],
58
- ...options?.persistentContextOptions,
59
- channel,
60
- noDefaultViewport: options.persistentContextOptions?.noDefaultViewport ?? true,
61
- acceptDownloads: options?.persistentContextOptions?.acceptDownloads ?? ((0, import_utils.isUnderTest)() ? "accept" : "internal-browser-default"),
62
- colorScheme: options?.persistentContextOptions?.colorScheme ?? "no-override",
63
- args
64
- }), 0);
56
+ let context;
57
+ try {
58
+ context = await controller.run((progress) => browserType.launchPersistentContext(progress, "", {
59
+ ignoreDefaultArgs: ["--enable-automation"],
60
+ ...options?.persistentContextOptions,
61
+ channel,
62
+ noDefaultViewport: options.persistentContextOptions?.noDefaultViewport ?? true,
63
+ acceptDownloads: options?.persistentContextOptions?.acceptDownloads ?? ((0, import_utils.isUnderTest)() ? "accept" : "internal-browser-default"),
64
+ colorScheme: options?.persistentContextOptions?.colorScheme ?? "no-override",
65
+ args
66
+ }), 0);
67
+ } catch (error) {
68
+ if (channel) {
69
+ error = (0, import_utils.rewriteErrorMessage)(error, [
70
+ `Failed to launch "${channel}" channel.`,
71
+ "Using custom channels could lead to unexpected behavior due to Enterprise policies (chrome://policy).",
72
+ "Install the default browser instead:",
73
+ (0, import_utils.wrapInASCIIBox)(`${(0, import_registry.buildPlaywrightCLICommand)(options.sdkLanguage, "install")}`, 2)
74
+ ].join("\n"));
75
+ }
76
+ throw error;
77
+ }
65
78
  const [page] = context.pages();
66
79
  if (browserType.name() === "chromium" && process.platform === "darwin") {
67
80
  context.on("page", async (newPage) => {
@@ -785,7 +785,7 @@ async function snapshotFrameForAI(progress, frame, frameOrdinal, frameIds) {
785
785
  const node = injected.document.body;
786
786
  if (!node)
787
787
  return true;
788
- return injected.ariaSnapshot(node, { forAI: true, refPrefix });
788
+ return injected.ariaSnapshot(node, { mode: "ai", refPrefix });
789
789
  }, frameOrdinal ? "f" + frameOrdinal : ""));
790
790
  if (snapshotOrRetry === true)
791
791
  return continuePolling;
@@ -31,7 +31,7 @@ __export(registry_exports, {
31
31
  Registry: () => Registry,
32
32
  browserDirectoryToMarkerFilePath: () => browserDirectoryToMarkerFilePath,
33
33
  buildPlaywrightCLICommand: () => buildPlaywrightCLICommand,
34
- findChromiumChannel: () => findChromiumChannel,
34
+ findChromiumChannelBestEffort: () => findChromiumChannelBestEffort,
35
35
  installBrowsersForNpmInstall: () => installBrowsersForNpmInstall,
36
36
  registry: () => registry,
37
37
  registryDirectory: () => registryDirectory,
@@ -1238,7 +1238,7 @@ async function installBrowsersForNpmInstall(browsers) {
1238
1238
  /* forceReinstall */
1239
1239
  );
1240
1240
  }
1241
- function findChromiumChannel(sdkLanguage) {
1241
+ function findChromiumChannelBestEffort(sdkLanguage) {
1242
1242
  let channel = null;
1243
1243
  for (const name of ["chromium", "chrome", "msedge"]) {
1244
1244
  try {
@@ -1278,7 +1278,7 @@ const registry = new Registry(require("../../../browsers.json"));
1278
1278
  Registry,
1279
1279
  browserDirectoryToMarkerFilePath,
1280
1280
  buildPlaywrightCLICommand,
1281
- findChromiumChannel,
1281
+ findChromiumChannelBestEffort,
1282
1282
  installBrowsersForNpmInstall,
1283
1283
  registry,
1284
1284
  registryDirectory,