@checkly/playwright-core 1.42.18 → 1.47.20-alpha

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 (238) 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-C-fQ5QZD.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-D-5S5PPN.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-CqYUz5ms.js +24 -0
  163. package/lib/vite/traceViewer/assets/codeMirrorModule-Dx6AXgMV.js +16838 -0
  164. package/lib/vite/traceViewer/assets/codeMirrorModule-T_sdMrbM.js +24 -0
  165. package/lib/vite/traceViewer/assets/codeMirrorModule-V7N6ppkd.js +15585 -0
  166. package/lib/vite/traceViewer/assets/testServerConnection-D-tXL3sj.js +224 -0
  167. package/lib/vite/traceViewer/assets/testServerConnection-DeE2kSzz.js +1 -0
  168. package/lib/vite/traceViewer/assets/workbench-Bjkiwcr1.js +19119 -0
  169. package/lib/vite/traceViewer/assets/workbench-C43LWZEX.js +72 -0
  170. package/lib/vite/traceViewer/assets/workbench-C5OQh9VX.js +19119 -0
  171. package/lib/vite/traceViewer/assets/workbench-DrQjKdyE.js +72 -0
  172. package/lib/vite/traceViewer/assets/workbench-caTaZnzx.js +72 -0
  173. package/lib/vite/traceViewer/assets/workbench-u2lRPMOT.js +72 -0
  174. package/lib/vite/traceViewer/assets/wsPort-EUvw-dwH.js +18540 -0
  175. package/lib/vite/traceViewer/assets/xtermModule-CZ7sDYXB.js +6529 -0
  176. package/lib/vite/traceViewer/assets/xtermModule-_6TC5FYT.js +6529 -0
  177. package/lib/vite/traceViewer/codeMirrorModule.Cy8X9Wtw.css +344 -0
  178. package/lib/vite/traceViewer/codeMirrorModule.svF_VrcJ.css +344 -0
  179. package/lib/vite/traceViewer/codicon.DCmgc-ay.ttf +0 -0
  180. package/lib/vite/traceViewer/embedded.BQq6Psnz.js +104 -0
  181. package/lib/vite/traceViewer/embedded.BVDVQOzc.js +2 -0
  182. package/lib/vite/traceViewer/embedded.Bn8Ptzv6.js +2 -0
  183. package/lib/vite/traceViewer/embedded.CvhnUgIi.js +2 -0
  184. package/lib/vite/traceViewer/embedded.D27cnKiB.js +104 -0
  185. package/lib/vite/traceViewer/embedded.DPqrDeET.js +2 -0
  186. package/lib/vite/traceViewer/embedded.DjZq4InJ.css +68 -0
  187. package/lib/vite/traceViewer/embedded.html +16 -0
  188. package/lib/vite/traceViewer/embedded.w7WN2u1R.css +1 -0
  189. package/lib/vite/traceViewer/index.5mge2rY_.css +124 -0
  190. package/lib/vite/traceViewer/index.6KJ-JQ0L.js +180 -0
  191. package/lib/vite/traceViewer/index.B8dgQwuN.js +2 -0
  192. package/lib/vite/traceViewer/index.BGj8jY3H.js +2 -0
  193. package/lib/vite/traceViewer/index.C0EgJ4oW.js +195 -0
  194. package/lib/vite/traceViewer/index.CUpI-BFe.js +195 -0
  195. package/lib/vite/traceViewer/{index.-g_5lMbJ.css → index.CrbWWHbf.css} +1 -1
  196. package/lib/vite/traceViewer/index.QanXxRUb.css +131 -0
  197. package/lib/vite/traceViewer/index._cX8k4co.js +2 -0
  198. package/lib/vite/traceViewer/index.html +5 -4
  199. package/lib/vite/traceViewer/index.pMAN88y-.js +2 -0
  200. package/lib/vite/traceViewer/snapshot.html +1 -1
  201. package/lib/vite/traceViewer/sw.bundle.js +3 -4
  202. package/lib/vite/traceViewer/uiMode.D-tg1Oci.js +1730 -0
  203. package/lib/vite/traceViewer/uiMode.D3cNFP6u.css +1 -0
  204. package/lib/vite/traceViewer/uiMode.DKjMBMlc.js +1730 -0
  205. package/lib/vite/traceViewer/uiMode.DVWUEIHq.css +1424 -0
  206. package/lib/vite/traceViewer/uiMode.DVrL7a1K.js +10 -0
  207. package/lib/vite/traceViewer/uiMode.Dg9oJCQU.js +10 -0
  208. package/lib/vite/traceViewer/uiMode.DwZAzstF.js +10 -0
  209. package/lib/vite/traceViewer/uiMode.html +5 -4
  210. package/lib/vite/traceViewer/uiMode.iq7CyYy7.js +1490 -0
  211. package/lib/vite/traceViewer/uiMode.jY2s-9ps.js +10 -0
  212. package/lib/vite/traceViewer/uiMode.xvJHbkzl.css +1324 -0
  213. package/lib/vite/traceViewer/workbench.B3X2QtYa.css +3702 -0
  214. package/lib/vite/traceViewer/workbench.DyTpxWVb.css +1 -0
  215. package/lib/vite/traceViewer/wsPort.p5jUwABW.css +3450 -0
  216. package/lib/vite/traceViewer/xtermModule.4oRVGWQ-.css +209 -0
  217. package/lib/vite/traceViewer/xtermModule.OKEVRlkP.css +209 -0
  218. package/package.json +2 -2
  219. package/types/protocol.d.ts +960 -78
  220. package/types/structs.d.ts +1 -1
  221. package/types/types.d.ts +3083 -2448
  222. package/lib/vite/recorder/assets/codeMirrorModule-W69B4LBB.js +0 -24
  223. package/lib/vite/recorder/assets/index-Ly3PcVUb.js +0 -47
  224. package/lib/vite/recorder/assets/index-ljsTwXtJ.css +0 -1
  225. package/lib/vite/traceViewer/assets/codeMirrorModule-0bpaqixv.js +0 -24
  226. package/lib/vite/traceViewer/assets/codeMirrorModule-wLpsbIhd.js +0 -24
  227. package/lib/vite/traceViewer/assets/wsPort-_JBDEilC.js +0 -69
  228. package/lib/vite/traceViewer/assets/wsPort-f2dAQL4I.js +0 -69
  229. package/lib/vite/traceViewer/index.-_8-eHEE.js +0 -2
  230. package/lib/vite/traceViewer/index.u51inEcm.js +0 -2
  231. package/lib/vite/traceViewer/uiMode.9CwNsWc6.js +0 -10
  232. package/lib/vite/traceViewer/uiMode.Fb0bNA4H.js +0 -10
  233. package/lib/vite/traceViewer/uiMode.pWy0Re7G.css +0 -1
  234. package/lib/vite/traceViewer/wsPort.zR1WIy9-.css +0 -1
  235. /package/lib/vite/recorder/assets/{codeMirrorModule-Hs9-1ZG4.css → codeMirrorModule-ez37Vkbh.css} +0 -0
  236. /package/lib/vite/traceViewer/assets/{xtermModule-Yt6xwiJ_.js → xtermModule-BeNbaIVa.js} +0 -0
  237. /package/lib/vite/traceViewer/{codeMirrorModule.Hs9-1ZG4.css → codeMirrorModule.ez37Vkbh.css} +0 -0
  238. /package/lib/vite/traceViewer/{xtermModule.0lwXJFHT.css → xtermModule.DSXBckUd.css} +0 -0
@@ -65,37 +65,36 @@ class DragManager {
65
65
  const client = this._crPage._mainFrameSession._client;
66
66
  let onDragIntercepted;
67
67
  const dragInterceptedPromise = new Promise(x => onDragIntercepted = x);
68
- await Promise.all(this._crPage._page.frames().map(async frame => {
69
- await frame.nonStallingEvaluateInExistingContext(function () {
70
- let didStartDrag = Promise.resolve(false);
71
- let dragEvent = null;
72
- const dragListener = event => dragEvent = event;
73
- const mouseListener = () => {
74
- didStartDrag = new Promise(callback => {
75
- window.addEventListener('dragstart', dragListener, {
76
- once: true,
77
- capture: true
78
- });
79
- setTimeout(() => callback(dragEvent ? !dragEvent.defaultPrevented : false), 0);
68
+ function setupDragListeners() {
69
+ let didStartDrag = Promise.resolve(false);
70
+ let dragEvent = null;
71
+ const dragListener = event => dragEvent = event;
72
+ const mouseListener = () => {
73
+ didStartDrag = new Promise(callback => {
74
+ window.addEventListener('dragstart', dragListener, {
75
+ once: true,
76
+ capture: true
80
77
  });
81
- };
82
- window.addEventListener('mousemove', mouseListener, {
83
- once: true,
78
+ setTimeout(() => callback(dragEvent ? !dragEvent.defaultPrevented : false), 0);
79
+ });
80
+ };
81
+ window.addEventListener('mousemove', mouseListener, {
82
+ once: true,
83
+ capture: true
84
+ });
85
+ window.__cleanupDrag = async () => {
86
+ const val = await didStartDrag;
87
+ window.removeEventListener('mousemove', mouseListener, {
84
88
  capture: true
85
89
  });
86
- window.__cleanupDrag = async () => {
87
- const val = await didStartDrag;
88
- window.removeEventListener('mousemove', mouseListener, {
89
- capture: true
90
- });
91
- window.removeEventListener('dragstart', dragListener, {
92
- capture: true
93
- });
94
- delete window.__cleanupDrag;
95
- return val;
96
- };
97
- }.toString(), true, 'utility').catch(() => {});
98
- }));
90
+ window.removeEventListener('dragstart', dragListener, {
91
+ capture: true
92
+ });
93
+ delete window.__cleanupDrag;
94
+ return val;
95
+ };
96
+ }
97
+ await this._crPage._page.safeNonStallingEvaluateInAllFrames(`(${setupDragListeners.toString()})()`, 'utility');
99
98
  client.on('Input.dragIntercepted', onDragIntercepted);
100
99
  try {
101
100
  await client.send('Input.setInterceptDrags', {
@@ -109,7 +108,7 @@ class DragManager {
109
108
  }
110
109
  await moveCallback();
111
110
  const expectingDrag = (await Promise.all(this._crPage._page.frames().map(async frame => {
112
- return frame.nonStallingEvaluateInExistingContext('window.__cleanupDrag && window.__cleanupDrag()', false, 'utility').catch(() => false);
111
+ return frame.nonStallingEvaluateInExistingContext('window.__cleanupDrag && window.__cleanupDrag()', 'utility').catch(() => false);
113
112
  }))).some(x => x);
114
113
  this._dragState = expectingDrag ? (await dragInterceptedPromise).data : null;
115
114
  client.off('Input.dragIntercepted', onDragIntercepted);
@@ -29,48 +29,67 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
29
29
  */
30
30
 
31
31
  class CRNetworkManager {
32
- constructor(session, page, serviceWorker, parentManager) {
33
- this._session = void 0;
32
+ constructor(page, serviceWorker) {
34
33
  this._page = void 0;
35
34
  this._serviceWorker = void 0;
36
- this._parentManager = void 0;
37
35
  this._requestIdToRequest = new Map();
38
36
  this._requestIdToRequestWillBeSentEvent = new Map();
39
37
  this._credentials = null;
40
38
  this._attemptedAuthentications = new Set();
41
39
  this._userRequestInterceptionEnabled = false;
42
40
  this._protocolRequestInterceptionEnabled = false;
41
+ this._offline = false;
42
+ this._extraHTTPHeaders = [];
43
43
  this._requestIdToRequestPausedEvent = new Map();
44
- this._eventListeners = void 0;
45
44
  this._responseExtraInfoTracker = new ResponseExtraInfoTracker();
46
- this._session = session;
45
+ this._sessions = new Map();
47
46
  this._page = page;
48
47
  this._serviceWorker = serviceWorker;
49
- this._parentManager = parentManager;
50
- this._eventListeners = this.instrumentNetworkEvents({
51
- session
52
- });
53
48
  }
54
- instrumentNetworkEvents(sessionInfo) {
55
- const listeners = [_eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Fetch.requestPaused', this._onRequestPaused.bind(this, sessionInfo)), _eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Fetch.authRequired', this._onAuthRequired.bind(this)), _eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Network.requestWillBeSent', this._onRequestWillBeSent.bind(this, sessionInfo)), _eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Network.requestWillBeSentExtraInfo', this._onRequestWillBeSentExtraInfo.bind(this)), _eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Network.requestServedFromCache', this._onRequestServedFromCache.bind(this)), _eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Network.responseReceived', this._onResponseReceived.bind(this, sessionInfo)), _eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Network.responseReceivedExtraInfo', this._onResponseReceivedExtraInfo.bind(this)), _eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Network.loadingFinished', this._onLoadingFinished.bind(this)), _eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Network.loadingFailed', this._onLoadingFailed.bind(this, sessionInfo))];
49
+ async addSession(session, workerFrame, isMain) {
50
+ const sessionInfo = {
51
+ session,
52
+ isMain,
53
+ workerFrame,
54
+ eventListeners: []
55
+ };
56
+ sessionInfo.eventListeners = [_eventsHelper.eventsHelper.addEventListener(session, 'Fetch.requestPaused', this._onRequestPaused.bind(this, sessionInfo)), _eventsHelper.eventsHelper.addEventListener(session, 'Fetch.authRequired', this._onAuthRequired.bind(this, sessionInfo)), _eventsHelper.eventsHelper.addEventListener(session, 'Network.requestWillBeSent', this._onRequestWillBeSent.bind(this, sessionInfo)), _eventsHelper.eventsHelper.addEventListener(session, 'Network.requestWillBeSentExtraInfo', this._onRequestWillBeSentExtraInfo.bind(this)), _eventsHelper.eventsHelper.addEventListener(session, 'Network.requestServedFromCache', this._onRequestServedFromCache.bind(this)), _eventsHelper.eventsHelper.addEventListener(session, 'Network.responseReceived', this._onResponseReceived.bind(this, sessionInfo)), _eventsHelper.eventsHelper.addEventListener(session, 'Network.responseReceivedExtraInfo', this._onResponseReceivedExtraInfo.bind(this)), _eventsHelper.eventsHelper.addEventListener(session, 'Network.loadingFinished', this._onLoadingFinished.bind(this, sessionInfo)), _eventsHelper.eventsHelper.addEventListener(session, 'Network.loadingFailed', this._onLoadingFailed.bind(this, sessionInfo))];
56
57
  if (this._page) {
57
- listeners.push(...[_eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Network.webSocketCreated', e => this._page._frameManager.onWebSocketCreated(e.requestId, e.url)), _eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Network.webSocketWillSendHandshakeRequest', e => this._page._frameManager.onWebSocketRequest(e.requestId)), _eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Network.webSocketHandshakeResponseReceived', e => this._page._frameManager.onWebSocketResponse(e.requestId, e.response.status, e.response.statusText)), _eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Network.webSocketFrameSent', e => e.response.payloadData && this._page._frameManager.onWebSocketFrameSent(e.requestId, e.response.opcode, e.response.payloadData)), _eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Network.webSocketFrameReceived', e => e.response.payloadData && this._page._frameManager.webSocketFrameReceived(e.requestId, e.response.opcode, e.response.payloadData)), _eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Network.webSocketClosed', e => this._page._frameManager.webSocketClosed(e.requestId)), _eventsHelper.eventsHelper.addEventListener(sessionInfo.session, 'Network.webSocketFrameError', e => this._page._frameManager.webSocketError(e.requestId, e.errorMessage))]);
58
+ sessionInfo.eventListeners.push(...[_eventsHelper.eventsHelper.addEventListener(session, 'Network.webSocketCreated', e => this._page._frameManager.onWebSocketCreated(e.requestId, e.url)), _eventsHelper.eventsHelper.addEventListener(session, 'Network.webSocketWillSendHandshakeRequest', e => this._page._frameManager.onWebSocketRequest(e.requestId)), _eventsHelper.eventsHelper.addEventListener(session, 'Network.webSocketHandshakeResponseReceived', e => this._page._frameManager.onWebSocketResponse(e.requestId, e.response.status, e.response.statusText)), _eventsHelper.eventsHelper.addEventListener(session, 'Network.webSocketFrameSent', e => e.response.payloadData && this._page._frameManager.onWebSocketFrameSent(e.requestId, e.response.opcode, e.response.payloadData)), _eventsHelper.eventsHelper.addEventListener(session, 'Network.webSocketFrameReceived', e => e.response.payloadData && this._page._frameManager.webSocketFrameReceived(e.requestId, e.response.opcode, e.response.payloadData)), _eventsHelper.eventsHelper.addEventListener(session, 'Network.webSocketClosed', e => this._page._frameManager.webSocketClosed(e.requestId)), _eventsHelper.eventsHelper.addEventListener(session, 'Network.webSocketFrameError', e => this._page._frameManager.webSocketError(e.requestId, e.errorMessage))]);
58
59
  }
59
- return listeners;
60
- }
61
- async initialize() {
62
- await this._session.send('Network.enable');
63
- }
64
- dispose() {
65
- _eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);
60
+ this._sessions.set(session, sessionInfo);
61
+ await Promise.all([session.send('Network.enable'), this._updateProtocolRequestInterceptionForSession(sessionInfo, true /* initial */), this._setOfflineForSession(sessionInfo, true /* initial */), this._setExtraHTTPHeadersForSession(sessionInfo, true /* initial */)]);
62
+ }
63
+ removeSession(session) {
64
+ const info = this._sessions.get(session);
65
+ if (info) _eventsHelper.eventsHelper.removeEventListeners(info.eventListeners);
66
+ this._sessions.delete(session);
67
+ }
68
+ async _forEachSession(cb) {
69
+ await Promise.all([...this._sessions.values()].map(info => {
70
+ if (info.isMain) return cb(info);
71
+ return cb(info).catch(e => {
72
+ // Broadcasting a message to the closed target should be a noop.
73
+ if ((0, _protocolError.isSessionClosedError)(e)) return;
74
+ throw e;
75
+ });
76
+ }));
66
77
  }
67
78
  async authenticate(credentials) {
68
79
  this._credentials = credentials;
69
80
  await this._updateProtocolRequestInterception();
70
81
  }
71
82
  async setOffline(offline) {
72
- await this._session.send('Network.emulateNetworkConditions', {
73
- offline,
83
+ if (offline === this._offline) return;
84
+ this._offline = offline;
85
+ await this._forEachSession(info => this._setOfflineForSession(info));
86
+ }
87
+ async _setOfflineForSession(info, initial) {
88
+ if (initial && !this._offline) return;
89
+ // Workers are affected by the owner frame's Network.emulateNetworkConditions.
90
+ if (info.workerFrame) return;
91
+ await info.session.send('Network.emulateNetworkConditions', {
92
+ offline: this._offline,
74
93
  // values of 0 remove any active throttling. crbug.com/456324#c9
75
94
  latency: 0,
76
95
  downloadThroughput: -1,
@@ -85,31 +104,48 @@ class CRNetworkManager {
85
104
  const enabled = this._userRequestInterceptionEnabled || !!this._credentials;
86
105
  if (enabled === this._protocolRequestInterceptionEnabled) return;
87
106
  this._protocolRequestInterceptionEnabled = enabled;
88
- if (enabled) {
89
- await Promise.all([this._session.send('Network.setCacheDisabled', {
90
- cacheDisabled: true
91
- }), this._session.send('Fetch.enable', {
107
+ await this._forEachSession(info => this._updateProtocolRequestInterceptionForSession(info));
108
+ }
109
+ async _updateProtocolRequestInterceptionForSession(info, initial) {
110
+ const enabled = this._protocolRequestInterceptionEnabled;
111
+ if (initial && !enabled) return;
112
+ const cachePromise = info.session.send('Network.setCacheDisabled', {
113
+ cacheDisabled: enabled
114
+ });
115
+ let fetchPromise = Promise.resolve(undefined);
116
+ if (!info.workerFrame) {
117
+ if (enabled) fetchPromise = info.session.send('Fetch.enable', {
92
118
  handleAuthRequests: true,
93
119
  patterns: [{
94
120
  urlPattern: '*',
95
121
  requestStage: 'Request'
96
122
  }]
97
- })]);
98
- } else {
99
- await Promise.all([this._session.send('Network.setCacheDisabled', {
100
- cacheDisabled: false
101
- }), this._session.send('Fetch.disable')]);
123
+ });else fetchPromise = info.session.send('Fetch.disable');
102
124
  }
125
+ await Promise.all([cachePromise, fetchPromise]);
103
126
  }
104
- async clearCache() {
105
- // Sending 'Network.setCacheDisabled' with 'cacheDisabled = true' will clear the MemoryCache.
106
- await this._session.send('Network.setCacheDisabled', {
107
- cacheDisabled: true
127
+ async setExtraHTTPHeaders(extraHTTPHeaders) {
128
+ if (!this._extraHTTPHeaders.length && !extraHTTPHeaders.length) return;
129
+ this._extraHTTPHeaders = extraHTTPHeaders;
130
+ await this._forEachSession(info => this._setExtraHTTPHeadersForSession(info));
131
+ }
132
+ async _setExtraHTTPHeadersForSession(info, initial) {
133
+ if (initial && !this._extraHTTPHeaders.length) return;
134
+ await info.session.send('Network.setExtraHTTPHeaders', {
135
+ headers: (0, _utils.headersArrayToObject)(this._extraHTTPHeaders, false /* lowerCase */)
108
136
  });
109
- if (!this._protocolRequestInterceptionEnabled) await this._session.send('Network.setCacheDisabled', {
110
- cacheDisabled: false
137
+ }
138
+ async clearCache() {
139
+ await this._forEachSession(async info => {
140
+ // Sending 'Network.setCacheDisabled' with 'cacheDisabled = true' will clear the MemoryCache.
141
+ await info.session.send('Network.setCacheDisabled', {
142
+ cacheDisabled: true
143
+ });
144
+ if (!this._protocolRequestInterceptionEnabled) await info.session.send('Network.setCacheDisabled', {
145
+ cacheDisabled: false
146
+ });
147
+ if (!info.workerFrame) await info.session.send('Network.clearBrowserCache');
111
148
  });
112
- await this._session.send('Network.clearBrowserCache');
113
149
  }
114
150
  _onRequestWillBeSent(sessionInfo, event) {
115
151
  // Request interception doesn't happen for data URLs with Network Service.
@@ -117,13 +153,16 @@ class CRNetworkManager {
117
153
  const requestId = event.requestId;
118
154
  const requestPausedEvent = this._requestIdToRequestPausedEvent.get(requestId);
119
155
  if (requestPausedEvent) {
120
- this._onRequest(sessionInfo, event, requestPausedEvent);
156
+ this._onRequest(sessionInfo, event, requestPausedEvent.sessionInfo, requestPausedEvent.event);
121
157
  this._requestIdToRequestPausedEvent.delete(requestId);
122
158
  } else {
123
- this._requestIdToRequestWillBeSentEvent.set(event.requestId, event);
159
+ this._requestIdToRequestWillBeSentEvent.set(event.requestId, {
160
+ sessionInfo,
161
+ event
162
+ });
124
163
  }
125
164
  } else {
126
- this._onRequest(sessionInfo, event, null);
165
+ this._onRequest(sessionInfo, event, undefined, undefined);
127
166
  }
128
167
  }
129
168
  _onRequestServedFromCache(event) {
@@ -132,7 +171,7 @@ class CRNetworkManager {
132
171
  _onRequestWillBeSentExtraInfo(event) {
133
172
  this._responseExtraInfoTracker.requestWillBeSentExtraInfo(event);
134
173
  }
135
- _onAuthRequired(event) {
174
+ _onAuthRequired(sessionInfo, event) {
136
175
  let response = 'Default';
137
176
  const shouldProvideCredentials = this._shouldProvideCredentials(event.request.url);
138
177
  if (this._attemptedAuthentications.has(event.requestId)) {
@@ -148,7 +187,7 @@ class CRNetworkManager {
148
187
  username: undefined,
149
188
  password: undefined
150
189
  };
151
- this._session._sendMayFail('Fetch.continueWithAuth', {
190
+ sessionInfo.session._sendMayFail('Fetch.continueWithAuth', {
152
191
  requestId: event.requestId,
153
192
  authChallengeResponse: {
154
193
  response,
@@ -165,7 +204,7 @@ class CRNetworkManager {
165
204
  if (!event.networkId) {
166
205
  // Fetch without networkId means that request was not recognized by inspector, and
167
206
  // it will never receive Network.requestWillBeSent. Continue the request to not affect it.
168
- this._session._sendMayFail('Fetch.continueRequest', {
207
+ sessionInfo.session._sendMayFail('Fetch.continueRequest', {
169
208
  requestId: event.requestId
170
209
  });
171
210
  return;
@@ -174,7 +213,7 @@ class CRNetworkManager {
174
213
  const requestId = event.networkId;
175
214
  const requestWillBeSentEvent = this._requestIdToRequestWillBeSentEvent.get(requestId);
176
215
  if (requestWillBeSentEvent) {
177
- this._onRequest(sessionInfo, requestWillBeSentEvent, event);
216
+ this._onRequest(requestWillBeSentEvent.sessionInfo, requestWillBeSentEvent.event, sessionInfo, event);
178
217
  this._requestIdToRequestWillBeSentEvent.delete(requestId);
179
218
  } else {
180
219
  var _existingRequest$_rou;
@@ -190,16 +229,19 @@ class CRNetworkManager {
190
229
  //
191
230
  // Note: make sure not to prematurely continue the redirect, which shares the
192
231
  // `networkId` between the original request and the redirect.
193
- this._session._sendMayFail('Fetch.continueRequest', {
232
+ sessionInfo.session._sendMayFail('Fetch.continueRequest', {
194
233
  ...alreadyContinuedParams,
195
234
  requestId: event.requestId
196
235
  });
197
236
  return;
198
237
  }
199
- this._requestIdToRequestPausedEvent.set(requestId, event);
238
+ this._requestIdToRequestPausedEvent.set(requestId, {
239
+ sessionInfo,
240
+ event
241
+ });
200
242
  }
201
243
  }
202
- _onRequest(sessionInfo, requestWillBeSentEvent, requestPausedEvent) {
244
+ _onRequest(requestWillBeSentSessionInfo, requestWillBeSentEvent, requestPausedSessionInfo, requestPausedEvent) {
203
245
  var _this$_page, _this$_page2, _this$_page3;
204
246
  if (requestWillBeSentEvent.request.url.startsWith('data:')) return;
205
247
  let redirectedFrom = null;
@@ -211,7 +253,7 @@ class CRNetworkManager {
211
253
  redirectedFrom = request;
212
254
  }
213
255
  }
214
- let frame = requestWillBeSentEvent.frameId ? (_this$_page = this._page) === null || _this$_page === void 0 ? void 0 : _this$_page._frameManager.frame(requestWillBeSentEvent.frameId) : sessionInfo.workerFrame;
256
+ let frame = requestWillBeSentEvent.frameId ? (_this$_page = this._page) === null || _this$_page === void 0 ? void 0 : _this$_page._frameManager.frame(requestWillBeSentEvent.frameId) : requestWillBeSentSessionInfo.workerFrame;
215
257
  // Requests from workers lack frameId, because we receive Network.requestWillBeSent
216
258
  // on the worker target. However, we receive Fetch.requestPaused on the page target,
217
259
  // and lack workerFrame there. Luckily, Fetch.requestPaused provides a frameId.
@@ -246,10 +288,10 @@ class CRNetworkManager {
246
288
  name: 'Access-Control-Allow-Headers',
247
289
  value: requestHeaders['Access-Control-Request-Headers']
248
290
  });
249
- this._session._sendMayFail('Fetch.fulfillRequest', {
291
+ requestPausedSessionInfo.session._sendMayFail('Fetch.fulfillRequest', {
250
292
  requestId: requestPausedEvent.requestId,
251
293
  responseCode: 204,
252
- responsePhrase: network.STATUS_TEXTS['204'],
294
+ responsePhrase: network.statusText(204),
253
295
  responseHeaders,
254
296
  body: ''
255
297
  });
@@ -258,30 +300,31 @@ class CRNetworkManager {
258
300
 
259
301
  // Non-service-worker requests MUST have a frame—if they don't, we pretend there was no request
260
302
  if (!frame && !this._serviceWorker) {
261
- if (requestPausedEvent) this._session._sendMayFail('Fetch.continueRequest', {
303
+ if (requestPausedEvent) requestPausedSessionInfo.session._sendMayFail('Fetch.continueRequest', {
262
304
  requestId: requestPausedEvent.requestId
263
305
  });
264
306
  return;
265
307
  }
266
308
  let route = null;
309
+ let headersOverride;
267
310
  if (requestPausedEvent) {
268
311
  // We do not support intercepting redirects.
269
312
  if (redirectedFrom || !this._userRequestInterceptionEnabled && this._protocolRequestInterceptionEnabled) {
270
313
  var _redirectedFrom;
271
314
  // Chromium does not preserve header overrides between redirects, so we have to do it ourselves.
272
- const headers = (_redirectedFrom = redirectedFrom) === null || _redirectedFrom === void 0 || (_redirectedFrom = _redirectedFrom._originalRequestRoute) === null || _redirectedFrom === void 0 || (_redirectedFrom = _redirectedFrom._alreadyContinuedParams) === null || _redirectedFrom === void 0 ? void 0 : _redirectedFrom.headers;
273
- this._session._sendMayFail('Fetch.continueRequest', {
315
+ headersOverride = (_redirectedFrom = redirectedFrom) === null || _redirectedFrom === void 0 || (_redirectedFrom = _redirectedFrom._originalRequestRoute) === null || _redirectedFrom === void 0 || (_redirectedFrom = _redirectedFrom._alreadyContinuedParams) === null || _redirectedFrom === void 0 ? void 0 : _redirectedFrom.headers;
316
+ requestPausedSessionInfo.session._sendMayFail('Fetch.continueRequest', {
274
317
  requestId: requestPausedEvent.requestId,
275
- headers
318
+ headers: headersOverride
276
319
  });
277
320
  } else {
278
- route = new RouteImpl(this._session, requestPausedEvent.requestId);
321
+ route = new RouteImpl(requestPausedSessionInfo.session, requestPausedEvent.requestId);
279
322
  }
280
323
  }
281
324
  const isNavigationRequest = requestWillBeSentEvent.requestId === requestWillBeSentEvent.loaderId && requestWillBeSentEvent.type === 'Document';
282
325
  const documentId = isNavigationRequest ? requestWillBeSentEvent.loaderId : undefined;
283
326
  const request = new InterceptableRequest({
284
- session: sessionInfo.session,
327
+ session: requestWillBeSentSessionInfo.session,
285
328
  context: (this._page || this._serviceWorker)._browserContext,
286
329
  frame: frame || null,
287
330
  serviceWorker: this._serviceWorker || null,
@@ -289,11 +332,12 @@ class CRNetworkManager {
289
332
  route,
290
333
  requestWillBeSentEvent,
291
334
  requestPausedEvent,
292
- redirectedFrom
335
+ redirectedFrom,
336
+ headersOverride: headersOverride || null
293
337
  });
294
338
  this._requestIdToRequest.set(requestWillBeSentEvent.requestId, request);
295
- if (requestPausedEvent) {
296
- // We will not receive extra info when intercepting the request.
339
+ if (route) {
340
+ // We may not receive extra info when intercepting the request.
297
341
  // Use the headers from the Fetch.requestPausedPayload and release the allHeaders()
298
342
  // right away, so that client can call it from the route handler.
299
343
  request.request.setRawRequestHeaders((0, _utils.headersObjectToArray)(requestPausedEvent.request.headers, '\n'));
@@ -303,6 +347,7 @@ class CRNetworkManager {
303
347
  _createResponse(request, responsePayload, hasExtraInfo) {
304
348
  var _responsePayload$secu, _responsePayload$secu2, _responsePayload$secu3, _responsePayload$secu4, _responsePayload$secu5;
305
349
  const getResponseBody = async () => {
350
+ var _request$_route;
306
351
  const contentLengthHeader = Object.entries(responsePayload.headers).find(header => header[0].toLowerCase() === 'content-length');
307
352
  const expectedLength = contentLengthHeader ? +contentLengthHeader[1] : undefined;
308
353
  const session = request.session;
@@ -311,6 +356,9 @@ class CRNetworkManager {
311
356
  });
312
357
  if (response.body || !expectedLength) return Buffer.from(response.body, response.base64Encoded ? 'base64' : 'utf8');
313
358
 
359
+ // Make sure no network requests sent while reading the body for fulfilled requests.
360
+ if ((_request$_route = request._route) !== null && _request$_route !== void 0 && _request$_route._fulfilled) return Buffer.from('');
361
+
314
362
  // For <link prefetch we are going to receive empty body with non-empty content-length expectation. Reach out for the actual content.
315
363
  const resource = await session.send('Network.loadNetworkResource', {
316
364
  url: request.request.url(),
@@ -406,7 +454,7 @@ class CRNetworkManager {
406
454
  const requestWillBeSentEvent = this._requestIdToRequestWillBeSentEvent.get(event.requestId);
407
455
  if (requestWillBeSentEvent) {
408
456
  this._requestIdToRequestWillBeSentEvent.delete(event.requestId);
409
- this._onRequest(sessionInfo, requestWillBeSentEvent, null /* requestPausedPayload */);
457
+ this._onRequest(sessionInfo, requestWillBeSentEvent.event, undefined, undefined);
410
458
  request = this._requestIdToRequest.get(event.requestId);
411
459
  }
412
460
  }
@@ -415,14 +463,14 @@ class CRNetworkManager {
415
463
  const response = this._createResponse(request, event.response, event.hasExtraInfo);
416
464
  (((_this$_page6 = this._page) === null || _this$_page6 === void 0 ? void 0 : _this$_page6._frameManager) || this._serviceWorker).requestReceivedResponse(response);
417
465
  }
418
- _onLoadingFinished(event) {
466
+ _onLoadingFinished(sessionInfo, event) {
419
467
  var _this$_page7;
420
468
  this._responseExtraInfoTracker.loadingFinished(event);
421
- let request = this._requestIdToRequest.get(event.requestId);
422
- if (!request) request = this._maybeAdoptMainRequest(event.requestId);
469
+ const request = this._requestIdToRequest.get(event.requestId);
423
470
  // For certain requestIds we never receive requestWillBeSent event.
424
471
  // @see https://crbug.com/750469
425
472
  if (!request) return;
473
+ this._maybeUpdateOOPIFMainRequest(sessionInfo, request);
426
474
 
427
475
  // Under certain conditions we never get the Network.responseReceived
428
476
  // event from protocol. @see https://crbug.com/883475
@@ -439,7 +487,6 @@ class CRNetworkManager {
439
487
  var _this$_page8;
440
488
  this._responseExtraInfoTracker.loadingFailed(event);
441
489
  let request = this._requestIdToRequest.get(event.requestId);
442
- if (!request) request = this._maybeAdoptMainRequest(event.requestId);
443
490
  if (!request) {
444
491
  const requestWillBeSentEvent = this._requestIdToRequestWillBeSentEvent.get(event.requestId);
445
492
  if (requestWillBeSentEvent) {
@@ -447,7 +494,7 @@ class CRNetworkManager {
447
494
  // We stop waiting for Fetch.requestPaused (it might never come), and dispatch request event
448
495
  // right away, followed by requestfailed event.
449
496
  this._requestIdToRequestWillBeSentEvent.delete(event.requestId);
450
- this._onRequest(sessionInfo, requestWillBeSentEvent, null);
497
+ this._onRequest(sessionInfo, requestWillBeSentEvent.event, undefined, undefined);
451
498
  request = this._requestIdToRequest.get(event.requestId);
452
499
  }
453
500
  }
@@ -455,30 +502,25 @@ class CRNetworkManager {
455
502
  // For certain requestIds we never receive requestWillBeSent event.
456
503
  // @see https://crbug.com/750469
457
504
  if (!request) return;
505
+ this._maybeUpdateOOPIFMainRequest(sessionInfo, request);
458
506
  const response = request.request._existingResponse();
459
507
  if (response) {
460
508
  response.setTransferSize(null);
461
509
  response.setEncodedBodySize(null);
462
510
  response._requestFinished(_helper.helper.secondsToRoundishMillis(event.timestamp - request._timestamp));
511
+ } else {
512
+ // Loading failed before response has arrived - there will be no extra info events.
513
+ request.request.setRawRequestHeaders(null);
463
514
  }
464
515
  this._deleteRequest(request);
465
- request.request._setFailureText(event.errorText);
516
+ request.request._setFailureText(event.errorText || event.blockedReason || '');
466
517
  (((_this$_page8 = this._page) === null || _this$_page8 === void 0 ? void 0 : _this$_page8._frameManager) || this._serviceWorker).requestFailed(request.request, !!event.canceled);
467
518
  }
468
- _maybeAdoptMainRequest(requestId) {
519
+ _maybeUpdateOOPIFMainRequest(sessionInfo, request) {
469
520
  // OOPIF has a main request that starts in the parent session but finishes in the child session.
470
- if (!this._parentManager) return;
471
- const request = this._parentManager._requestIdToRequest.get(requestId);
472
- // Main requests have matching loaderId and requestId.
473
- if (!request || request._documentId !== requestId) return;
474
- this._requestIdToRequest.set(requestId, request);
475
- request.session = this._session;
476
- this._parentManager._requestIdToRequest.delete(requestId);
477
- if (request._interceptionId && this._parentManager._attemptedAuthentications.has(request._interceptionId)) {
478
- this._parentManager._attemptedAuthentications.delete(request._interceptionId);
479
- this._attemptedAuthentications.add(request._interceptionId);
480
- }
481
- return request;
521
+ // We check for the main request by matching loaderId and requestId, and if it now belongs to
522
+ // a child session, migrate it there.
523
+ if (request.session !== sessionInfo.session && !sessionInfo.isMain && request._documentId === request._requestId) request.session = sessionInfo.session;
482
524
  }
483
525
  }
484
526
  exports.CRNetworkManager = CRNetworkManager;
@@ -504,7 +546,8 @@ class InterceptableRequest {
504
546
  requestWillBeSentEvent,
505
547
  requestPausedEvent,
506
548
  redirectedFrom,
507
- serviceWorker
549
+ serviceWorker,
550
+ headersOverride
508
551
  } = options;
509
552
  this.session = session;
510
553
  this._timestamp = requestWillBeSentEvent.timestamp;
@@ -522,8 +565,9 @@ class InterceptableRequest {
522
565
  } = requestPausedEvent ? requestPausedEvent.request : requestWillBeSentEvent.request;
523
566
  const type = (requestWillBeSentEvent.type || '').toLowerCase();
524
567
  let postDataBuffer = null;
525
- if (postDataEntries && postDataEntries.length && postDataEntries[0].bytes) postDataBuffer = Buffer.from(postDataEntries[0].bytes, 'base64');
526
- this.request = new network.Request(context, frame, serviceWorker, (redirectedFrom === null || redirectedFrom === void 0 ? void 0 : redirectedFrom.request) || null, documentId, url, type, method, postDataBuffer, (0, _utils.headersObjectToArray)(headers));
568
+ const entries = postDataEntries === null || postDataEntries === void 0 ? void 0 : postDataEntries.filter(entry => entry.bytes);
569
+ if (entries && entries.length) postDataBuffer = Buffer.concat(entries.map(entry => Buffer.from(entry.bytes, 'base64')));
570
+ this.request = new network.Request(context, frame, serviceWorker, (redirectedFrom === null || redirectedFrom === void 0 ? void 0 : redirectedFrom.request) || null, documentId, url, type, method, postDataBuffer, headersOverride || (0, _utils.headersObjectToArray)(headers));
527
571
  }
528
572
  }
529
573
  class RouteImpl {
@@ -531,10 +575,11 @@ class RouteImpl {
531
575
  this._session = void 0;
532
576
  this._interceptionId = void 0;
533
577
  this._alreadyContinuedParams = void 0;
578
+ this._fulfilled = false;
534
579
  this._session = session;
535
580
  this._interceptionId = interceptionId;
536
581
  }
537
- async continue(request, overrides) {
582
+ async continue(overrides) {
538
583
  this._alreadyContinuedParams = {
539
584
  requestId: this._interceptionId,
540
585
  url: overrides.url,
@@ -547,13 +592,14 @@ class RouteImpl {
547
592
  });
548
593
  }
549
594
  async fulfill(response) {
595
+ this._fulfilled = true;
550
596
  const body = response.isBase64 ? response.body : Buffer.from(response.body).toString('base64');
551
597
  const responseHeaders = splitSetCookieHeader(response.headers);
552
598
  await catchDisallowedErrors(async () => {
553
599
  await this._session.send('Fetch.fulfillRequest', {
554
600
  requestId: this._interceptionId,
555
601
  responseCode: response.status,
556
- responsePhrase: network.STATUS_TEXTS[String(response.status)],
602
+ responsePhrase: network.statusText(response.status),
557
603
  responseHeaders,
558
604
  body
559
605
  });