@checkly/playwright-core 1.42.17 → 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 (234) 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-I9ks4y7D.js +0 -24
  223. package/lib/vite/recorder/assets/index-ljsTwXtJ.css +0 -1
  224. package/lib/vite/recorder/assets/index-yg8ypzl6.js +0 -47
  225. package/lib/vite/traceViewer/assets/codeMirrorModule-0bpaqixv.js +0 -24
  226. package/lib/vite/traceViewer/assets/wsPort-_JBDEilC.js +0 -69
  227. package/lib/vite/traceViewer/index.u51inEcm.js +0 -2
  228. package/lib/vite/traceViewer/uiMode.Fb0bNA4H.js +0 -10
  229. package/lib/vite/traceViewer/uiMode.pWy0Re7G.css +0 -1
  230. package/lib/vite/traceViewer/wsPort.zR1WIy9-.css +0 -1
  231. /package/lib/vite/recorder/assets/{codeMirrorModule-Hs9-1ZG4.css → codeMirrorModule-ez37Vkbh.css} +0 -0
  232. /package/lib/vite/traceViewer/assets/{xtermModule-Yt6xwiJ_.js → xtermModule-BeNbaIVa.js} +0 -0
  233. /package/lib/vite/traceViewer/{codeMirrorModule.Hs9-1ZG4.css → codeMirrorModule.ez37Vkbh.css} +0 -0
  234. /package/lib/vite/traceViewer/{xtermModule.0lwXJFHT.css → xtermModule.DSXBckUd.css} +0 -0
@@ -142,28 +142,36 @@ class BrowserType extends _channelOwner.ChannelOwner {
142
142
  connection.on('close', closePipe);
143
143
  let browser;
144
144
  let closeError;
145
- const onPipeClosed = () => {
146
- var _browser2;
145
+ const onPipeClosed = reason => {
147
146
  // Emulate all pages, contexts and the browser closing upon disconnect.
148
147
  for (const context of ((_browser = browser) === null || _browser === void 0 ? void 0 : _browser.contexts()) || []) {
149
148
  var _browser;
150
149
  for (const page of context.pages()) page._onClose();
151
150
  context._onClose();
152
151
  }
153
- (_browser2 = browser) === null || _browser2 === void 0 || _browser2._didClose();
154
- connection.close(closeError);
152
+ connection.close(reason || closeError);
153
+ // Give a chance to any API call promises to reject upon page/context closure.
154
+ // This happens naturally when we receive page.onClose and browser.onClose from the server
155
+ // in separate tasks. However, upon pipe closure we used to dispatch them all synchronously
156
+ // here and promises did not have a chance to reject.
157
+ // The order of rejects vs closure is a part of the API contract and our test runner
158
+ // relies on it to attribute rejections to the right test.
159
+ setTimeout(() => {
160
+ var _browser2;
161
+ return (_browser2 = browser) === null || _browser2 === void 0 ? void 0 : _browser2._didClose();
162
+ }, 0);
155
163
  };
156
- pipe.on('closed', onPipeClosed);
157
- connection.onmessage = message => pipe.send({
164
+ pipe.on('closed', params => onPipeClosed(params.reason));
165
+ connection.onmessage = message => this._wrapApiCall(() => pipe.send({
158
166
  message
159
- }).catch(onPipeClosed);
167
+ }).catch(() => onPipeClosed()), /* isInternal */true);
160
168
  pipe.on('message', ({
161
169
  message
162
170
  }) => {
163
171
  try {
164
172
  connection.dispatch(message);
165
173
  } catch (e) {
166
- closeError = e;
174
+ closeError = String(e);
167
175
  closePipe();
168
176
  }
169
177
  });
@@ -180,7 +188,7 @@ class BrowserType extends _channelOwner.ChannelOwner {
180
188
  this._didLaunchBrowser(browser, {}, logger);
181
189
  browser._shouldCloseConnectionOnClose = true;
182
190
  browser._connectHeaders = connectHeaders;
183
- browser.on(_events.Events.Browser.Disconnected, closePipe);
191
+ browser.on(_events.Events.Browser.Disconnected, () => this._wrapApiCall(() => closePipe(), /* isInternal */true));
184
192
  return browser;
185
193
  }, deadline);
186
194
  if (!result.timedOut) {
@@ -223,11 +231,11 @@ class BrowserType extends _channelOwner.ChannelOwner {
223
231
  context._setOptions(contextOptions, browserOptions);
224
232
  if (this._defaultContextTimeout !== undefined) context.setDefaultTimeout(this._defaultContextTimeout);
225
233
  if (this._defaultContextNavigationTimeout !== undefined) context.setDefaultNavigationTimeout(this._defaultContextNavigationTimeout);
226
- await this._instrumentation.onDidCreateBrowserContext(context);
234
+ await this._instrumentation.runAfterCreateBrowserContext(context);
227
235
  }
228
236
  async _willCloseContext(context) {
229
237
  this._contexts.delete(context);
230
- await this._instrumentation.onWillCloseBrowserContext(context);
238
+ await this._instrumentation.runBeforeCloseBrowserContext(context);
231
239
  }
232
240
  }
233
241
  exports.BrowserType = BrowserType;
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.ChannelOwner = void 0;
7
- var _events = require("events");
7
+ var _eventEmitter = require("./eventEmitter");
8
8
  var _validator = require("../protocol/validator");
9
9
  var _debugLogger = require("../utils/debugLogger");
10
10
  var _stackTrace = require("../utils/stackTrace");
@@ -26,7 +26,7 @@ var _zones = require("../utils/zones");
26
26
  * limitations under the License.
27
27
  */
28
28
 
29
- class ChannelOwner extends _events.EventEmitter {
29
+ class ChannelOwner extends _eventEmitter.EventEmitter {
30
30
  constructor(parent, type, guid, initializer) {
31
31
  super();
32
32
  this._connection = void 0;
@@ -51,7 +51,7 @@ class ChannelOwner extends _events.EventEmitter {
51
51
  this._parent._objects.set(guid, this);
52
52
  this._logger = this._parent._logger;
53
53
  }
54
- this._channel = this._createChannel(new _events.EventEmitter());
54
+ this._channel = this._createChannel(new _eventEmitter.EventEmitter());
55
55
  this._initializer = initializer;
56
56
  }
57
57
  _setEventToSubscriptionMapping(mapping) {
@@ -127,20 +127,25 @@ class ChannelOwner extends _events.EventEmitter {
127
127
  frames,
128
128
  csi,
129
129
  callCookie,
130
- wallTime
130
+ stepId
131
131
  } = apiZone.reported ? {
132
132
  apiName: undefined,
133
133
  csi: undefined,
134
134
  callCookie: undefined,
135
135
  frames: [],
136
- wallTime: undefined
136
+ stepId: undefined
137
137
  } : apiZone;
138
138
  apiZone.reported = true;
139
- if (csi && apiName) csi.onApiCallBegin(apiName, params, frames, wallTime, callCookie);
139
+ let currentStepId = stepId;
140
+ if (csi && apiName) {
141
+ const out = {};
142
+ csi.onApiCallBegin(apiName, params, frames, callCookie, out);
143
+ currentStepId = out.stepId;
144
+ }
140
145
  return await this._connection.sendMessageToServer(this, prop, validator(params, '', {
141
146
  tChannelImpl: tChannelImplToWire,
142
147
  binary: this._connection.rawBuffers() ? 'buffer' : 'toBase64'
143
- }), apiName, frames, wallTime);
148
+ }), apiName, frames, currentStepId);
144
149
  });
145
150
  };
146
151
  }
@@ -153,18 +158,17 @@ class ChannelOwner extends _events.EventEmitter {
153
158
  }
154
159
  async _wrapApiCall(func, isInternal = false) {
155
160
  const logger = this._logger;
156
- const stack = (0, _stackTrace.captureRawStack)();
157
- const apiZone = _zones.zones.zoneData('apiZone', stack);
161
+ const apiZone = _zones.zones.zoneData('apiZone');
158
162
  if (apiZone) return await func(apiZone);
159
- const stackTrace = (0, _stackTrace.captureLibraryStackTrace)(stack);
163
+ const stackTrace = (0, _stackTrace.captureLibraryStackTrace)();
160
164
  let apiName = stackTrace.apiName;
161
165
  const frames = stackTrace.frames;
162
166
  isInternal = isInternal || this._type === 'LocalUtils';
163
167
  if (isInternal) apiName = undefined;
164
168
 
165
169
  // Enclosing zone could have provided the apiName and wallTime.
166
- const expectZone = _zones.zones.zoneData('expectZone', stack);
167
- const wallTime = expectZone ? expectZone.wallTime : Date.now();
170
+ const expectZone = _zones.zones.zoneData('expectZone');
171
+ const stepId = expectZone === null || expectZone === void 0 ? void 0 : expectZone.stepId;
168
172
  if (!isInternal && expectZone) apiName = expectZone.title;
169
173
 
170
174
  // If we are coming from the expectZone, there is no need to generate a new
@@ -180,11 +184,10 @@ class ChannelOwner extends _events.EventEmitter {
180
184
  reported: false,
181
185
  csi,
182
186
  callCookie,
183
- wallTime
187
+ stepId
184
188
  };
185
- const result = await _zones.zones.run('apiZone', apiZone, async () => {
186
- return await func(apiZone);
187
- });
189
+ const result = await _zones.zones.run('apiZone', apiZone, async () => await func(apiZone));
190
+ // @ts-ignore
188
191
  csi === null || csi === void 0 || csi.onApiCallEnd(callCookie, null, result);
189
192
  logApiCall(logger, `<= ${apiName} succeeded`, isInternal);
190
193
  return result;
@@ -28,13 +28,23 @@ function createInstrumentation() {
28
28
  if (prop === 'addListener') return listener => listeners.push(listener);
29
29
  if (prop === 'removeListener') return listener => listeners.splice(listeners.indexOf(listener), 1);
30
30
  if (prop === 'removeAllListeners') return () => listeners.splice(0, listeners.length);
31
- if (!prop.startsWith('on')) return obj[prop];
32
- return async (...params) => {
33
- for (const listener of listeners) {
34
- var _prop, _ref;
35
- await ((_prop = (_ref = listener)[prop]) === null || _prop === void 0 ? void 0 : _prop.call(_ref, ...params));
36
- }
37
- };
31
+ if (prop.startsWith('run')) {
32
+ return async (...params) => {
33
+ for (const listener of listeners) {
34
+ var _prop, _ref;
35
+ await ((_prop = (_ref = listener)[prop]) === null || _prop === void 0 ? void 0 : _prop.call(_ref, ...params));
36
+ }
37
+ };
38
+ }
39
+ if (prop.startsWith('on')) {
40
+ return (...params) => {
41
+ for (const listener of listeners) {
42
+ var _prop2, _ref2;
43
+ (_prop2 = (_ref2 = listener)[prop]) === null || _prop2 === void 0 || _prop2.call(_ref2, ...params);
44
+ }
45
+ };
46
+ }
47
+ return obj[prop];
38
48
  }
39
49
  });
40
50
  }
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Clock = void 0;
7
+ /**
8
+ * Copyright (c) Microsoft Corporation.
9
+ *
10
+ * Licensed under the Apache License, Version 2.0 (the "License");
11
+ * you may not use this file except in compliance with the License.
12
+ * You may obtain a copy of the License at
13
+ *
14
+ * http://www.apache.org/licenses/LICENSE-2.0
15
+ *
16
+ * Unless required by applicable law or agreed to in writing, software
17
+ * distributed under the License is distributed on an "AS IS" BASIS,
18
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
+ * See the License for the specific language governing permissions and
20
+ * limitations under the License.
21
+ */
22
+
23
+ class Clock {
24
+ constructor(browserContext) {
25
+ this._browserContext = void 0;
26
+ this._browserContext = browserContext;
27
+ }
28
+ async install(options = {}) {
29
+ await this._browserContext._channel.clockInstall(options.time !== undefined ? parseTime(options.time) : {});
30
+ }
31
+ async fastForward(ticks) {
32
+ await this._browserContext._channel.clockFastForward(parseTicks(ticks));
33
+ }
34
+ async pauseAt(time) {
35
+ await this._browserContext._channel.clockPauseAt(parseTime(time));
36
+ }
37
+ async resume() {
38
+ await this._browserContext._channel.clockResume({});
39
+ }
40
+ async runFor(ticks) {
41
+ await this._browserContext._channel.clockRunFor(parseTicks(ticks));
42
+ }
43
+ async setFixedTime(time) {
44
+ await this._browserContext._channel.clockSetFixedTime(parseTime(time));
45
+ }
46
+ async setSystemTime(time) {
47
+ await this._browserContext._channel.clockSetSystemTime(parseTime(time));
48
+ }
49
+ }
50
+ exports.Clock = Clock;
51
+ function parseTime(time) {
52
+ if (typeof time === 'number') return {
53
+ timeNumber: time
54
+ };
55
+ if (typeof time === 'string') return {
56
+ timeString: time
57
+ };
58
+ if (!isFinite(time.getTime())) throw new Error(`Invalid date: ${time}`);
59
+ return {
60
+ timeNumber: time.getTime()
61
+ };
62
+ }
63
+ function parseTicks(ticks) {
64
+ return {
65
+ ticksNumber: typeof ticks === 'number' ? ticks : undefined,
66
+ ticksString: typeof ticks === 'string' ? ticks : undefined
67
+ };
68
+ }
@@ -104,7 +104,7 @@ class Connection extends _events.EventEmitter {
104
104
  setIsTracing(isTracing) {
105
105
  if (isTracing) this._tracingCount++;else this._tracingCount--;
106
106
  }
107
- async sendMessageToServer(object, method, params, apiName, frames, wallTime) {
107
+ async sendMessageToServer(object, method, params, apiName, frames, stepId) {
108
108
  var _this$_localUtils;
109
109
  if (this._closedError) throw this._closedError;
110
110
  if (object._wasCollected) throw new Error('The object has been collected to prevent unbounded heap growth.');
@@ -127,10 +127,10 @@ class Connection extends _events.EventEmitter {
127
127
  column: frames[0].column
128
128
  } : undefined;
129
129
  const metadata = {
130
- wallTime,
131
130
  apiName,
132
131
  location,
133
- internal: !apiName
132
+ internal: !apiName,
133
+ stepId
134
134
  };
135
135
  if (this._tracingCount && frames && type !== 'LocalUtils') (_this$_localUtils = this._localUtils) === null || _this$_localUtils === void 0 || _this$_localUtils._channel.addStackToTracingNoReply({
136
136
  callData: {
@@ -138,10 +138,12 @@ class Connection extends _events.EventEmitter {
138
138
  id
139
139
  }
140
140
  }).catch(() => {});
141
- this.onmessage({
141
+ // We need to exit zones before calling into the server, otherwise
142
+ // when we receive events from the server, we would be in an API zone.
143
+ _utils.zones.exitZones(() => this.onmessage({
142
144
  ...message,
143
145
  metadata
144
- });
146
+ }));
145
147
  return await new Promise((resolve, reject) => this._callbacks.set(id, {
146
148
  resolve,
147
149
  reject,
@@ -203,7 +205,8 @@ class Connection extends _events.EventEmitter {
203
205
  }));
204
206
  }
205
207
  close(cause) {
206
- this._closedError = new _errors.TargetClosedError(cause === null || cause === void 0 ? void 0 : cause.toString());
208
+ if (this._closedError) return;
209
+ this._closedError = new _errors.TargetClosedError(cause);
207
210
  for (const callback of this._callbacks.values()) callback.reject(this._closedError);
208
211
  this._callbacks.clear();
209
212
  this.emit('close');
@@ -43,7 +43,7 @@ class Electron extends _channelOwner.ChannelOwner {
43
43
  tracesDir: options.tracesDir
44
44
  };
45
45
  const app = ElectronApplication.from((await this._channel.launch(params)).electronApplication);
46
- app._context._options = params;
46
+ app._context._setOptions(params, options);
47
47
  return app;
48
48
  }
49
49
  }
@@ -58,12 +58,10 @@ class ElectronApplication extends _channelOwner.ChannelOwner {
58
58
  this._context = void 0;
59
59
  this._windows = new Set();
60
60
  this._timeoutSettings = new _timeoutSettings.TimeoutSettings();
61
- this._isClosed = false;
62
61
  this._context = _browserContext.BrowserContext.from(initializer.context);
63
62
  for (const page of this._context._pages) this._onPage(page);
64
63
  this._context.on(_events.Events.BrowserContext.Page, page => this._onPage(page));
65
64
  this._channel.on('close', () => {
66
- this._isClosed = true;
67
65
  this.emit(_events.Events.ElectronApplication.Close);
68
66
  });
69
67
  this._channel.on('console', event => this.emit(_events.Events.ElectronApplication.Console, new _consoleMessage.ConsoleMessage(event)));
@@ -92,8 +90,12 @@ class ElectronApplication extends _channelOwner.ChannelOwner {
92
90
  await this.close();
93
91
  }
94
92
  async close() {
95
- if (this._isClosed) return;
96
- await this._channel.close().catch(() => {});
93
+ try {
94
+ await this._context.close();
95
+ } catch (e) {
96
+ if ((0, _errors.isTargetClosedError)(e)) return;
97
+ throw e;
98
+ }
97
99
  }
98
100
  async waitForEvent(event, optionsOrPredicate = {}) {
99
101
  return await this._wrapApiCall(async () => {
@@ -250,29 +250,59 @@ function convertSelectOptionValues(values) {
250
250
  function filePayloadExceedsSizeLimit(payloads) {
251
251
  return payloads.reduce((size, item) => size + (item.buffer ? item.buffer.byteLength : 0), 0) >= _fileUtils.fileUploadSizeLimit;
252
252
  }
253
+ async function resolvePathsAndDirectoryForInputFiles(items) {
254
+ var _localPaths2;
255
+ let localPaths;
256
+ let localDirectory;
257
+ for (const item of items) {
258
+ const stat = await _fs.default.promises.stat(item);
259
+ if (stat.isDirectory()) {
260
+ if (localDirectory) throw new Error('Multiple directories are not supported');
261
+ localDirectory = _path.default.resolve(item);
262
+ } else {
263
+ var _localPaths;
264
+ (_localPaths = localPaths) !== null && _localPaths !== void 0 ? _localPaths : localPaths = [];
265
+ localPaths.push(_path.default.resolve(item));
266
+ }
267
+ }
268
+ if ((_localPaths2 = localPaths) !== null && _localPaths2 !== void 0 && _localPaths2.length && localDirectory) throw new Error('File paths must be all files or a single directory');
269
+ return [localPaths, localDirectory];
270
+ }
253
271
  async function convertInputFiles(files, context) {
254
272
  const items = Array.isArray(files) ? files.slice() : [files];
255
273
  if (items.some(item => typeof item === 'string')) {
256
274
  if (!items.every(item => typeof item === 'string')) throw new Error('File paths cannot be mixed with buffers');
275
+ const [localPaths, localDirectory] = await resolvePathsAndDirectoryForInputFiles(items);
257
276
  if (context._connection.isRemote()) {
258
- const streams = await Promise.all(items.map(async item => {
259
- const lastModifiedMs = (await _fs.default.promises.stat(item)).mtimeMs;
260
- const {
261
- writableStream: stream
262
- } = await context._wrapApiCall(() => context._channel.createTempFile({
263
- name: _path.default.basename(item),
264
- lastModifiedMs
265
- }), true);
266
- const writable = _writableStream.WritableStream.from(stream);
267
- await pipelineAsync(_fs.default.createReadStream(item), writable.stream());
268
- return stream;
269
- }));
277
+ const files = localDirectory ? (await _fs.default.promises.readdir(localDirectory, {
278
+ withFileTypes: true,
279
+ recursive: true
280
+ })).filter(f => f.isFile()).map(f => _path.default.join(f.path, f.name)) : localPaths;
281
+ const {
282
+ writableStreams,
283
+ rootDir
284
+ } = await context._wrapApiCall(async () => context._channel.createTempFiles({
285
+ rootDirName: localDirectory ? _path.default.basename(localDirectory) : undefined,
286
+ items: await Promise.all(files.map(async file => {
287
+ const lastModifiedMs = (await _fs.default.promises.stat(file)).mtimeMs;
288
+ return {
289
+ name: localDirectory ? _path.default.relative(localDirectory, file) : _path.default.basename(file),
290
+ lastModifiedMs
291
+ };
292
+ }))
293
+ }), true);
294
+ for (let i = 0; i < files.length; i++) {
295
+ const writable = _writableStream.WritableStream.from(writableStreams[i]);
296
+ await pipelineAsync(_fs.default.createReadStream(files[i]), writable.stream());
297
+ }
270
298
  return {
271
- streams
299
+ directoryStream: rootDir,
300
+ streams: localDirectory ? undefined : writableStreams
272
301
  };
273
302
  }
274
303
  return {
275
- localPaths: items.map(f => _path.default.resolve(f))
304
+ localPaths,
305
+ localDirectory
276
306
  };
277
307
  }
278
308
  const payloads = items;