@checkly/playwright-core 1.42.17 → 1.47.11

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 (246) hide show
  1. package/ThirdPartyNotices.txt +144 -109
  2. package/browsers.json +15 -25
  3. package/lib/androidServerImpl.js +1 -1
  4. package/lib/browserServerImpl.js +1 -1
  5. package/lib/cli/driver.js +1 -3
  6. package/lib/cli/program.js +5 -10
  7. package/lib/client/android.js +1 -1
  8. package/lib/client/api.js +7 -0
  9. package/lib/client/browserContext.js +37 -5
  10. package/lib/client/browserType.js +19 -11
  11. package/lib/client/channelOwner.js +19 -16
  12. package/lib/client/clientInstrumentation.js +17 -7
  13. package/lib/client/clock.js +68 -0
  14. package/lib/client/connection.js +9 -6
  15. package/lib/client/electron.js +7 -5
  16. package/lib/client/elementHandle.js +44 -14
  17. package/lib/client/eventEmitter.js +314 -0
  18. package/lib/client/fetch.js +81 -28
  19. package/lib/client/frame.js +2 -4
  20. package/lib/client/jsHandle.js +7 -1
  21. package/lib/client/locator.js +9 -0
  22. package/lib/client/network.js +12 -9
  23. package/lib/client/page.js +45 -23
  24. package/lib/client/playwright.js +3 -0
  25. package/lib/client/tracing.js +7 -4
  26. package/lib/common/socksProxy.js +2 -2
  27. package/lib/generated/clockSource.js +7 -0
  28. package/lib/generated/injectedScriptSource.js +1 -1
  29. package/lib/generated/recorderSource.js +1 -1
  30. package/lib/generated/utilityScriptSource.js +1 -1
  31. package/lib/protocol/serializers.js +12 -11
  32. package/lib/protocol/validator.js +137 -55
  33. package/lib/server/bidi/bidiBrowser.js +296 -0
  34. package/lib/server/bidi/bidiConnection.js +206 -0
  35. package/lib/server/bidi/bidiExecutionContext.js +162 -0
  36. package/lib/server/bidi/bidiFirefox.js +110 -0
  37. package/lib/server/bidi/bidiInput.js +174 -0
  38. package/lib/server/bidi/bidiNetworkManager.js +304 -0
  39. package/lib/server/bidi/bidiPage.js +456 -0
  40. package/lib/server/bidi/third_party/bidiDeserializer.js +93 -0
  41. package/lib/server/bidi/third_party/bidiKeyboard.js +238 -0
  42. package/lib/server/bidi/third_party/bidiProtocol.js +139 -0
  43. package/lib/server/bidi/third_party/bidiSerializer.js +144 -0
  44. package/lib/server/browser.js +9 -1
  45. package/lib/server/browserContext.js +97 -22
  46. package/lib/server/browserType.js +27 -20
  47. package/lib/server/chromium/chromium.js +30 -15
  48. package/lib/server/chromium/chromiumSwitches.js +6 -3
  49. package/lib/server/chromium/crBrowser.js +11 -17
  50. package/lib/server/chromium/crConnection.js +2 -2
  51. package/lib/server/chromium/crDragDrop.js +28 -29
  52. package/lib/server/chromium/crNetworkManager.js +130 -84
  53. package/lib/server/chromium/crPage.js +34 -79
  54. package/lib/server/chromium/crProtocolHelper.js +3 -1
  55. package/lib/server/chromium/crServiceWorker.js +20 -23
  56. package/lib/server/chromium/videoRecorder.js +1 -1
  57. package/lib/server/clock.js +125 -0
  58. package/lib/server/codegen/csharp.js +299 -0
  59. package/lib/server/codegen/java.js +235 -0
  60. package/lib/server/codegen/javascript.js +223 -0
  61. package/lib/server/codegen/jsonl.js +47 -0
  62. package/lib/server/codegen/language.js +76 -0
  63. package/lib/server/codegen/languages.js +30 -0
  64. package/lib/server/codegen/python.js +265 -0
  65. package/lib/server/codegen/types.js +5 -0
  66. package/lib/server/debugController.js +3 -5
  67. package/lib/server/deviceDescriptors.js +9 -4
  68. package/lib/server/deviceDescriptorsSource.json +239 -119
  69. package/lib/server/dispatchers/androidDispatcher.js +1 -1
  70. package/lib/server/dispatchers/browserContextDispatcher.js +51 -7
  71. package/lib/server/dispatchers/dispatcher.js +36 -40
  72. package/lib/server/dispatchers/frameDispatcher.js +1 -2
  73. package/lib/server/dispatchers/jsHandleDispatcher.js +1 -1
  74. package/lib/server/dispatchers/jsonPipeDispatcher.js +4 -6
  75. package/lib/server/dispatchers/localUtilsDispatcher.js +19 -5
  76. package/lib/server/dispatchers/networkDispatchers.js +2 -2
  77. package/lib/server/dispatchers/pageDispatcher.js +5 -2
  78. package/lib/server/dispatchers/playwrightDispatcher.js +1 -0
  79. package/lib/server/dispatchers/writableStreamDispatcher.js +8 -5
  80. package/lib/server/dom.js +90 -53
  81. package/lib/server/electron/electron.js +21 -4
  82. package/lib/server/fetch.js +74 -25
  83. package/lib/server/fileUploadUtils.js +7 -3
  84. package/lib/server/firefox/ffBrowser.js +36 -25
  85. package/lib/server/firefox/ffConnection.js +2 -2
  86. package/lib/server/firefox/ffNetworkManager.js +6 -4
  87. package/lib/server/firefox/ffPage.js +22 -24
  88. package/lib/server/firefox/firefox.js +25 -6
  89. package/lib/server/frameSelectors.js +2 -2
  90. package/lib/server/frames.js +205 -159
  91. package/lib/server/har/harTracer.js +4 -12
  92. package/lib/server/helper.js +3 -3
  93. package/lib/server/index.js +18 -0
  94. package/lib/server/input.js +18 -8
  95. package/lib/server/instrumentation.js +0 -4
  96. package/lib/server/isomorphic/utilityScriptSerializers.js +19 -5
  97. package/lib/server/javascript.js +3 -2
  98. package/lib/server/launchApp.js +3 -2
  99. package/lib/server/network.js +14 -4
  100. package/lib/server/page.js +75 -46
  101. package/lib/server/playwright.js +5 -2
  102. package/lib/server/recorder/codeGenerator.js +2 -1
  103. package/lib/server/recorder/contextRecorder.js +316 -0
  104. package/lib/server/recorder/csharp.js +2 -1
  105. package/lib/server/recorder/java.js +2 -1
  106. package/lib/server/recorder/javascript.js +2 -1
  107. package/lib/server/recorder/jsonl.js +2 -1
  108. package/lib/server/recorder/language.js +2 -1
  109. package/lib/server/recorder/python.js +2 -1
  110. package/lib/server/recorder/recorderApp.js +14 -5
  111. package/lib/server/recorder/recorderCollection.js +127 -0
  112. package/lib/server/recorder/recorderRunner.js +177 -0
  113. package/lib/server/recorder/recorderUtils.js +23 -0
  114. package/lib/server/recorder/throttledFile.js +46 -0
  115. package/lib/server/recorder/utils.js +2 -1
  116. package/lib/server/recorder.js +42 -418
  117. package/lib/server/registry/index.js +99 -100
  118. package/lib/server/registry/nativeDeps.js +107 -0
  119. package/lib/server/screenshotter.js +6 -12
  120. package/lib/server/socksClientCertificatesInterceptor.js +328 -0
  121. package/lib/server/trace/recorder/snapshotter.js +4 -1
  122. package/lib/server/trace/recorder/tracing.js +27 -96
  123. package/lib/server/trace/viewer/traceViewer.js +54 -67
  124. package/lib/server/transport.js +1 -1
  125. package/lib/server/webkit/webkit.js +5 -5
  126. package/lib/server/webkit/wkBrowser.js +14 -14
  127. package/lib/server/webkit/wkConnection.js +3 -3
  128. package/lib/server/webkit/wkInterceptableRequest.js +8 -4
  129. package/lib/server/webkit/wkPage.js +52 -34
  130. package/lib/server/webkit/wkProvisionalPage.js +36 -1
  131. package/lib/utils/crypto.js +141 -0
  132. package/lib/utils/debugLogger.js +2 -0
  133. package/lib/utils/env.js +4 -2
  134. package/lib/utils/expectUtils.js +33 -0
  135. package/lib/utils/fileUtils.js +140 -1
  136. package/lib/utils/glob.js +2 -1
  137. package/lib/utils/happy-eyeballs.js +29 -2
  138. package/lib/utils/hostPlatform.js +13 -4
  139. package/lib/utils/httpServer.js +54 -13
  140. package/lib/utils/index.js +53 -31
  141. package/lib/utils/isomorphic/cssTokenizer.js +1 -1
  142. package/lib/utils/isomorphic/locatorParser.js +1 -1
  143. package/lib/utils/isomorphic/mimeType.js +29 -0
  144. package/lib/utils/isomorphic/stringUtils.js +28 -1
  145. package/lib/utils/isomorphic/urlMatch.js +120 -0
  146. package/lib/utils/mimeType.js +2 -1
  147. package/lib/utils/network.js +7 -35
  148. package/lib/utils/stackTrace.js +2 -4
  149. package/lib/utils/timeoutRunner.js +11 -76
  150. package/lib/utils/zones.js +23 -60
  151. package/lib/utilsBundle.js +2 -1
  152. package/lib/utilsBundleImpl/index.js +33 -31
  153. package/lib/vite/htmlReport/index.html +12 -12
  154. package/lib/vite/recorder/assets/codeMirrorModule-BN0yUF4I.js +24 -0
  155. package/lib/vite/recorder/assets/{codicon-zGuYmc9o.ttf → codicon-DCmgc-ay.ttf} +0 -0
  156. package/lib/vite/recorder/assets/index-B-MT5gKo.css +1 -0
  157. package/lib/vite/recorder/assets/index-DVt3E1Ef.js +47 -0
  158. package/lib/vite/recorder/index.html +2 -2
  159. package/lib/vite/traceViewer/assets/codeMirrorModule-5yiV-3wl.js +16831 -0
  160. package/lib/vite/traceViewer/assets/codeMirrorModule-B7Z3vq11.js +24 -0
  161. package/lib/vite/traceViewer/assets/codeMirrorModule-C6p3E9Zg.js +24 -0
  162. package/lib/vite/traceViewer/assets/codeMirrorModule-CcviAl53.js +16831 -0
  163. package/lib/vite/traceViewer/assets/codeMirrorModule-CqYUz5ms.js +24 -0
  164. package/lib/vite/traceViewer/assets/codeMirrorModule-DS3v0XrQ.js +24 -0
  165. package/lib/vite/traceViewer/assets/codeMirrorModule-Dx6AXgMV.js +16838 -0
  166. package/lib/vite/traceViewer/assets/codeMirrorModule-T_sdMrbM.js +24 -0
  167. package/lib/vite/traceViewer/assets/codeMirrorModule-V7N6ppkd.js +15585 -0
  168. package/lib/vite/traceViewer/assets/testServerConnection-D-tXL3sj.js +224 -0
  169. package/lib/vite/traceViewer/assets/testServerConnection-DeE2kSzz.js +1 -0
  170. package/lib/vite/traceViewer/assets/workbench-Bjkiwcr1.js +19119 -0
  171. package/lib/vite/traceViewer/assets/workbench-C43LWZEX.js +72 -0
  172. package/lib/vite/traceViewer/assets/workbench-C5OQh9VX.js +19119 -0
  173. package/lib/vite/traceViewer/assets/workbench-Crj6jzdv.js +19119 -0
  174. package/lib/vite/traceViewer/assets/workbench-DrQjKdyE.js +72 -0
  175. package/lib/vite/traceViewer/assets/workbench-Pa1v1Ojh.js +72 -0
  176. package/lib/vite/traceViewer/assets/workbench-caTaZnzx.js +72 -0
  177. package/lib/vite/traceViewer/assets/workbench-u2lRPMOT.js +72 -0
  178. package/lib/vite/traceViewer/assets/wsPort-EUvw-dwH.js +18540 -0
  179. package/lib/vite/traceViewer/assets/xtermModule-CZ7sDYXB.js +6529 -0
  180. package/lib/vite/traceViewer/assets/xtermModule-_6TC5FYT.js +6529 -0
  181. package/lib/vite/traceViewer/codeMirrorModule.Cy8X9Wtw.css +344 -0
  182. package/lib/vite/traceViewer/codeMirrorModule.svF_VrcJ.css +344 -0
  183. package/lib/vite/traceViewer/codicon.DCmgc-ay.ttf +0 -0
  184. package/lib/vite/traceViewer/embedded.BBZ9gQEw.js +104 -0
  185. package/lib/vite/traceViewer/embedded.BQq6Psnz.js +104 -0
  186. package/lib/vite/traceViewer/embedded.BVDVQOzc.js +2 -0
  187. package/lib/vite/traceViewer/embedded.Bn8Ptzv6.js +2 -0
  188. package/lib/vite/traceViewer/embedded.CvhnUgIi.js +2 -0
  189. package/lib/vite/traceViewer/embedded.D27cnKiB.js +104 -0
  190. package/lib/vite/traceViewer/embedded.DPqrDeET.js +2 -0
  191. package/lib/vite/traceViewer/embedded.DbzY7Q8w.js +2 -0
  192. package/lib/vite/traceViewer/embedded.DjZq4InJ.css +68 -0
  193. package/lib/vite/traceViewer/embedded.html +16 -0
  194. package/lib/vite/traceViewer/embedded.w7WN2u1R.css +1 -0
  195. package/lib/vite/traceViewer/index.5mge2rY_.css +124 -0
  196. package/lib/vite/traceViewer/index.6KJ-JQ0L.js +180 -0
  197. package/lib/vite/traceViewer/index.B8dgQwuN.js +2 -0
  198. package/lib/vite/traceViewer/index.BGj8jY3H.js +2 -0
  199. package/lib/vite/traceViewer/index.BSak5QT9.js +2 -0
  200. package/lib/vite/traceViewer/index.C0EgJ4oW.js +195 -0
  201. package/lib/vite/traceViewer/index.CUpI-BFe.js +195 -0
  202. package/lib/vite/traceViewer/{index.-g_5lMbJ.css → index.CrbWWHbf.css} +1 -1
  203. package/lib/vite/traceViewer/index.DkRbtWVo.js +195 -0
  204. package/lib/vite/traceViewer/index.QanXxRUb.css +131 -0
  205. package/lib/vite/traceViewer/index._cX8k4co.js +2 -0
  206. package/lib/vite/traceViewer/index.html +5 -4
  207. package/lib/vite/traceViewer/index.pMAN88y-.js +2 -0
  208. package/lib/vite/traceViewer/snapshot.html +1 -1
  209. package/lib/vite/traceViewer/sw.bundle.js +3 -4
  210. package/lib/vite/traceViewer/uiMode.D-tg1Oci.js +1730 -0
  211. package/lib/vite/traceViewer/uiMode.D3cNFP6u.css +1 -0
  212. package/lib/vite/traceViewer/uiMode.DKjMBMlc.js +1730 -0
  213. package/lib/vite/traceViewer/uiMode.DVWUEIHq.css +1424 -0
  214. package/lib/vite/traceViewer/uiMode.DVrL7a1K.js +10 -0
  215. package/lib/vite/traceViewer/uiMode.Dg9oJCQU.js +10 -0
  216. package/lib/vite/traceViewer/uiMode.DwZAzstF.js +10 -0
  217. package/lib/vite/traceViewer/uiMode.O07awP3T.js +10 -0
  218. package/lib/vite/traceViewer/uiMode.gGHHTsyL.js +1730 -0
  219. package/lib/vite/traceViewer/uiMode.html +5 -4
  220. package/lib/vite/traceViewer/uiMode.iq7CyYy7.js +1490 -0
  221. package/lib/vite/traceViewer/uiMode.jY2s-9ps.js +10 -0
  222. package/lib/vite/traceViewer/uiMode.xvJHbkzl.css +1324 -0
  223. package/lib/vite/traceViewer/workbench.B3X2QtYa.css +3702 -0
  224. package/lib/vite/traceViewer/workbench.DjbIuxix.css +1 -0
  225. package/lib/vite/traceViewer/workbench.DyTpxWVb.css +1 -0
  226. package/lib/vite/traceViewer/workbench.wuxQoE2z.css +3703 -0
  227. package/lib/vite/traceViewer/wsPort.p5jUwABW.css +3450 -0
  228. package/lib/vite/traceViewer/xtermModule.4oRVGWQ-.css +209 -0
  229. package/lib/vite/traceViewer/xtermModule.OKEVRlkP.css +209 -0
  230. package/package.json +2 -2
  231. package/types/protocol.d.ts +960 -78
  232. package/types/structs.d.ts +1 -1
  233. package/types/types.d.ts +3083 -2448
  234. package/lib/vite/recorder/assets/codeMirrorModule-I9ks4y7D.js +0 -24
  235. package/lib/vite/recorder/assets/index-ljsTwXtJ.css +0 -1
  236. package/lib/vite/recorder/assets/index-yg8ypzl6.js +0 -47
  237. package/lib/vite/traceViewer/assets/codeMirrorModule-0bpaqixv.js +0 -24
  238. package/lib/vite/traceViewer/assets/wsPort-_JBDEilC.js +0 -69
  239. package/lib/vite/traceViewer/index.u51inEcm.js +0 -2
  240. package/lib/vite/traceViewer/uiMode.Fb0bNA4H.js +0 -10
  241. package/lib/vite/traceViewer/uiMode.pWy0Re7G.css +0 -1
  242. package/lib/vite/traceViewer/wsPort.zR1WIy9-.css +0 -1
  243. /package/lib/vite/recorder/assets/{codeMirrorModule-Hs9-1ZG4.css → codeMirrorModule-ez37Vkbh.css} +0 -0
  244. /package/lib/vite/traceViewer/assets/{xtermModule-Yt6xwiJ_.js → xtermModule-BeNbaIVa.js} +0 -0
  245. /package/lib/vite/traceViewer/{codeMirrorModule.Hs9-1ZG4.css → codeMirrorModule.ez37Vkbh.css} +0 -0
  246. /package/lib/vite/traceViewer/{xtermModule.0lwXJFHT.css → xtermModule.DSXBckUd.css} +0 -0
@@ -3,8 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.installRootRedirect = installRootRedirect;
6
7
  exports.openTraceInBrowser = openTraceInBrowser;
7
8
  exports.openTraceViewerApp = openTraceViewerApp;
9
+ exports.runTraceInBrowser = runTraceInBrowser;
10
+ exports.runTraceViewerApp = runTraceViewerApp;
11
+ exports.startTraceViewerServer = startTraceViewerServer;
8
12
  var _path = _interopRequireDefault(require("path"));
9
13
  var _fs = _interopRequireDefault(require("fs"));
10
14
  var _httpServer = require("../../../utils/httpServer");
@@ -31,17 +35,15 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
31
35
  * limitations under the License.
32
36
  */
33
37
 
34
- async function startTraceViewerServer(traceUrls, options) {
38
+ function validateTraceUrls(traceUrls) {
35
39
  for (const traceUrl of traceUrls) {
36
40
  let traceFile = traceUrl;
37
41
  // If .json is requested, we'll synthesize it.
38
42
  if (traceUrl.endsWith('.json')) traceFile = traceUrl.substring(0, traceUrl.length - '.json'.length);
39
- if (!traceUrl.startsWith('http://') && !traceUrl.startsWith('https://') && !_fs.default.existsSync(traceFile) && !_fs.default.existsSync(traceFile + '.trace')) {
40
- // eslint-disable-next-line no-console
41
- console.error(`Trace file ${traceUrl} does not exist!`);
42
- (0, _utils.gracefullyProcessExitDoNotHang)(1);
43
- }
43
+ if (!traceUrl.startsWith('http://') && !traceUrl.startsWith('https://') && !_fs.default.existsSync(traceFile) && !_fs.default.existsSync(traceFile + '.trace')) throw new Error(`Trace file ${traceUrl} does not exist!`);
44
44
  }
45
+ }
46
+ async function startTraceViewerServer(options) {
45
47
  const server = new _httpServer.HttpServer();
46
48
  server.routePrefix('/trace', (request, response) => {
47
49
  const url = new URL('http://localhost' + request.url);
@@ -68,67 +70,57 @@ async function startTraceViewerServer(traceUrls, options) {
68
70
  const absolutePath = _path.default.join(__dirname, '..', '..', '..', 'vite', 'traceViewer', ...relativePath.split('/'));
69
71
  return server.serveFile(request, response, absolutePath);
70
72
  });
71
- const params = traceUrls.map(t => `trace=${encodeURIComponent(t)}`);
72
73
  const transport = (options === null || options === void 0 ? void 0 : options.transport) || (options !== null && options !== void 0 && options.isServer ? new StdinServer() : undefined);
73
- if (transport) {
74
- const guid = (0, _utils.createGuid)();
75
- params.push('ws=' + guid);
76
- const wss = new _utilsBundle.wsServer({
77
- server: server.server(),
78
- path: '/' + guid
79
- });
80
- wss.on('connection', ws => {
81
- transport.sendEvent = (method, params) => ws.send(JSON.stringify({
82
- method,
83
- params
84
- }));
85
- transport.close = () => ws.close();
86
- ws.on('message', async message => {
87
- const {
88
- id,
89
- method,
90
- params
91
- } = JSON.parse(message);
92
- const result = await transport.dispatch(method, params);
93
- ws.send(JSON.stringify({
94
- id,
95
- result
96
- }));
97
- });
98
- ws.on('close', () => transport.onclose());
99
- ws.on('error', () => transport.onclose());
100
- });
101
- }
102
- if (options !== null && options !== void 0 && options.isServer) params.push('isServer');
103
- if ((0, _utils.isUnderTest)()) params.push('isUnderTest=true');
74
+ if (transport) server.createWebSocket(transport);
104
75
  const {
105
76
  host,
106
77
  port
107
78
  } = options || {};
108
- const url = await server.start({
79
+ await server.start({
109
80
  preferredPort: port,
110
81
  host
111
82
  });
112
- const {
113
- app
114
- } = options || {};
115
- const searchQuery = params.length ? '?' + params.join('&') : '';
116
- const urlPath = `/trace/${app || 'index.html'}${searchQuery}`;
117
- server.routePath('/', (request, response) => {
83
+ return server;
84
+ }
85
+ async function installRootRedirect(server, traceUrls, options) {
86
+ const params = new URLSearchParams();
87
+ for (const traceUrl of traceUrls) params.append('trace', traceUrl);
88
+ if (server.wsGuid()) params.append('ws', server.wsGuid());
89
+ if (options !== null && options !== void 0 && options.isServer) params.append('isServer', '');
90
+ if ((0, _utils.isUnderTest)()) params.append('isUnderTest', 'true');
91
+ for (const arg of options.args || []) params.append('arg', arg);
92
+ if (options.grep) params.append('grep', options.grep);
93
+ if (options.grepInvert) params.append('grepInvert', options.grepInvert);
94
+ for (const project of options.project || []) params.append('project', project);
95
+ if (options.workers) params.append('workers', String(options.workers));
96
+ if (options.timeout) params.append('timeout', String(options.timeout));
97
+ if (options.headed) params.append('headed', '');
98
+ if (options.outputDir) params.append('outputDir', options.outputDir);
99
+ if (options.updateSnapshots) params.append('updateSnapshots', options.updateSnapshots);
100
+ for (const reporter of options.reporter || []) params.append('reporter', reporter);
101
+ const urlPath = `./trace/${options.webApp || 'index.html'}?${params.toString()}`;
102
+ server.routePath('/', (_, response) => {
118
103
  response.statusCode = 302;
119
- response.setHeader('Location', urlPath + request.url.substring(1));
104
+ response.setHeader('Location', urlPath);
120
105
  response.end();
121
106
  return true;
122
107
  });
123
- return {
124
- server,
125
- url
126
- };
127
108
  }
128
- async function openTraceViewerApp(traceUrls, browserName, options) {
129
- const {
130
- url
131
- } = await startTraceViewerServer(traceUrls, options);
109
+ async function runTraceViewerApp(traceUrls, browserName, options, exitOnClose) {
110
+ validateTraceUrls(traceUrls);
111
+ const server = await startTraceViewerServer(options);
112
+ await installRootRedirect(server, traceUrls, options);
113
+ const page = await openTraceViewerApp(server.urlPrefix('precise'), browserName, options);
114
+ if (exitOnClose) page.on('close', () => (0, _utils.gracefullyProcessExitDoNotHang)(0));
115
+ return page;
116
+ }
117
+ async function runTraceInBrowser(traceUrls, options) {
118
+ validateTraceUrls(traceUrls);
119
+ const server = await startTraceViewerServer(options);
120
+ await installRootRedirect(server, traceUrls, options);
121
+ await openTraceInBrowser(server.urlPrefix('human-readable'));
122
+ }
123
+ async function openTraceViewerApp(url, browserName, options) {
132
124
  const traceViewerPlaywright = (0, _playwright.createPlaywright)({
133
125
  sdkLanguage: 'javascript',
134
126
  isInternalPlaywright: true
@@ -147,7 +139,7 @@ async function openTraceViewerApp(traceUrls, browserName, options) {
147
139
  persistentContextOptions: {
148
140
  ...(options === null || options === void 0 ? void 0 : options.persistentContextOptions),
149
141
  useWebSocket: (0, _utils.isUnderTest)(),
150
- headless: options === null || options === void 0 ? void 0 : options.headless
142
+ headless: !!(options !== null && options !== void 0 && options.headless)
151
143
  }
152
144
  });
153
145
  const controller = new _progress.ProgressController((0, _instrumentation.serverSideCallMetadata)(), context._browser);
@@ -162,10 +154,7 @@ async function openTraceViewerApp(traceUrls, browserName, options) {
162
154
  await page.mainFrame().goto((0, _instrumentation.serverSideCallMetadata)(), url);
163
155
  return page;
164
156
  }
165
- async function openTraceInBrowser(traceUrls, options) {
166
- const {
167
- url
168
- } = await startTraceViewerServer(traceUrls, options);
157
+ async function openTraceInBrowser(url) {
169
158
  // eslint-disable-next-line no-console
170
159
  console.log('\nListening on ' + url);
171
160
  if (!(0, _utils.isUnderTest)()) await (0, _utilsBundle.open)(url.replace('0.0.0.0', 'localhost')).catch(() => {});
@@ -184,19 +173,17 @@ class StdinServer {
184
173
  process.stdin.on('close', () => (0, _utils.gracefullyProcessExitDoNotHang)(0));
185
174
  }
186
175
  async dispatch(method, params) {
187
- if (method === 'ready') {
176
+ if (method === 'initialize') {
188
177
  if (this._traceUrl) this._loadTrace(this._traceUrl);
189
178
  }
190
179
  }
191
- onclose() {
192
- (0, _utils.gracefullyProcessExitDoNotHang)(0);
193
- }
194
- _loadTrace(url) {
180
+ onclose() {}
181
+ _loadTrace(traceUrl) {
195
182
  var _this$sendEvent;
196
- this._traceUrl = url;
183
+ this._traceUrl = traceUrl;
197
184
  clearTimeout(this._pollTimer);
198
- (_this$sendEvent = this.sendEvent) === null || _this$sendEvent === void 0 || _this$sendEvent.call(this, 'loadTrace', {
199
- url
185
+ (_this$sendEvent = this.sendEvent) === null || _this$sendEvent === void 0 || _this$sendEvent.call(this, 'loadTraceRequested', {
186
+ traceUrl
200
187
  });
201
188
  }
202
189
  _pollLoadTrace(url) {
@@ -155,7 +155,7 @@ class WebSocketTransport {
155
155
  this._ws.addEventListener('close', event => {
156
156
  var _this$_progress3;
157
157
  (_this$_progress3 = this._progress) === null || _this$_progress3 === void 0 || _this$_progress3.log(`<ws disconnected> ${logUrl} code=${event.code} reason=${event.reason}`);
158
- if (this.onclose) this.onclose.call(null);
158
+ if (this.onclose) this.onclose.call(null, event.reason);
159
159
  });
160
160
  // Prevent Error: read ECONNRESET.
161
161
  this._ws.addEventListener('error', error => {
@@ -31,28 +31,28 @@ class WebKit extends _browserType.BrowserType {
31
31
  constructor(parent) {
32
32
  super(parent, 'webkit');
33
33
  }
34
- _connectToTransport(transport, options) {
34
+ connectToTransport(transport, options) {
35
35
  return _wkBrowser.WKBrowser.connect(this.attribution.playwright, transport, options);
36
36
  }
37
- _amendEnvironment(env, userDataDir, executable, browserArguments) {
37
+ amendEnvironment(env, userDataDir, executable, browserArguments) {
38
38
  return {
39
39
  ...env,
40
40
  CURL_COOKIE_JAR_PATH: _path.default.join(userDataDir, 'cookiejar.db')
41
41
  };
42
42
  }
43
- _doRewriteStartupLog(error) {
43
+ doRewriteStartupLog(error) {
44
44
  if (!error.logs) return error;
45
45
  if (error.logs.includes('cannot open display')) error.logs = '\n' + (0, _utils.wrapInASCIIBox)(_browserType.kNoXServerRunningError, 1);
46
46
  return error;
47
47
  }
48
- _attemptToGracefullyCloseBrowser(transport) {
48
+ attemptToGracefullyCloseBrowser(transport) {
49
49
  transport.send({
50
50
  method: 'Playwright.close',
51
51
  params: {},
52
52
  id: _wkConnection.kBrowserCloseMessageId
53
53
  });
54
54
  }
55
- _defaultArgs(options, isPersistent, userDataDir) {
55
+ defaultArgs(options, isPersistent, userDataDir) {
56
56
  const {
57
57
  args = [],
58
58
  proxy,
@@ -7,7 +7,6 @@ exports.WKBrowserContext = exports.WKBrowser = void 0;
7
7
  var _browser = require("../browser");
8
8
  var _browserContext = require("../browserContext");
9
9
  var _utils = require("../../utils");
10
- var _eventsHelper = require("../../utils/eventsHelper");
11
10
  var network = _interopRequireWildcard(require("../network"));
12
11
  var _wkConnection = require("./wkConnection");
13
12
  var _wkPage = require("./wkPage");
@@ -31,8 +30,8 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
31
30
  * limitations under the License.
32
31
  */
33
32
 
34
- const DEFAULT_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15';
35
- const BROWSER_VERSION = '17.4';
33
+ const DEFAULT_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15';
34
+ const BROWSER_VERSION = '18.0';
36
35
  class WKBrowser extends _browser.Browser {
37
36
  static async connect(parent, transport, options) {
38
37
  const browser = new WKBrowser(parent, transport, options);
@@ -53,10 +52,17 @@ class WKBrowser extends _browser.Browser {
53
52
  this._browserSession = void 0;
54
53
  this._contexts = new Map();
55
54
  this._wkPages = new Map();
56
- this._eventListeners = void 0;
57
55
  this._connection = new _wkConnection.WKConnection(transport, this._onDisconnect.bind(this), options.protocolLogger, options.browserLogsCollector);
58
56
  this._browserSession = this._connection.browserSession;
59
- this._eventListeners = [_eventsHelper.eventsHelper.addEventListener(this._browserSession, 'Playwright.pageProxyCreated', this._onPageProxyCreated.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._browserSession, 'Playwright.pageProxyDestroyed', this._onPageProxyDestroyed.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._browserSession, 'Playwright.provisionalLoadFailed', event => this._onProvisionalLoadFailed(event)), _eventsHelper.eventsHelper.addEventListener(this._browserSession, 'Playwright.windowOpen', event => this._onWindowOpen(event)), _eventsHelper.eventsHelper.addEventListener(this._browserSession, 'Playwright.downloadCreated', this._onDownloadCreated.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._browserSession, 'Playwright.downloadFilenameSuggested', this._onDownloadFilenameSuggested.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._browserSession, 'Playwright.downloadFinished', this._onDownloadFinished.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._browserSession, 'Playwright.screencastFinished', this._onScreencastFinished.bind(this)), _eventsHelper.eventsHelper.addEventListener(this._browserSession, _wkConnection.kPageProxyMessageReceived, this._onPageProxyMessageReceived.bind(this))];
57
+ this._browserSession.on('Playwright.pageProxyCreated', this._onPageProxyCreated.bind(this));
58
+ this._browserSession.on('Playwright.pageProxyDestroyed', this._onPageProxyDestroyed.bind(this));
59
+ this._browserSession.on('Playwright.provisionalLoadFailed', event => this._onProvisionalLoadFailed(event));
60
+ this._browserSession.on('Playwright.windowOpen', event => this._onWindowOpen(event));
61
+ this._browserSession.on('Playwright.downloadCreated', this._onDownloadCreated.bind(this));
62
+ this._browserSession.on('Playwright.downloadFilenameSuggested', this._onDownloadFilenameSuggested.bind(this));
63
+ this._browserSession.on('Playwright.downloadFinished', this._onDownloadFinished.bind(this));
64
+ this._browserSession.on('Playwright.screencastFinished', this._onScreencastFinished.bind(this));
65
+ this._browserSession.on(_wkConnection.kPageProxyMessageReceived, this._onPageProxyMessageReceived.bind(this));
60
66
  }
61
67
  _onDisconnect() {
62
68
  for (const wkPage of this._wkPages.values()) wkPage.didClose();
@@ -240,7 +246,7 @@ class WKBrowserContext extends _browserContext.BrowserContext {
240
246
  browserContextId: this._browserContextId
241
247
  });
242
248
  }
243
- async clearCookies() {
249
+ async doClearCookies() {
244
250
  await this._browser._browserSession.send('Playwright.deleteAllCookies', {
245
251
  browserContextId: this._browserContextId
246
252
  });
@@ -279,18 +285,12 @@ class WKBrowserContext extends _browserContext.BrowserContext {
279
285
  this._options.httpCredentials = httpCredentials;
280
286
  for (const page of this.pages()) await page._delegate.updateHttpCredentials();
281
287
  }
282
- async doAddInitScript(source) {
288
+ async doAddInitScript(initScript) {
283
289
  for (const page of this.pages()) await page._delegate._updateBootstrapScript();
284
290
  }
285
- async doRemoveInitScripts() {
291
+ async doRemoveNonInternalInitScripts() {
286
292
  for (const page of this.pages()) await page._delegate._updateBootstrapScript();
287
293
  }
288
- async doExposeBinding(binding) {
289
- for (const page of this.pages()) await page._delegate.exposeBinding(binding);
290
- }
291
- async doRemoveExposedBindings() {
292
- for (const page of this.pages()) await page._delegate.removeExposedBindings();
293
- }
294
294
  async doUpdateRequestInterception() {
295
295
  for (const page of this.pages()) await page._delegate.updateRequestInterception();
296
296
  }
@@ -32,7 +32,7 @@ const kBrowserCloseMessageId = exports.kBrowserCloseMessageId = -9999;
32
32
 
33
33
  // We emulate kPageProxyMessageReceived message to unify it with Browser.pageProxyCreated
34
34
  // and Browser.pageProxyDestroyed for easier management.
35
- const kPageProxyMessageReceived = exports.kPageProxyMessageReceived = 'kPageProxyMessageReceived';
35
+ const kPageProxyMessageReceived = exports.kPageProxyMessageReceived = Symbol('kPageProxyMessageReceived');
36
36
  class WKConnection {
37
37
  constructor(transport, onDisconnect, protocolLogger, browserLogsCollector) {
38
38
  this._transport = void 0;
@@ -77,11 +77,11 @@ class WKConnection {
77
77
  }
78
78
  this.browserSession.dispatchMessage(message);
79
79
  }
80
- _onClose() {
80
+ _onClose(reason) {
81
81
  this._closed = true;
82
82
  this._transport.onmessage = undefined;
83
83
  this._transport.onclose = undefined;
84
- this._browserDisconnectedLogs = _helper.helper.formatBrowserLogs(this._browserLogsCollector.recentLogs());
84
+ this._browserDisconnectedLogs = _helper.helper.formatBrowserLogs(this._browserLogsCollector.recentLogs(), reason);
85
85
  this.browserSession.dispose();
86
86
  this._onDisconnect();
87
87
  }
@@ -44,8 +44,8 @@ const errorReasons = {
44
44
  class WKInterceptableRequest {
45
45
  constructor(session, frame, event, redirectedFrom, documentId) {
46
46
  this._session = void 0;
47
- this.request = void 0;
48
47
  this._requestId = void 0;
48
+ this.request = void 0;
49
49
  this._timestamp = void 0;
50
50
  this._wallTime = void 0;
51
51
  this._session = session;
@@ -57,6 +57,10 @@ class WKInterceptableRequest {
57
57
  if (event.request.postData) postDataBuffer = Buffer.from(event.request.postData, 'base64');
58
58
  this.request = new network.Request(frame._page._browserContext, frame, null, (redirectedFrom === null || redirectedFrom === void 0 ? void 0 : redirectedFrom.request) || null, documentId, event.request.url, resourceType, event.request.method, postDataBuffer, (0, _utils.headersObjectToArray)(event.request.headers));
59
59
  }
60
+ adoptRequestFromNewProcess(newSession, requestId) {
61
+ this._session = newSession;
62
+ this._requestId = requestId;
63
+ }
60
64
  createResponse(responsePayload) {
61
65
  const getResponseBody = async () => {
62
66
  const response = await this._session.send('Network.getResponseBody', {
@@ -75,7 +79,7 @@ class WKInterceptableRequest {
75
79
  requestStart: timingPayload ? wkMillisToRoundishMillis(timingPayload.requestStart) : -1,
76
80
  responseStart: timingPayload ? wkMillisToRoundishMillis(timingPayload.responseStart) : -1
77
81
  };
78
- const setCookieSeparator = process.platform === 'darwin' ? ',' : '\n';
82
+ const setCookieSeparator = process.platform === 'darwin' ? ',' : 'playwright-set-cookie-separator';
79
83
  const response = new network.Response(this.request, responsePayload.status, responsePayload.statusText, (0, _utils.headersObjectToArray)(responsePayload.headers, ',', setCookieSeparator), timing, getResponseBody, responsePayload.source === 'service-worker');
80
84
 
81
85
  // No raw response headers in WebKit, use "provisional" ones.
@@ -125,14 +129,14 @@ class WKRouteImpl {
125
129
  await this._session.sendMayFail('Network.interceptRequestWithResponse', {
126
130
  requestId: this._requestId,
127
131
  status: response.status,
128
- statusText: network.STATUS_TEXTS[String(response.status)],
132
+ statusText: network.statusText(response.status),
129
133
  mimeType,
130
134
  headers,
131
135
  base64Encoded: response.isBase64,
132
136
  content: response.body
133
137
  });
134
138
  }
135
- async continue(request, overrides) {
139
+ async continue(overrides) {
136
140
  // In certain cases, protocol will return error if the request was already canceled
137
141
  // or the page was closed. We should tolerate these errors.
138
142
  await this._session.sendMayFail('Network.interceptWithRequest', {
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.WKPage = void 0;
7
7
  var _path = _interopRequireDefault(require("path"));
8
+ var _os = _interopRequireDefault(require("os"));
8
9
  var _utilsBundle = require("../../utilsBundle");
9
10
  var _stackTrace = require("../../utils/stackTrace");
10
11
  var _utils = require("../../utils");
@@ -159,7 +160,9 @@ class WKPage {
159
160
  resourceTreeHandler(frameTree);
160
161
  const promises = [
161
162
  // Resource tree should be received before first execution context.
162
- session.send('Runtime.enable'), session.send('Page.createUserWorld', {
163
+ session.send('Runtime.enable'), session.send('Runtime.addBinding', {
164
+ name: _page.PageBinding.kPlaywrightBinding
165
+ }), session.send('Page.createUserWorld', {
163
166
  name: UTILITY_WORLD_NAME
164
167
  }).catch(_ => {}),
165
168
  // Worlds are per-process
@@ -185,9 +188,6 @@ class WKPage {
185
188
  if (contextOptions.userAgent) promises.push(this.updateUserAgent());
186
189
  const emulatedMedia = this._page.emulatedMedia();
187
190
  if (emulatedMedia.media || emulatedMedia.colorScheme || emulatedMedia.reducedMotion || emulatedMedia.forcedColors) promises.push(WKPage._setEmulateMedia(session, emulatedMedia.media, emulatedMedia.colorScheme, emulatedMedia.reducedMotion, emulatedMedia.forcedColors));
188
- for (const binding of this._page.allBindings()) promises.push(session.send('Runtime.addBinding', {
189
- name: binding.name
190
- }));
191
191
  const bootstrapScript = this._calculateBootstrapScript();
192
192
  if (bootstrapScript.length) promises.push(session.send('Page.setBootstrapScript', {
193
193
  source: bootstrapScript
@@ -269,6 +269,7 @@ class WKPage {
269
269
  crashed
270
270
  } = event;
271
271
  if (this._provisionalPage && this._provisionalPage._session.sessionId === targetId) {
272
+ this._maybeCancelCoopNavigationRequest(this._provisionalPage);
272
273
  this._provisionalPage._session.dispose();
273
274
  this._provisionalPage.dispose();
274
275
  this._provisionalPage = null;
@@ -460,11 +461,11 @@ class WKPage {
460
461
  const frame = this._page._frameManager.frame(contextPayload.frameId);
461
462
  if (!frame) return;
462
463
  const delegate = new _wkExecutionContext.WKExecutionContext(this._session, contextPayload.id);
463
- let worldName = null;
464
- if (contextPayload.type === 'normal') worldName = 'main';else if (contextPayload.type === 'user' && contextPayload.name === UTILITY_WORLD_NAME) worldName = 'utility';
464
+ let worldName;
465
+ if (contextPayload.type === 'normal') worldName = 'main';else if (contextPayload.type === 'user' && contextPayload.name === UTILITY_WORLD_NAME) worldName = 'utility';else return;
465
466
  const context = new dom.FrameExecutionContext(delegate, frame, worldName);
466
467
  context[contextDelegateSymbol] = delegate;
467
- if (worldName) frame._contextCreated(worldName, context);
468
+ frame._contextCreated(worldName, context);
468
469
  this._contextIdToContext.set(contextPayload.id, context);
469
470
  }
470
471
  async _onBindingCalled(contextId, argument) {
@@ -685,7 +686,11 @@ class WKPage {
685
686
  })];
686
687
  if (options.isMobile) {
687
688
  const angle = viewportSize.width > viewportSize.height ? 90 : 0;
688
- promises.push(this._session.send('Page.setOrientationOverride', {
689
+ // Special handling for macOS 12.
690
+ const useLegacySetOrientationOverrideMethod = _os.default.platform() === 'darwin' && parseInt(_os.default.release().split('.')[0], 10) <= 21;
691
+ if (useLegacySetOrientationOverrideMethod) promises.push(this._session.send('Page.setOrientationOverride', {
692
+ angle
693
+ }));else promises.push(this._pageProxySession.send('Emulation.setOrientationOverride', {
689
694
  angle
690
695
  }));
691
696
  }
@@ -741,20 +746,10 @@ class WKPage {
741
746
  throw error;
742
747
  });
743
748
  }
744
- async exposeBinding(binding) {
745
- this._session.send('Runtime.addBinding', {
746
- name: binding.name
747
- });
748
- await this._updateBootstrapScript();
749
- await Promise.all(this._page.frames().map(frame => frame.evaluateExpression(binding.source).catch(e => {})));
750
- }
751
- async removeExposedBindings() {
752
- await this._updateBootstrapScript();
753
- }
754
- async addInitScript(script) {
749
+ async addInitScript(initScript) {
755
750
  await this._updateBootstrapScript();
756
751
  }
757
- async removeInitScripts() {
752
+ async removeNonInternalInitScripts() {
758
753
  await this._updateBootstrapScript();
759
754
  }
760
755
  _calculateBootstrapScript() {
@@ -766,9 +761,7 @@ class WKPage {
766
761
  }
767
762
  scripts.push('if (!window.safari) window.safari = { pushNotification: { toString() { return "[object SafariRemoteNotification]"; } } };');
768
763
  scripts.push('if (!window.GestureEvent) window.GestureEvent = function GestureEvent() {};');
769
- for (const binding of this._page.allBindings()) scripts.push(binding.source);
770
- scripts.push(...this._browserContext.initScripts);
771
- scripts.push(...this._page.initScripts);
764
+ scripts.push(...this._page.allInitScripts().map(script => script.source));
772
765
  return scripts.join(';\n');
773
766
  }
774
767
  async _updateBootstrapScript() {
@@ -944,7 +937,7 @@ class WKPage {
944
937
  files: protocolFiles
945
938
  });
946
939
  }
947
- async setInputFilePaths(progress, handle, paths) {
940
+ async setInputFilePaths(handle, paths) {
948
941
  const pageProxyId = this._pageProxySession.sessionId;
949
942
  const objectId = handle._objectId;
950
943
  await Promise.all([this._pageProxySession.connection.browserSession.send('Playwright.grantFileReadAccess', {
@@ -979,6 +972,31 @@ class WKPage {
979
972
  if (!result || result.object.subtype === 'null') throw new Error('Frame has been detached.');
980
973
  return context.createHandle(result.object);
981
974
  }
975
+ _maybeCancelCoopNavigationRequest(provisionalPage) {
976
+ const navigationRequest = provisionalPage.coopNavigationRequest();
977
+ for (const [requestId, request] of this._requestIdToRequest) {
978
+ if (request.request === navigationRequest) {
979
+ // Make sure the request completes if the provisional navigation is canceled.
980
+ this._onLoadingFailed(provisionalPage._session, {
981
+ requestId: requestId,
982
+ errorText: 'Provisiolal navigation canceled.',
983
+ timestamp: request._timestamp,
984
+ canceled: true
985
+ });
986
+ return;
987
+ }
988
+ }
989
+ }
990
+ _adoptRequestFromNewProcess(navigationRequest, newSession, newRequestId) {
991
+ for (const [requestId, request] of this._requestIdToRequest) {
992
+ if (request.request === navigationRequest) {
993
+ this._requestIdToRequest.delete(requestId);
994
+ request.adoptRequestFromNewProcess(newSession, newRequestId);
995
+ this._requestIdToRequest.set(newRequestId, request);
996
+ return;
997
+ }
998
+ }
999
+ }
982
1000
  _onRequestWillBeSent(session, event) {
983
1001
  if (event.request.url.startsWith('data:')) return;
984
1002
 
@@ -991,7 +1009,7 @@ class WKPage {
991
1009
  const request = this._requestIdToRequest.get(event.requestId);
992
1010
  // If we connect late to the target, we could have missed the requestWillBeSent event.
993
1011
  if (request) {
994
- this._handleRequestRedirect(request, event.redirectResponse, event.timestamp);
1012
+ this._handleRequestRedirect(request, event.requestId, event.redirectResponse, event.timestamp);
995
1013
  redirectedFrom = request;
996
1014
  }
997
1015
  }
@@ -1006,7 +1024,7 @@ class WKPage {
1006
1024
  const request = new _wkInterceptableRequest.WKInterceptableRequest(session, frame, event, redirectedFrom, documentId);
1007
1025
  let route;
1008
1026
  if (intercepted) {
1009
- route = new _wkInterceptableRequest.WKRouteImpl(session, request._requestId);
1027
+ route = new _wkInterceptableRequest.WKRouteImpl(session, event.requestId);
1010
1028
  // There is no point in waiting for the raw headers in Network.responseReceived when intercepting.
1011
1029
  // Use provisional headers as raw headers, so that client can call allHeaders() from the route handler.
1012
1030
  request.request.setRawRequestHeaders(null);
@@ -1014,14 +1032,14 @@ class WKPage {
1014
1032
  this._requestIdToRequest.set(event.requestId, request);
1015
1033
  this._page._frameManager.requestStarted(request.request, route);
1016
1034
  }
1017
- _handleRequestRedirect(request, responsePayload, timestamp) {
1035
+ _handleRequestRedirect(request, requestId, responsePayload, timestamp) {
1018
1036
  const response = request.createResponse(responsePayload);
1019
1037
  response._securityDetailsFinished();
1020
1038
  response._serverAddrFinished();
1021
1039
  response.setResponseHeadersSize(null);
1022
1040
  response.setEncodedBodySize(null);
1023
1041
  response._requestFinished(responsePayload.timing ? _helper.helper.secondsToRoundishMillis(timestamp - request._timestamp) : -1);
1024
- this._requestIdToRequest.delete(request._requestId);
1042
+ this._requestIdToRequest.delete(requestId);
1025
1043
  this._page._frameManager.requestReceivedResponse(response);
1026
1044
  this._page._frameManager.reportRequestFinished(request.request, response);
1027
1045
  }
@@ -1049,7 +1067,7 @@ class WKPage {
1049
1067
  const request = this._requestIdToRequest.get(event.requestId);
1050
1068
  // FileUpload sends a response without a matching request.
1051
1069
  if (!request) return;
1052
- this._requestIdToResponseReceivedPayloadEvent.set(request._requestId, event);
1070
+ this._requestIdToResponseReceivedPayloadEvent.set(event.requestId, event);
1053
1071
  const response = request.createResponse(event.response);
1054
1072
  this._page._frameManager.requestReceivedResponse(response);
1055
1073
  if (response.status() === 204) {
@@ -1071,7 +1089,7 @@ class WKPage {
1071
1089
  const response = request.request._existingResponse();
1072
1090
  if (response) {
1073
1091
  var _event$metrics, _event$metrics2, _responseReceivedPayl, _responseReceivedPayl2, _responseReceivedPayl3, _event$metrics3, _event$metrics$respon, _event$metrics4, _event$metrics$respon2, _event$metrics5;
1074
- const responseReceivedPayload = this._requestIdToResponseReceivedPayloadEvent.get(request._requestId);
1092
+ const responseReceivedPayload = this._requestIdToResponseReceivedPayloadEvent.get(event.requestId);
1075
1093
  response._serverAddrFinished(parseRemoteAddress(event === null || event === void 0 || (_event$metrics = event.metrics) === null || _event$metrics === void 0 ? void 0 : _event$metrics.remoteAddress));
1076
1094
  response._securityDetailsFinished({
1077
1095
  protocol: isLoadedSecurely(response.url(), response.timing()) ? (_event$metrics2 = event.metrics) === null || _event$metrics2 === void 0 || (_event$metrics2 = _event$metrics2.securityConnection) === null || _event$metrics2 === void 0 ? void 0 : _event$metrics2.protocol : undefined,
@@ -1087,8 +1105,8 @@ class WKPage {
1087
1105
  // Use provisional headers if we didn't have the response with raw headers.
1088
1106
  request.request.setRawRequestHeaders(null);
1089
1107
  }
1090
- this._requestIdToResponseReceivedPayloadEvent.delete(request._requestId);
1091
- this._requestIdToRequest.delete(request._requestId);
1108
+ this._requestIdToResponseReceivedPayloadEvent.delete(event.requestId);
1109
+ this._requestIdToRequest.delete(event.requestId);
1092
1110
  this._page._frameManager.reportRequestFinished(request.request, response);
1093
1111
  }
1094
1112
  _onLoadingFailed(session, event) {
@@ -1114,12 +1132,12 @@ class WKPage {
1114
1132
  // Use provisional headers if we didn't have the response with raw headers.
1115
1133
  request.request.setRawRequestHeaders(null);
1116
1134
  }
1117
- this._requestIdToRequest.delete(request._requestId);
1135
+ this._requestIdToRequest.delete(event.requestId);
1118
1136
  request.request._setFailureText(event.errorText);
1119
1137
  this._page._frameManager.requestFailed(request.request, event.errorText.includes('cancelled'));
1120
1138
  }
1121
1139
  async _grantPermissions(origin, permissions) {
1122
- const webPermissionToProtocol = new Map([['geolocation', 'geolocation'], ['clipboard-read', 'clipboard-read']]);
1140
+ const webPermissionToProtocol = new Map([['geolocation', 'geolocation'], ['notifications', 'notifications'], ['clipboard-read', 'clipboard-read']]);
1123
1141
  const filtered = permissions.map(permission => {
1124
1142
  const protocolPermission = webPermissionToProtocol.get(permission);
1125
1143
  if (!protocolPermission) throw new Error('Unknown permission: ' + permission);
@@ -24,13 +24,25 @@ var _utils = require("../../utils");
24
24
 
25
25
  class WKProvisionalPage {
26
26
  constructor(session, page) {
27
+ var _page$_page$mainFrame;
27
28
  this._session = void 0;
28
29
  this._wkPage = void 0;
30
+ this._coopNavigationRequest = void 0;
29
31
  this._sessionListeners = [];
30
32
  this._mainFrameId = null;
31
33
  this.initializationPromise = void 0;
32
34
  this._session = session;
33
35
  this._wkPage = page;
36
+ // Cross-Origin-Opener-Policy (COOP) request starts in one process and once response headers
37
+ // have been received, continues in another.
38
+ //
39
+ // Network.requestWillBeSent and requestIntercepted (if intercepting) from the original web process
40
+ // will always come before a provisional page is created based on the response COOP headers.
41
+ // Thereafter we'll receive targetCreated (provisional) and later on in some order loadingFailed from the
42
+ // original process and requestWillBeSent from the provisional one. We should ignore loadingFailed
43
+ // as the original request continues in the provisional process. But if the provisional load is later
44
+ // canceled we should dispatch loadingFailed to the client.
45
+ this._coopNavigationRequest = (_page$_page$mainFrame = page._page.mainFrame().pendingDocument()) === null || _page$_page$mainFrame === void 0 ? void 0 : _page$_page$mainFrame.request;
34
46
  const overrideFrameId = handler => {
35
47
  return payload => {
36
48
  // Pretend that the events happened in the same process.
@@ -39,11 +51,14 @@ class WKProvisionalPage {
39
51
  };
40
52
  };
41
53
  const wkPage = this._wkPage;
42
- this._sessionListeners = [_eventsHelper.eventsHelper.addEventListener(session, 'Network.requestWillBeSent', overrideFrameId(e => wkPage._onRequestWillBeSent(session, e))), _eventsHelper.eventsHelper.addEventListener(session, 'Network.requestIntercepted', overrideFrameId(e => wkPage._onRequestIntercepted(session, e))), _eventsHelper.eventsHelper.addEventListener(session, 'Network.responseReceived', overrideFrameId(e => wkPage._onResponseReceived(session, e))), _eventsHelper.eventsHelper.addEventListener(session, 'Network.loadingFinished', overrideFrameId(e => wkPage._onLoadingFinished(e))), _eventsHelper.eventsHelper.addEventListener(session, 'Network.loadingFailed', overrideFrameId(e => wkPage._onLoadingFailed(session, e)))];
54
+ this._sessionListeners = [_eventsHelper.eventsHelper.addEventListener(session, 'Network.requestWillBeSent', overrideFrameId(e => this._onRequestWillBeSent(e))), _eventsHelper.eventsHelper.addEventListener(session, 'Network.requestIntercepted', overrideFrameId(e => wkPage._onRequestIntercepted(session, e))), _eventsHelper.eventsHelper.addEventListener(session, 'Network.responseReceived', overrideFrameId(e => wkPage._onResponseReceived(session, e))), _eventsHelper.eventsHelper.addEventListener(session, 'Network.loadingFinished', overrideFrameId(e => this._onLoadingFinished(e))), _eventsHelper.eventsHelper.addEventListener(session, 'Network.loadingFailed', overrideFrameId(e => this._onLoadingFailed(e)))];
43
55
  this.initializationPromise = this._wkPage._initializeSession(session, true, ({
44
56
  frameTree
45
57
  }) => this._handleFrameTree(frameTree));
46
58
  }
59
+ coopNavigationRequest() {
60
+ return this._coopNavigationRequest;
61
+ }
47
62
  dispose() {
48
63
  _eventsHelper.eventsHelper.removeEventListeners(this._sessionListeners);
49
64
  }
@@ -51,6 +66,26 @@ class WKProvisionalPage {
51
66
  (0, _utils.assert)(this._mainFrameId);
52
67
  this._wkPage._onFrameAttached(this._mainFrameId, null);
53
68
  }
69
+ _onRequestWillBeSent(event) {
70
+ if (this._coopNavigationRequest && this._coopNavigationRequest.url() === event.request.url) {
71
+ // If it's a continuation of the main frame navigation request after COOP headers were received,
72
+ // take over original request, and replace its request id with the new one.
73
+ this._wkPage._adoptRequestFromNewProcess(this._coopNavigationRequest, this._session, event.requestId);
74
+ // Simply ignore this event as it has already been dispatched from the original process
75
+ // and there will ne no requestIntercepted event from the provisional process as it resumes
76
+ // existing network load (that has already received reponse headers).
77
+ return;
78
+ }
79
+ this._wkPage._onRequestWillBeSent(this._session, event);
80
+ }
81
+ _onLoadingFinished(event) {
82
+ this._coopNavigationRequest = undefined;
83
+ this._wkPage._onLoadingFinished(event);
84
+ }
85
+ _onLoadingFailed(event) {
86
+ this._coopNavigationRequest = undefined;
87
+ this._wkPage._onLoadingFailed(this._session, event);
88
+ }
54
89
  _handleFrameTree(frameTree) {
55
90
  (0, _utils.assert)(!frameTree.frame.parentId);
56
91
  this._mainFrameId = frameTree.frame.id;