patchright-core 1.52.4 → 1.55.0

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 (218) hide show
  1. package/ThirdPartyNotices.txt +65 -123
  2. package/bin/reinstall_chrome_beta_mac.sh +1 -1
  3. package/bin/reinstall_chrome_stable_mac.sh +1 -1
  4. package/bin/reinstall_msedge_beta_mac.sh +1 -1
  5. package/bin/reinstall_msedge_dev_mac.sh +1 -1
  6. package/bin/reinstall_msedge_stable_mac.sh +1 -1
  7. package/browsers.json +14 -14
  8. package/index.js +1 -1
  9. package/lib/androidServerImpl.js +4 -2
  10. package/lib/browserServerImpl.js +47 -12
  11. package/lib/cli/program.js +116 -50
  12. package/lib/cli/programWithTestStub.js +1 -1
  13. package/lib/client/android.js +30 -34
  14. package/lib/client/browser.js +54 -17
  15. package/lib/client/browserContext.js +67 -71
  16. package/lib/client/browserType.js +25 -34
  17. package/lib/client/channelOwner.js +20 -24
  18. package/lib/client/connection.js +6 -10
  19. package/lib/client/electron.js +8 -3
  20. package/lib/client/elementHandle.js +18 -21
  21. package/lib/client/fetch.js +5 -3
  22. package/lib/client/frame.js +57 -35
  23. package/lib/client/input.js +3 -1
  24. package/lib/client/jsHandle.js +4 -0
  25. package/lib/client/localUtils.js +0 -1
  26. package/lib/client/locator.js +32 -28
  27. package/lib/client/network.js +5 -12
  28. package/lib/client/page.js +32 -32
  29. package/lib/client/playwright.js +6 -16
  30. package/lib/client/selectors.js +18 -38
  31. package/lib/client/timeoutSettings.js +12 -8
  32. package/lib/client/tracing.js +24 -20
  33. package/lib/client/waiter.js +2 -2
  34. package/lib/client/webSocket.js +4 -22
  35. package/lib/generated/bindingsControllerSource.js +28 -0
  36. package/lib/generated/clockSource.js +1 -1
  37. package/lib/generated/injectedScriptSource.js +1 -1
  38. package/lib/generated/pollingRecorderSource.js +1 -1
  39. package/lib/generated/storageScriptSource.js +28 -0
  40. package/lib/generated/utilityScriptSource.js +1 -1
  41. package/lib/generated/webSocketMockSource.js +12 -50
  42. package/lib/inProcessFactory.js +9 -6
  43. package/lib/outofprocess.js +0 -2
  44. package/lib/protocol/validator.js +423 -346
  45. package/lib/protocol/validatorPrimitives.js +18 -4
  46. package/lib/remote/playwrightConnection.js +29 -166
  47. package/lib/remote/playwrightServer.js +233 -35
  48. package/lib/server/android/android.js +97 -83
  49. package/lib/server/android/backendAdb.js +0 -2
  50. package/lib/server/bidi/bidiBrowser.js +139 -73
  51. package/lib/server/bidi/bidiChromium.js +23 -22
  52. package/lib/server/bidi/bidiExecutionContext.js +2 -1
  53. package/lib/server/bidi/bidiFirefox.js +17 -14
  54. package/lib/server/bidi/bidiInput.js +22 -22
  55. package/lib/server/bidi/bidiNetworkManager.js +8 -11
  56. package/lib/server/bidi/bidiPage.js +42 -86
  57. package/lib/server/bidi/third_party/bidiProtocol.js +5 -133
  58. package/lib/server/bidi/third_party/bidiProtocolCore.js +179 -0
  59. package/lib/server/{dispatchers/selectorsDispatcher.js → bidi/third_party/bidiProtocolPermissions.js} +20 -18
  60. package/lib/server/browser.js +30 -21
  61. package/lib/server/browserContext.js +203 -165
  62. package/lib/server/browserType.js +109 -107
  63. package/lib/server/chromium/chromium.js +84 -69
  64. package/lib/server/chromium/chromiumSwitches.js +13 -20
  65. package/lib/server/chromium/crBrowser.js +74 -40
  66. package/lib/server/chromium/crConnection.js +8 -9
  67. package/lib/server/chromium/crCoverage.js +11 -8
  68. package/lib/server/chromium/crDragDrop.js +25 -20
  69. package/lib/server/chromium/crExecutionContext.js +2 -1
  70. package/lib/server/chromium/crInput.js +32 -29
  71. package/lib/server/chromium/crNetworkManager.js +45 -33
  72. package/lib/server/chromium/crPage.js +98 -73
  73. package/lib/server/chromium/crServiceWorker.js +13 -18
  74. package/lib/server/chromium/videoRecorder.js +10 -18
  75. package/lib/server/clock.js +51 -39
  76. package/lib/server/codegen/csharp.js +10 -5
  77. package/lib/server/codegen/java.js +1 -1
  78. package/lib/server/codegen/javascript.js +1 -1
  79. package/lib/server/codegen/jsonl.js +2 -1
  80. package/lib/server/codegen/language.js +22 -1
  81. package/lib/server/codegen/languages.js +4 -4
  82. package/lib/server/codegen/python.js +1 -1
  83. package/lib/server/cookieStore.js +3 -1
  84. package/lib/server/debugController.js +105 -71
  85. package/lib/server/debugger.js +6 -23
  86. package/lib/server/deviceDescriptorsSource.json +237 -127
  87. package/lib/server/dialog.js +50 -6
  88. package/lib/server/dispatchers/androidDispatcher.js +77 -62
  89. package/lib/server/dispatchers/artifactDispatcher.js +18 -18
  90. package/lib/server/dispatchers/browserContextDispatcher.js +141 -91
  91. package/lib/server/dispatchers/browserDispatcher.js +55 -88
  92. package/lib/server/dispatchers/browserTypeDispatcher.js +18 -9
  93. package/lib/server/dispatchers/cdpSessionDispatcher.js +4 -4
  94. package/lib/server/dispatchers/debugControllerDispatcher.js +12 -21
  95. package/lib/server/dispatchers/dialogDispatcher.js +4 -4
  96. package/lib/server/dispatchers/dispatcher.js +78 -53
  97. package/lib/server/dispatchers/electronDispatcher.js +19 -20
  98. package/lib/server/dispatchers/elementHandlerDispatcher.js +83 -93
  99. package/lib/server/dispatchers/frameDispatcher.js +99 -102
  100. package/lib/server/dispatchers/jsHandleDispatcher.js +21 -16
  101. package/lib/server/dispatchers/jsonPipeDispatcher.js +4 -4
  102. package/lib/server/dispatchers/localUtilsDispatcher.js +53 -59
  103. package/lib/server/dispatchers/networkDispatchers.js +41 -35
  104. package/lib/server/dispatchers/pageDispatcher.js +156 -107
  105. package/lib/server/dispatchers/playwrightDispatcher.js +37 -25
  106. package/lib/server/dispatchers/streamDispatcher.js +15 -8
  107. package/lib/server/dispatchers/tracingDispatcher.js +22 -13
  108. package/lib/server/dispatchers/webSocketRouteDispatcher.js +46 -35
  109. package/lib/server/dispatchers/writableStreamDispatcher.js +16 -10
  110. package/lib/server/dom.js +198 -266
  111. package/lib/server/download.js +3 -3
  112. package/lib/server/electron/electron.js +96 -103
  113. package/lib/server/electron/loader.js +1 -1
  114. package/lib/server/fetch.js +22 -41
  115. package/lib/server/fileUploadUtils.js +1 -1
  116. package/lib/server/firefox/ffBrowser.js +79 -55
  117. package/lib/server/firefox/ffExecutionContext.js +2 -1
  118. package/lib/server/firefox/ffInput.js +23 -23
  119. package/lib/server/firefox/ffNetworkManager.js +8 -6
  120. package/lib/server/firefox/ffPage.js +39 -36
  121. package/lib/server/firefox/firefox.js +9 -10
  122. package/lib/server/frameSelectors.js +65 -22
  123. package/lib/server/frames.js +516 -544
  124. package/lib/server/har/harRecorder.js +1 -1
  125. package/lib/server/har/harTracer.js +4 -2
  126. package/lib/server/helper.js +3 -7
  127. package/lib/server/index.js +0 -3
  128. package/lib/server/input.js +47 -54
  129. package/lib/server/instrumentation.js +8 -14
  130. package/lib/server/javascript.js +9 -17
  131. package/lib/server/launchApp.js +48 -30
  132. package/lib/server/localUtils.js +45 -38
  133. package/lib/server/network.js +44 -10
  134. package/lib/server/page.js +233 -178
  135. package/lib/server/pageBinding.js +6 -7
  136. package/lib/server/playwright.js +4 -14
  137. package/lib/server/progress.js +57 -49
  138. package/lib/server/recorder/recorderApp.js +298 -95
  139. package/lib/server/recorder/recorderRunner.js +23 -24
  140. package/lib/server/recorder/recorderSignalProcessor.js +83 -0
  141. package/lib/server/recorder/recorderUtils.js +67 -10
  142. package/lib/server/recorder.js +284 -146
  143. package/lib/server/registry/index.js +83 -48
  144. package/lib/server/registry/nativeDeps.js +175 -0
  145. package/lib/server/registry/oopDownloadBrowserMain.js +1 -1
  146. package/lib/server/screenshotter.js +84 -83
  147. package/lib/server/selectors.js +12 -12
  148. package/lib/server/socksClientCertificatesInterceptor.js +198 -136
  149. package/lib/server/trace/recorder/snapshotter.js +12 -19
  150. package/lib/server/trace/recorder/tracing.js +36 -27
  151. package/lib/server/trace/viewer/traceViewer.js +11 -20
  152. package/lib/server/transport.js +20 -22
  153. package/lib/server/utils/comparators.js +2 -2
  154. package/lib/server/utils/debug.js +3 -8
  155. package/lib/server/utils/debugLogger.js +8 -0
  156. package/lib/server/utils/hostPlatform.js +3 -1
  157. package/lib/server/utils/network.js +35 -25
  158. package/lib/server/utils/nodePlatform.js +1 -1
  159. package/lib/server/utils/processLauncher.js +4 -1
  160. package/lib/server/utils/wsServer.js +11 -17
  161. package/lib/server/webkit/webkit.js +5 -2
  162. package/lib/server/webkit/wkBrowser.js +51 -28
  163. package/lib/server/webkit/wkExecutionContext.js +2 -1
  164. package/lib/server/webkit/wkInput.js +25 -25
  165. package/lib/server/webkit/wkInterceptableRequest.js +1 -1
  166. package/lib/server/webkit/wkPage.js +80 -59
  167. package/lib/server/webkit/wkProvisionalPage.js +1 -1
  168. package/lib/server/webkit/wkWorkers.js +7 -7
  169. package/lib/utils/isomorphic/ariaSnapshot.js +13 -7
  170. package/lib/utils/isomorphic/cssParser.js +1 -2
  171. package/lib/utils/isomorphic/locatorGenerators.js +18 -0
  172. package/lib/utils/isomorphic/manualPromise.js +1 -2
  173. package/lib/utils/isomorphic/mimeType.js +1 -2
  174. package/lib/utils/isomorphic/multimap.js +1 -2
  175. package/lib/utils/isomorphic/oldUtilityScriptSerializers.js +248 -0
  176. package/lib/utils/isomorphic/protocolFormatter.js +78 -0
  177. package/lib/utils/isomorphic/protocolMetainfo.js +318 -0
  178. package/lib/utils/isomorphic/selectorParser.js +3 -4
  179. package/lib/utils/isomorphic/stringUtils.js +3 -24
  180. package/lib/utils/isomorphic/time.js +9 -4
  181. package/lib/utils/isomorphic/timeoutRunner.js +3 -4
  182. package/lib/utils/isomorphic/traceUtils.js +2 -3
  183. package/lib/utils/isomorphic/urlMatch.js +21 -7
  184. package/lib/utils/isomorphic/utilityScriptSerializers.js +208 -205
  185. package/lib/utils.js +8 -2
  186. package/lib/utilsBundleImpl/index.js +160 -150
  187. package/lib/vite/htmlReport/index.html +17 -17
  188. package/lib/vite/recorder/assets/{codeMirrorModule-CXVeovup.js → codeMirrorModule-DzQ0k89p.js} +1 -1
  189. package/lib/vite/recorder/assets/{index-eHBmevrY.css → index-CI4HQ-Zb.css} +1 -1
  190. package/lib/vite/recorder/assets/index-D7C7daHH.js +184 -0
  191. package/lib/vite/recorder/index.html +3 -3
  192. package/lib/vite/traceViewer/assets/{codeMirrorModule-_GLjJL-7.js → codeMirrorModule-Di48jgWx.js} +1 -1
  193. package/lib/vite/traceViewer/assets/defaultSettingsView-szBn8781.js +256 -0
  194. package/lib/vite/traceViewer/defaultSettingsView.DVJHpiGt.css +1 -0
  195. package/lib/vite/traceViewer/index.BFsek2M6.css +1 -0
  196. package/lib/vite/traceViewer/index.DQvXoPLL.js +2 -0
  197. package/lib/vite/traceViewer/index.html +6 -6
  198. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  199. package/lib/vite/traceViewer/uiMode.dBV3oN9h.js +5 -0
  200. package/lib/vite/traceViewer/uiMode.html +4 -4
  201. package/lib/zipBundleImpl.js +4 -4
  202. package/package.json +1 -1
  203. package/types/protocol.d.ts +712 -107
  204. package/types/types.d.ts +148 -37
  205. package/lib/generated/consoleApiSource.js +0 -28
  206. package/lib/protocol/debug.js +0 -211
  207. package/lib/server/recorder/contextRecorder.js +0 -286
  208. package/lib/server/recorder/recorderCollection.js +0 -116
  209. package/lib/server/recorder/recorderFrontend.js +0 -16
  210. package/lib/server/storageScript.js +0 -154
  211. package/lib/server/timeoutSettings.js +0 -89
  212. package/lib/utils/isomorphic/builtins.js +0 -86
  213. package/lib/vite/recorder/assets/index-BsWQsSGl.js +0 -184
  214. package/lib/vite/traceViewer/assets/defaultSettingsView-DtCQiGHe.js +0 -265
  215. package/lib/vite/traceViewer/defaultSettingsView.QdHITyLI.css +0 -1
  216. package/lib/vite/traceViewer/index.CFOW-Ezb.css +0 -1
  217. package/lib/vite/traceViewer/index.cFZzK9RN.js +0 -2
  218. package/lib/vite/traceViewer/uiMode.XVPIqBeS.js +0 -5
@@ -29,7 +29,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  var browserContext_exports = {};
30
30
  __export(browserContext_exports, {
31
31
  BrowserContext: () => BrowserContext,
32
- assertBrowserContextIsNotOwned: () => assertBrowserContextIsNotOwned,
33
32
  normalizeProxySettings: () => normalizeProxySettings,
34
33
  validateBrowserContextOptions: () => validateBrowserContextOptions,
35
34
  verifyClientCertificates: () => verifyClientCertificates,
@@ -38,58 +37,55 @@ __export(browserContext_exports, {
38
37
  module.exports = __toCommonJS(browserContext_exports);
39
38
  var import_fs = __toESM(require("fs"));
40
39
  var import_path = __toESM(require("path"));
41
- var import_timeoutSettings = require("./timeoutSettings");
42
40
  var import_crypto = require("./utils/crypto");
43
41
  var import_debug = require("./utils/debug");
44
42
  var import_clock = require("./clock");
45
43
  var import_debugger = require("./debugger");
44
+ var import_dialog = require("./dialog");
46
45
  var import_fetch = require("./fetch");
47
46
  var import_fileUtils = require("./utils/fileUtils");
47
+ var import_stackTrace = require("../utils/isomorphic/stackTrace");
48
48
  var import_harRecorder = require("./har/harRecorder");
49
49
  var import_helper = require("./helper");
50
50
  var import_instrumentation = require("./instrumentation");
51
- var import_builtins = require("../utils/isomorphic/builtins");
52
- var utilityScriptSerializers = __toESM(require("../utils/isomorphic/utilityScriptSerializers"));
53
51
  var network = __toESM(require("./network"));
54
52
  var import_page = require("./page");
55
53
  var import_page2 = require("./page");
56
- var import_recorder = require("./recorder");
57
54
  var import_recorderApp = require("./recorder/recorderApp");
58
- var storageScript = __toESM(require("./storageScript"));
59
- var consoleApiSource = __toESM(require("../generated/consoleApiSource"));
55
+ var import_selectors = require("./selectors");
60
56
  var import_tracing = require("./trace/recorder/tracing");
57
+ var rawStorageSource = __toESM(require("../generated/storageScriptSource"));
61
58
  class BrowserContext extends import_instrumentation.SdkObject {
62
59
  constructor(browser, options, browserContextId) {
63
60
  super(browser, "browser-context");
64
- this._timeoutSettings = new import_timeoutSettings.TimeoutSettings();
65
61
  this._pageBindings = /* @__PURE__ */ new Map();
66
- this._activeProgressControllers = /* @__PURE__ */ new Set();
62
+ this.requestInterceptors = [];
67
63
  this._closedStatus = "open";
68
64
  this._permissions = /* @__PURE__ */ new Map();
69
65
  this._downloads = /* @__PURE__ */ new Set();
70
66
  this._origins = /* @__PURE__ */ new Set();
71
67
  this._harRecorders = /* @__PURE__ */ new Map();
72
68
  this._tempDirs = [];
73
- this._settingStorageState = false;
69
+ this._creatingStorageStatePage = false;
74
70
  this.initScripts = [];
75
71
  this._routesInFlight = /* @__PURE__ */ new Set();
72
+ this._playwrightBindingExposed = false;
76
73
  this.attribution.context = this;
77
74
  this._browser = browser;
78
75
  this._options = options;
79
76
  this._browserContextId = browserContextId;
80
77
  this._isPersistentContext = !browserContextId;
81
78
  this._closePromise = new Promise((fulfill) => this._closePromiseFulfill = fulfill);
79
+ this._selectors = new import_selectors.Selectors(options.selectorEngines || [], options.testIdAttributeName);
82
80
  this.fetchRequest = new import_fetch.BrowserContextAPIRequestContext(this);
83
- if (this._options.recordHar)
84
- this._harRecorders.set("", new import_harRecorder.HarRecorder(this, null, this._options.recordHar));
85
81
  this.tracing = new import_tracing.Tracing(this, browser.options.tracesDir);
86
82
  this.clock = new import_clock.Clock(this);
83
+ this.dialogManager = new import_dialog.DialogManager(this.instrumentation);
87
84
  }
88
85
  static {
89
86
  this.Events = {
90
87
  Console: "console",
91
88
  Close: "close",
92
- Dialog: "dialog",
93
89
  Page: "page",
94
90
  // Can't use just 'error' due to node.js special treatment of error events.
95
91
  // @see https://nodejs.org/api/events.html#events_error_events
@@ -102,34 +98,38 @@ class BrowserContext extends import_instrumentation.SdkObject {
102
98
  RequestFulfilled: "requestfulfilled",
103
99
  RequestContinued: "requestcontinued",
104
100
  BeforeClose: "beforeclose",
105
- VideoStarted: "videostarted"
101
+ VideoStarted: "videostarted",
102
+ RecorderEvent: "recorderevent"
106
103
  };
107
104
  }
108
105
  isPersistentContext() {
109
106
  return this._isPersistentContext;
110
107
  }
111
- setSelectors(selectors) {
112
- this._selectors = selectors;
113
- }
114
108
  selectors() {
115
- return this._selectors || this.attribution.playwright.selectors;
109
+ return this._selectors;
116
110
  }
117
111
  async _initialize() {
118
112
  if (this.attribution.playwright.options.isInternalPlaywright)
119
113
  return;
120
114
  this._debugger = new import_debugger.Debugger(this);
121
115
  if ((0, import_debug.debugMode)() === "inspector")
122
- await import_recorder.Recorder.show(this, import_recorderApp.RecorderApp.factory(this), { pauseOnNextStatement: true });
116
+ await import_recorderApp.RecorderApp.show(this, { pauseOnNextStatement: true });
123
117
  if (this._debugger.isPaused())
124
- import_recorder.Recorder.showInspectorNoReply(this, import_recorderApp.RecorderApp.factory(this));
118
+ import_recorderApp.RecorderApp.showInspectorNoReply(this);
125
119
  this._debugger.on(import_debugger.Debugger.Events.PausedStateChanged, () => {
126
120
  if (this._debugger.isPaused())
127
- import_recorder.Recorder.showInspectorNoReply(this, import_recorderApp.RecorderApp.factory(this));
121
+ import_recorderApp.RecorderApp.showInspectorNoReply(this);
128
122
  });
129
- if ((0, import_debug.debugMode)() === "console")
130
- await this.extendInjectedScript(consoleApiSource.source);
123
+ if ((0, import_debug.debugMode)() === "console") {
124
+ await this.extendInjectedScript(`
125
+ function installConsoleApi(injectedScript) { injectedScript.consoleApi.install(); }
126
+ module.exports = { default: () => installConsoleApi };
127
+ `);
128
+ }
131
129
  if (this._options.serviceWorkers === "block")
132
- await this.addInitScript(`navigator.serviceWorker.register = async () => { };`);
130
+ await this.addInitScript(`navigator.serviceWorker.register = async () => { };`, `
131
+ if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { console.warn('Service Worker registration blocked by Playwright'); };
132
+ `);
133
133
  if (this._options.permissions)
134
134
  await this.grantPermissions(this._options.permissions);
135
135
  }
@@ -145,13 +145,10 @@ class BrowserContext extends import_instrumentation.SdkObject {
145
145
  return false;
146
146
  return true;
147
147
  }
148
- async stopPendingOperations(reason) {
149
- for (const controller of this._activeProgressControllers)
150
- controller.abort(new Error(reason));
151
- await new Promise((f) => setTimeout(f, 0));
152
- }
153
148
  static reusableContextHash(params) {
154
149
  const paramsCopy = { ...params };
150
+ if (paramsCopy.selectorEngines?.length === 0)
151
+ delete paramsCopy.selectorEngines;
155
152
  for (const k of Object.keys(paramsCopy)) {
156
153
  const key = k;
157
154
  if (paramsCopy[key] === defaultNewContextParamValues[key])
@@ -161,42 +158,29 @@ class BrowserContext extends import_instrumentation.SdkObject {
161
158
  delete paramsCopy[key];
162
159
  return JSON.stringify(paramsCopy);
163
160
  }
164
- async resetForReuse(metadata, params) {
165
- this.setDefaultNavigationTimeout(void 0);
166
- this.setDefaultTimeout(void 0);
167
- this.tracing.resetForReuse();
161
+ async resetForReuse(progress, params) {
162
+ await this.tracing.resetForReuse(progress);
168
163
  if (params) {
169
164
  for (const key of paramsThatAllowContextReuse)
170
165
  this._options[key] = params[key];
166
+ if (params.testIdAttributeName)
167
+ this.selectors().setTestIdAttributeName(params.testIdAttributeName);
171
168
  }
172
- await this._cancelAllRoutesInFlight();
173
169
  let page = this.pages()[0];
174
- const [, ...otherPages] = this.pages();
170
+ const otherPages = this.possiblyUninitializedPages().filter((p) => p !== page);
175
171
  for (const p of otherPages)
176
- await p.close(metadata);
172
+ await p.close();
177
173
  if (page && page.hasCrashed()) {
178
- await page.close(metadata);
174
+ await page.close();
179
175
  page = void 0;
180
176
  }
181
- page?._frameManager.setCloseAllOpeningDialogs(true);
182
- await page?._frameManager.closeOpenDialogs();
183
- await page?.mainFrame().goto(metadata, "about:blank", { timeout: 0 });
184
- page?._frameManager.setCloseAllOpeningDialogs(false);
185
- await this._resetStorage();
186
- await this._removeExposedBindings();
187
- await this._removeInitScripts();
188
- this.clock.markAsUninstalled();
189
- if (this._options.permissions)
190
- await this.grantPermissions(this._options.permissions);
191
- else
192
- await this.clearPermissions();
193
- await this.setExtraHTTPHeaders(this._options.extraHTTPHeaders || []);
194
- await this.setGeolocation(this._options.geolocation);
195
- await this.setOffline(!!this._options.offline);
196
- await this.setUserAgent(this._options.userAgent);
197
- await this.clearCache();
198
- await this._resetCookies();
199
- await page?.resetForReuse(metadata);
177
+ await page?.mainFrame().gotoImpl(progress, "about:blank", {});
178
+ await this.clock.uninstall(progress);
179
+ await progress.race(this.setUserAgent(this._options.userAgent));
180
+ await progress.race(this.doUpdateDefaultEmulatedMedia());
181
+ await progress.race(this.doUpdateDefaultViewport());
182
+ await this.setStorageState(progress, this._options.storageState, "resetForReuse");
183
+ await page?.resetForReuse(progress);
200
184
  }
201
185
  _browserClosed() {
202
186
  for (const page of this.pages())
@@ -243,10 +227,23 @@ class BrowserContext extends import_instrumentation.SdkObject {
243
227
  setHTTPCredentials(httpCredentials) {
244
228
  return this.doSetHTTPCredentials(httpCredentials);
245
229
  }
246
- hasBinding(name) {
247
- return this._pageBindings.has(name);
230
+ getBindingClient(name) {
231
+ return this._pageBindings.get(name)?.forClient;
232
+ }
233
+ async exposePlaywrightBindingIfNeeded() {
234
+ if (this._playwrightBindingExposed)
235
+ return;
236
+ this._playwrightBindingExposed = true;
237
+ await this.doExposePlaywrightBinding();
238
+ this.bindingsInitScript = import_page2.PageBinding.createInitScript();
239
+ this.initScripts.push(this.bindingsInitScript);
240
+ await this.doAddInitScript(this.bindingsInitScript);
241
+ await this.safeNonStallingEvaluateInAllFrames(this.bindingsInitScript.source, "main");
242
+ }
243
+ needsPlaywrightBinding() {
244
+ return this._playwrightBindingExposed;
248
245
  }
249
- async exposeBinding(name, needsHandle, playwrightBinding) {
246
+ async exposeBinding(progress, name, needsHandle, playwrightBinding, forClient) {
250
247
  if (this._pageBindings.has(name))
251
248
  throw new Error(`Function "${name}" has been already registered`);
252
249
  for (const page of this.pages()) {
@@ -254,13 +251,13 @@ class BrowserContext extends import_instrumentation.SdkObject {
254
251
  throw new Error(`Function "${name}" has been already registered in one of the pages`);
255
252
  }
256
253
  const binding = new import_page2.PageBinding(name, playwrightBinding, needsHandle);
254
+ binding.forClient = forClient;
257
255
  this._pageBindings.set(name, binding);
258
256
  await this.doExposeBinding(binding);
259
257
  }
260
- async _removeExposedBindings() {
258
+ async removeExposedBindings(bindings) {
261
259
  for (const key of this._pageBindings.keys()) {
262
- if (!key.startsWith("__pw"))
263
- this._pageBindings.delete(key);
260
+ if (!key.startsWith("__pw")) this._pageBindings.delete(key);
264
261
  }
265
262
  await this.doRemoveExposedBindings();
266
263
  }
@@ -280,22 +277,39 @@ class BrowserContext extends import_instrumentation.SdkObject {
280
277
  this._permissions.clear();
281
278
  await this.doClearPermissions();
282
279
  }
283
- setDefaultNavigationTimeout(timeout) {
284
- this._timeoutSettings.setDefaultNavigationTimeout(timeout);
280
+ async setExtraHTTPHeaders(progress, headers) {
281
+ const oldHeaders = this._options.extraHTTPHeaders;
282
+ this._options.extraHTTPHeaders = headers;
283
+ try {
284
+ await progress.race(this.doUpdateExtraHTTPHeaders());
285
+ } catch (error) {
286
+ this._options.extraHTTPHeaders = oldHeaders;
287
+ this.doUpdateExtraHTTPHeaders().catch(() => {
288
+ });
289
+ throw error;
290
+ }
285
291
  }
286
- setDefaultTimeout(timeout) {
287
- this._timeoutSettings.setDefaultTimeout(timeout);
292
+ async setOffline(progress, offline) {
293
+ const oldOffline = this._options.offline;
294
+ this._options.offline = offline;
295
+ try {
296
+ await progress.race(this.doUpdateOffline());
297
+ } catch (error) {
298
+ this._options.offline = oldOffline;
299
+ this.doUpdateOffline().catch(() => {
300
+ });
301
+ throw error;
302
+ }
288
303
  }
289
304
  async _loadDefaultContextAsIs(progress) {
290
305
  if (!this.possiblyUninitializedPages().length) {
291
306
  const waitForEvent = import_helper.helper.waitForEvent(progress, this, BrowserContext.Events.Page);
292
- progress.cleanupWhenAborted(() => waitForEvent.dispose);
293
307
  await Promise.race([waitForEvent.promise, this._closePromise]);
294
308
  }
295
309
  const page = this.possiblyUninitializedPages()[0];
296
310
  if (!page)
297
311
  return;
298
- const pageOrError = await page.waitForInitializedOrError();
312
+ const pageOrError = await progress.race(page.waitForInitializedOrError());
299
313
  if (pageOrError instanceof Error)
300
314
  throw pageOrError;
301
315
  await page.mainFrame()._waitForLoadState(progress, "load");
@@ -307,8 +321,8 @@ class BrowserContext extends import_instrumentation.SdkObject {
307
321
  return;
308
322
  const browserName = this._browser.options.name;
309
323
  if (this._options.isMobile && browserName === "chromium" || this._options.locale && browserName === "webkit") {
310
- await this.newPage(progress.metadata);
311
- await defaultPage.close(progress.metadata);
324
+ await this.newPage(progress);
325
+ await defaultPage.close();
312
326
  }
313
327
  }
314
328
  _authenticateProxyViaHeader() {
@@ -331,17 +345,36 @@ class BrowserContext extends import_instrumentation.SdkObject {
331
345
  if (username)
332
346
  this._options.httpCredentials = { username, password: password || "" };
333
347
  }
334
- async addInitScript(source, name) {
335
- const initScript = new import_page.InitScript(source, false, name);
348
+ async addInitScript(progress, source) {
349
+ const initScript = new import_page.InitScript(source);
336
350
  this.initScripts.push(initScript);
337
- await this.doAddInitScript(initScript);
351
+ try {
352
+ const promise = this.doAddInitScript(initScript);
353
+ if (progress)
354
+ await progress.race(promise);
355
+ else
356
+ await promise;
357
+ return initScript;
358
+ } catch (error) {
359
+ this.removeInitScripts([initScript]).catch(() => {
360
+ });
361
+ throw error;
362
+ }
338
363
  }
339
- async _removeInitScripts() {
364
+ async removeInitScripts(initScripts) {
340
365
  this.initScripts.splice(0, this.initScripts.length);
341
366
  await this.doRemoveInitScripts();
342
367
  }
343
- async setRequestInterceptor(handler) {
344
- this._requestInterceptor = handler;
368
+ async addRequestInterceptor(progress, handler) {
369
+ this.requestInterceptors.push(handler);
370
+ await this.doUpdateRequestInterception();
371
+ }
372
+ async removeRequestInterceptor(handler) {
373
+ const index = this.requestInterceptors.indexOf(handler);
374
+ if (index === -1)
375
+ return;
376
+ this.requestInterceptors.splice(index, 1);
377
+ await this.notifyRoutesInFlightAboutRemovedHandler(handler);
345
378
  await this.doUpdateRequestInterception();
346
379
  }
347
380
  isClosingOrClosed() {
@@ -384,28 +417,41 @@ class BrowserContext extends import_instrumentation.SdkObject {
384
417
  }
385
418
  await this._closePromise;
386
419
  }
387
- async newPage(metadata) {
388
- const page = await this.doCreateNewPage();
389
- if (metadata.isServerSide)
390
- page.markAsServerSideOnly();
391
- const pageOrError = await page.waitForInitializedOrError();
392
- if (pageOrError instanceof import_page2.Page) {
393
- if (pageOrError.isClosed())
394
- throw new Error("Page has been closed.");
395
- return pageOrError;
420
+ async newPage(progress, forStorageState) {
421
+ let page;
422
+ try {
423
+ this._creatingStorageStatePage = !!forStorageState;
424
+ page = await progress.race(this.doCreateNewPage());
425
+ const pageOrError = await progress.race(page.waitForInitializedOrError());
426
+ if (pageOrError instanceof import_page2.Page) {
427
+ if (pageOrError.isClosed())
428
+ throw new Error("Page has been closed.");
429
+ return pageOrError;
430
+ }
431
+ throw pageOrError;
432
+ } catch (error) {
433
+ await page?.close({ reason: "Failed to create page" }).catch(() => {
434
+ });
435
+ throw error;
436
+ } finally {
437
+ this._creatingStorageStatePage = false;
396
438
  }
397
- throw pageOrError;
398
439
  }
399
440
  addVisitedOrigin(origin) {
400
441
  this._origins.add(origin);
401
442
  }
402
- async storageState(indexedDB = false) {
443
+ async storageState(progress, indexedDB = false) {
403
444
  const result = {
404
445
  cookies: await this.cookies(),
405
446
  origins: []
406
447
  };
407
448
  const originsToSave = new Set(this._origins);
408
- const collectScript = `(${storageScript.collect})(${utilityScriptSerializers.source}, (${import_builtins.builtins})(), ${this._browser.options.name === "firefox"}, ${indexedDB})`;
449
+ const collectScript = `(() => {
450
+ const module = {};
451
+ ${rawStorageSource.source}
452
+ const script = new (module.exports.StorageScript())(${this._browser.options.name === "firefox"});
453
+ return script.collect(${indexedDB});
454
+ })()`;
409
455
  for (const page of this.pages()) {
410
456
  const origin = page.mainFrame().origin();
411
457
  if (!origin || !originsToSave.has(origin))
@@ -419,80 +465,80 @@ class BrowserContext extends import_instrumentation.SdkObject {
419
465
  }
420
466
  }
421
467
  if (originsToSave.size) {
422
- const internalMetadata = (0, import_instrumentation.serverSideCallMetadata)();
423
- const page = await this.newPage(internalMetadata);
424
- await page._setServerRequestInterceptor((handler) => {
425
- handler.fulfill({ body: "<html></html>" }).catch(() => {
426
- });
427
- return true;
428
- });
429
- for (const origin of originsToSave) {
430
- const frame = page.mainFrame();
431
- await frame.goto(internalMetadata, origin);
432
- const storage = await frame.evaluateExpression(collectScript, { world: "utility" });
433
- if (storage.localStorage.length || storage.indexedDB?.length)
434
- result.origins.push({ origin, localStorage: storage.localStorage, indexedDB: storage.indexedDB });
468
+ const page = await this.newPage(
469
+ progress,
470
+ true
471
+ /* forStorageState */
472
+ );
473
+ try {
474
+ await page.addRequestInterceptor(progress, (route) => {
475
+ route.fulfill({ body: "<html></html>" }).catch(() => {
476
+ });
477
+ }, "prepend");
478
+ for (const origin of originsToSave) {
479
+ const frame = page.mainFrame();
480
+ await frame.gotoImpl(progress, origin, {});
481
+ const storage = await progress.race(frame.evaluateExpression(collectScript, { world: "utility" }));
482
+ if (storage.localStorage.length || storage.indexedDB?.length)
483
+ result.origins.push({ origin, localStorage: storage.localStorage, indexedDB: storage.indexedDB });
484
+ }
485
+ } finally {
486
+ await page.close();
435
487
  }
436
- await page.close(internalMetadata);
437
488
  }
438
489
  return result;
439
490
  }
440
- async _resetStorage() {
441
- const oldOrigins = this._origins;
442
- const newOrigins = new Map(this._options.storageState?.origins?.map((p) => [p.origin, p]) || []);
443
- if (!oldOrigins.size && !newOrigins.size)
444
- return;
445
- let page = this.pages()[0];
446
- const internalMetadata = (0, import_instrumentation.serverSideCallMetadata)();
447
- page = page || await this.newPage({
448
- ...internalMetadata,
449
- // Do not mark this page as internal, because we will leave it for later reuse
450
- // as a user-visible page.
451
- isServerSide: false
452
- });
453
- await page._setServerRequestInterceptor((handler) => {
454
- handler.fulfill({ body: "<html></html>" }).catch(() => {
455
- });
456
- return true;
457
- });
458
- for (const origin of /* @__PURE__ */ new Set([...oldOrigins, ...newOrigins.keys()])) {
459
- const frame = page.mainFrame();
460
- await frame.goto(internalMetadata, origin);
461
- await frame.resetStorageForCurrentOriginBestEffort(newOrigins.get(origin));
462
- }
463
- await page._setServerRequestInterceptor(void 0);
464
- this._origins = /* @__PURE__ */ new Set([...newOrigins.keys()]);
465
- }
466
- async _resetCookies() {
467
- await this.doClearCookies();
468
- if (this._options.storageState?.cookies)
469
- await this.addCookies(this._options.storageState?.cookies);
470
- }
471
- isSettingStorageState() {
472
- return this._settingStorageState;
491
+ isCreatingStorageStatePage() {
492
+ return this._creatingStorageStatePage;
473
493
  }
474
- async setStorageState(metadata, state) {
475
- this._settingStorageState = true;
494
+ async setStorageState(progress, state, mode) {
495
+ let page;
496
+ let interceptor;
476
497
  try {
477
- if (state.cookies)
478
- await this.addCookies(state.cookies);
479
- if (state.origins && state.origins.length) {
480
- const internalMetadata = (0, import_instrumentation.serverSideCallMetadata)();
481
- const page = await this.newPage(internalMetadata);
482
- await page._setServerRequestInterceptor((handler) => {
483
- handler.fulfill({ body: "<html></html>" }).catch(() => {
498
+ if (mode !== "initial") {
499
+ await progress.race(this.clearCache());
500
+ await progress.race(this.doClearCookies());
501
+ }
502
+ if (state?.cookies)
503
+ await progress.race(this.addCookies(state.cookies));
504
+ const newOrigins = new Map(state?.origins?.map((p) => [p.origin, p]) || []);
505
+ const allOrigins = /* @__PURE__ */ new Set([...this._origins, ...newOrigins.keys()]);
506
+ if (allOrigins.size) {
507
+ if (mode === "resetForReuse")
508
+ page = this.pages()[0];
509
+ if (!page)
510
+ page = await this.newPage(
511
+ progress,
512
+ mode !== "resetForReuse"
513
+ /* forStorageState */
514
+ );
515
+ interceptor = (route) => {
516
+ route.fulfill({ body: "<html></html>" }).catch(() => {
484
517
  });
485
- return true;
486
- });
487
- for (const originState of state.origins) {
518
+ };
519
+ await page.addRequestInterceptor(progress, interceptor, "prepend");
520
+ for (const origin of allOrigins) {
488
521
  const frame = page.mainFrame();
489
- await frame.goto(metadata, originState.origin);
490
- await frame.evaluateExpression(`(${storageScript.restore})(${utilityScriptSerializers.source}, (${import_builtins.builtins})(), ${JSON.stringify(originState)})`, { world: "utility" });
522
+ await frame.gotoImpl(progress, origin, {});
523
+ const restoreScript = `(() => {
524
+ const module = {};
525
+ ${rawStorageSource.source}
526
+ const script = new (module.exports.StorageScript())(${this._browser.options.name === "firefox"});
527
+ return script.restore(${JSON.stringify(newOrigins.get(origin))});
528
+ })()`;
529
+ await progress.race(frame.evaluateExpression(restoreScript, { world: "utility" }));
491
530
  }
492
- await page.close(internalMetadata);
493
531
  }
532
+ this._origins = /* @__PURE__ */ new Set([...newOrigins.keys()]);
533
+ } catch (error) {
534
+ (0, import_stackTrace.rewriteErrorMessage)(error, `Error setting storage state:
535
+ ` + error.message);
536
+ throw error;
494
537
  } finally {
495
- this._settingStorageState = false;
538
+ if (mode !== "resetForReuse")
539
+ await page?.close();
540
+ else if (interceptor)
541
+ await page?.removeRequestInterceptor(interceptor);
496
542
  }
497
543
  }
498
544
  async extendInjectedScript(source, arg) {
@@ -508,12 +554,12 @@ class BrowserContext extends import_instrumentation.SdkObject {
508
554
  async safeNonStallingEvaluateInAllFrames(expression, world, options = {}) {
509
555
  await Promise.all(this.pages().map((page) => page.safeNonStallingEvaluateInAllFrames(expression, world, options)));
510
556
  }
511
- async _harStart(page, options) {
557
+ harStart(page, options) {
512
558
  const harId = (0, import_crypto.createGuid)();
513
559
  this._harRecorders.set(harId, new import_harRecorder.HarRecorder(this, page, options));
514
560
  return harId;
515
561
  }
516
- async _harExport(harId) {
562
+ async harExport(harId) {
517
563
  const recorder = this._harRecorders.get(harId || "");
518
564
  return recorder.export();
519
565
  }
@@ -523,16 +569,8 @@ class BrowserContext extends import_instrumentation.SdkObject {
523
569
  removeRouteInFlight(route) {
524
570
  this._routesInFlight.delete(route);
525
571
  }
526
- async _cancelAllRoutesInFlight() {
527
- await Promise.all([...this._routesInFlight].map((r) => r.abort())).catch(() => {
528
- });
529
- this._routesInFlight.clear();
530
- }
531
- }
532
- function assertBrowserContextIsNotOwned(context) {
533
- for (const page of context.pages()) {
534
- if (page._ownedContext)
535
- throw new Error("Please use browser.newContext() for multi-page scripts that share the context.");
572
+ async notifyRoutesInFlightAboutRemovedHandler(handler) {
573
+ await Promise.all([...this._routesInFlight].map((route) => route.removeHandler(handler)));
536
574
  }
537
575
  }
538
576
  function validateBrowserContextOptions(options, browserOptions) {
@@ -620,7 +658,8 @@ const paramsThatAllowContextReuse = [
620
658
  "contrast",
621
659
  "screen",
622
660
  "userAgent",
623
- "viewport"
661
+ "viewport",
662
+ "testIdAttributeName"
624
663
  ];
625
664
  const defaultNewContextParamValues = {
626
665
  noDefaultViewport: false,
@@ -638,7 +677,6 @@ const defaultNewContextParamValues = {
638
677
  // Annotate the CommonJS export names for ESM import in node:
639
678
  0 && (module.exports = {
640
679
  BrowserContext,
641
- assertBrowserContextIsNotOwned,
642
680
  normalizeProxySettings,
643
681
  validateBrowserContextOptions,
644
682
  verifyClientCertificates,