@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.
- package/ThirdPartyNotices.txt +144 -109
- package/browsers.json +15 -25
- package/lib/androidServerImpl.js +1 -1
- package/lib/browserServerImpl.js +1 -1
- package/lib/cli/driver.js +1 -3
- package/lib/cli/program.js +5 -10
- package/lib/client/android.js +1 -1
- package/lib/client/api.js +7 -0
- package/lib/client/browserContext.js +37 -5
- package/lib/client/browserType.js +19 -11
- package/lib/client/channelOwner.js +19 -16
- package/lib/client/clientInstrumentation.js +17 -7
- package/lib/client/clock.js +68 -0
- package/lib/client/connection.js +9 -6
- package/lib/client/electron.js +7 -5
- package/lib/client/elementHandle.js +44 -14
- package/lib/client/eventEmitter.js +314 -0
- package/lib/client/fetch.js +81 -28
- package/lib/client/frame.js +2 -4
- package/lib/client/jsHandle.js +7 -1
- package/lib/client/locator.js +9 -0
- package/lib/client/network.js +12 -9
- package/lib/client/page.js +45 -23
- package/lib/client/playwright.js +3 -0
- package/lib/client/tracing.js +7 -4
- package/lib/common/socksProxy.js +2 -2
- package/lib/generated/clockSource.js +7 -0
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/recorderSource.js +1 -1
- package/lib/generated/utilityScriptSource.js +1 -1
- package/lib/protocol/serializers.js +12 -11
- package/lib/protocol/validator.js +137 -55
- package/lib/server/bidi/bidiBrowser.js +296 -0
- package/lib/server/bidi/bidiConnection.js +206 -0
- package/lib/server/bidi/bidiExecutionContext.js +162 -0
- package/lib/server/bidi/bidiFirefox.js +110 -0
- package/lib/server/bidi/bidiInput.js +174 -0
- package/lib/server/bidi/bidiNetworkManager.js +304 -0
- package/lib/server/bidi/bidiPage.js +456 -0
- package/lib/server/bidi/third_party/bidiDeserializer.js +93 -0
- package/lib/server/bidi/third_party/bidiKeyboard.js +238 -0
- package/lib/server/bidi/third_party/bidiProtocol.js +139 -0
- package/lib/server/bidi/third_party/bidiSerializer.js +144 -0
- package/lib/server/browser.js +9 -1
- package/lib/server/browserContext.js +97 -22
- package/lib/server/browserType.js +27 -20
- package/lib/server/chromium/chromium.js +30 -15
- package/lib/server/chromium/chromiumSwitches.js +6 -3
- package/lib/server/chromium/crBrowser.js +11 -17
- package/lib/server/chromium/crConnection.js +2 -2
- package/lib/server/chromium/crDragDrop.js +28 -29
- package/lib/server/chromium/crNetworkManager.js +130 -84
- package/lib/server/chromium/crPage.js +34 -79
- package/lib/server/chromium/crProtocolHelper.js +3 -1
- package/lib/server/chromium/crServiceWorker.js +20 -23
- package/lib/server/chromium/videoRecorder.js +1 -1
- package/lib/server/clock.js +125 -0
- package/lib/server/codegen/csharp.js +299 -0
- package/lib/server/codegen/java.js +235 -0
- package/lib/server/codegen/javascript.js +223 -0
- package/lib/server/codegen/jsonl.js +47 -0
- package/lib/server/codegen/language.js +76 -0
- package/lib/server/codegen/languages.js +30 -0
- package/lib/server/codegen/python.js +265 -0
- package/lib/server/codegen/types.js +5 -0
- package/lib/server/debugController.js +3 -5
- package/lib/server/deviceDescriptors.js +9 -4
- package/lib/server/deviceDescriptorsSource.json +239 -119
- package/lib/server/dispatchers/androidDispatcher.js +1 -1
- package/lib/server/dispatchers/browserContextDispatcher.js +51 -7
- package/lib/server/dispatchers/dispatcher.js +36 -40
- package/lib/server/dispatchers/frameDispatcher.js +1 -2
- package/lib/server/dispatchers/jsHandleDispatcher.js +1 -1
- package/lib/server/dispatchers/jsonPipeDispatcher.js +4 -6
- package/lib/server/dispatchers/localUtilsDispatcher.js +19 -5
- package/lib/server/dispatchers/networkDispatchers.js +2 -2
- package/lib/server/dispatchers/pageDispatcher.js +5 -2
- package/lib/server/dispatchers/playwrightDispatcher.js +1 -0
- package/lib/server/dispatchers/writableStreamDispatcher.js +8 -5
- package/lib/server/dom.js +90 -53
- package/lib/server/electron/electron.js +21 -4
- package/lib/server/fetch.js +74 -25
- package/lib/server/fileUploadUtils.js +7 -3
- package/lib/server/firefox/ffBrowser.js +36 -25
- package/lib/server/firefox/ffConnection.js +2 -2
- package/lib/server/firefox/ffNetworkManager.js +6 -4
- package/lib/server/firefox/ffPage.js +22 -24
- package/lib/server/firefox/firefox.js +25 -6
- package/lib/server/frameSelectors.js +2 -2
- package/lib/server/frames.js +205 -159
- package/lib/server/har/harTracer.js +4 -12
- package/lib/server/helper.js +3 -3
- package/lib/server/index.js +18 -0
- package/lib/server/input.js +18 -8
- package/lib/server/instrumentation.js +0 -4
- package/lib/server/isomorphic/utilityScriptSerializers.js +19 -5
- package/lib/server/javascript.js +3 -2
- package/lib/server/launchApp.js +3 -2
- package/lib/server/network.js +14 -4
- package/lib/server/page.js +75 -46
- package/lib/server/playwright.js +5 -2
- package/lib/server/recorder/codeGenerator.js +2 -1
- package/lib/server/recorder/contextRecorder.js +316 -0
- package/lib/server/recorder/csharp.js +2 -1
- package/lib/server/recorder/java.js +2 -1
- package/lib/server/recorder/javascript.js +2 -1
- package/lib/server/recorder/jsonl.js +2 -1
- package/lib/server/recorder/language.js +2 -1
- package/lib/server/recorder/python.js +2 -1
- package/lib/server/recorder/recorderApp.js +14 -5
- package/lib/server/recorder/recorderCollection.js +127 -0
- package/lib/server/recorder/recorderRunner.js +177 -0
- package/lib/server/recorder/recorderUtils.js +23 -0
- package/lib/server/recorder/throttledFile.js +46 -0
- package/lib/server/recorder/utils.js +2 -1
- package/lib/server/recorder.js +42 -418
- package/lib/server/registry/index.js +99 -100
- package/lib/server/registry/nativeDeps.js +107 -0
- package/lib/server/screenshotter.js +6 -12
- package/lib/server/socksClientCertificatesInterceptor.js +328 -0
- package/lib/server/trace/recorder/snapshotter.js +4 -1
- package/lib/server/trace/recorder/tracing.js +27 -96
- package/lib/server/trace/viewer/traceViewer.js +54 -67
- package/lib/server/transport.js +1 -1
- package/lib/server/webkit/webkit.js +5 -5
- package/lib/server/webkit/wkBrowser.js +14 -14
- package/lib/server/webkit/wkConnection.js +3 -3
- package/lib/server/webkit/wkInterceptableRequest.js +8 -4
- package/lib/server/webkit/wkPage.js +52 -34
- package/lib/server/webkit/wkProvisionalPage.js +36 -1
- package/lib/utils/crypto.js +141 -0
- package/lib/utils/debugLogger.js +2 -0
- package/lib/utils/env.js +4 -2
- package/lib/utils/expectUtils.js +33 -0
- package/lib/utils/fileUtils.js +140 -1
- package/lib/utils/glob.js +2 -1
- package/lib/utils/happy-eyeballs.js +29 -2
- package/lib/utils/hostPlatform.js +13 -4
- package/lib/utils/httpServer.js +54 -13
- package/lib/utils/index.js +53 -31
- package/lib/utils/isomorphic/cssTokenizer.js +1 -1
- package/lib/utils/isomorphic/locatorParser.js +1 -1
- package/lib/utils/isomorphic/mimeType.js +29 -0
- package/lib/utils/isomorphic/stringUtils.js +28 -1
- package/lib/utils/isomorphic/urlMatch.js +120 -0
- package/lib/utils/mimeType.js +2 -1
- package/lib/utils/network.js +7 -35
- package/lib/utils/stackTrace.js +2 -4
- package/lib/utils/timeoutRunner.js +11 -76
- package/lib/utils/zones.js +23 -60
- package/lib/utilsBundle.js +2 -1
- package/lib/utilsBundleImpl/index.js +33 -31
- package/lib/vite/htmlReport/index.html +12 -12
- package/lib/vite/recorder/assets/codeMirrorModule-BN0yUF4I.js +24 -0
- package/lib/vite/recorder/assets/{codicon-zGuYmc9o.ttf → codicon-DCmgc-ay.ttf} +0 -0
- package/lib/vite/recorder/assets/index-B-MT5gKo.css +1 -0
- package/lib/vite/recorder/assets/index-DVt3E1Ef.js +47 -0
- package/lib/vite/recorder/index.html +2 -2
- package/lib/vite/traceViewer/assets/codeMirrorModule-5yiV-3wl.js +16831 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-B7Z3vq11.js +24 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-C6p3E9Zg.js +24 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-CcviAl53.js +16831 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-CqYUz5ms.js +24 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-DS3v0XrQ.js +24 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-Dx6AXgMV.js +16838 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-T_sdMrbM.js +24 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-V7N6ppkd.js +15585 -0
- package/lib/vite/traceViewer/assets/testServerConnection-D-tXL3sj.js +224 -0
- package/lib/vite/traceViewer/assets/testServerConnection-DeE2kSzz.js +1 -0
- package/lib/vite/traceViewer/assets/workbench-Bjkiwcr1.js +19119 -0
- package/lib/vite/traceViewer/assets/workbench-C43LWZEX.js +72 -0
- package/lib/vite/traceViewer/assets/workbench-C5OQh9VX.js +19119 -0
- package/lib/vite/traceViewer/assets/workbench-Crj6jzdv.js +19119 -0
- package/lib/vite/traceViewer/assets/workbench-DrQjKdyE.js +72 -0
- package/lib/vite/traceViewer/assets/workbench-Pa1v1Ojh.js +72 -0
- package/lib/vite/traceViewer/assets/workbench-caTaZnzx.js +72 -0
- package/lib/vite/traceViewer/assets/workbench-u2lRPMOT.js +72 -0
- package/lib/vite/traceViewer/assets/wsPort-EUvw-dwH.js +18540 -0
- package/lib/vite/traceViewer/assets/xtermModule-CZ7sDYXB.js +6529 -0
- package/lib/vite/traceViewer/assets/xtermModule-_6TC5FYT.js +6529 -0
- package/lib/vite/traceViewer/codeMirrorModule.Cy8X9Wtw.css +344 -0
- package/lib/vite/traceViewer/codeMirrorModule.svF_VrcJ.css +344 -0
- package/lib/vite/traceViewer/codicon.DCmgc-ay.ttf +0 -0
- package/lib/vite/traceViewer/embedded.BBZ9gQEw.js +104 -0
- package/lib/vite/traceViewer/embedded.BQq6Psnz.js +104 -0
- package/lib/vite/traceViewer/embedded.BVDVQOzc.js +2 -0
- package/lib/vite/traceViewer/embedded.Bn8Ptzv6.js +2 -0
- package/lib/vite/traceViewer/embedded.CvhnUgIi.js +2 -0
- package/lib/vite/traceViewer/embedded.D27cnKiB.js +104 -0
- package/lib/vite/traceViewer/embedded.DPqrDeET.js +2 -0
- package/lib/vite/traceViewer/embedded.DbzY7Q8w.js +2 -0
- package/lib/vite/traceViewer/embedded.DjZq4InJ.css +68 -0
- package/lib/vite/traceViewer/embedded.html +16 -0
- package/lib/vite/traceViewer/embedded.w7WN2u1R.css +1 -0
- package/lib/vite/traceViewer/index.5mge2rY_.css +124 -0
- package/lib/vite/traceViewer/index.6KJ-JQ0L.js +180 -0
- package/lib/vite/traceViewer/index.B8dgQwuN.js +2 -0
- package/lib/vite/traceViewer/index.BGj8jY3H.js +2 -0
- package/lib/vite/traceViewer/index.BSak5QT9.js +2 -0
- package/lib/vite/traceViewer/index.C0EgJ4oW.js +195 -0
- package/lib/vite/traceViewer/index.CUpI-BFe.js +195 -0
- package/lib/vite/traceViewer/{index.-g_5lMbJ.css → index.CrbWWHbf.css} +1 -1
- package/lib/vite/traceViewer/index.DkRbtWVo.js +195 -0
- package/lib/vite/traceViewer/index.QanXxRUb.css +131 -0
- package/lib/vite/traceViewer/index._cX8k4co.js +2 -0
- package/lib/vite/traceViewer/index.html +5 -4
- package/lib/vite/traceViewer/index.pMAN88y-.js +2 -0
- package/lib/vite/traceViewer/snapshot.html +1 -1
- package/lib/vite/traceViewer/sw.bundle.js +3 -4
- package/lib/vite/traceViewer/uiMode.D-tg1Oci.js +1730 -0
- package/lib/vite/traceViewer/uiMode.D3cNFP6u.css +1 -0
- package/lib/vite/traceViewer/uiMode.DKjMBMlc.js +1730 -0
- package/lib/vite/traceViewer/uiMode.DVWUEIHq.css +1424 -0
- package/lib/vite/traceViewer/uiMode.DVrL7a1K.js +10 -0
- package/lib/vite/traceViewer/uiMode.Dg9oJCQU.js +10 -0
- package/lib/vite/traceViewer/uiMode.DwZAzstF.js +10 -0
- package/lib/vite/traceViewer/uiMode.O07awP3T.js +10 -0
- package/lib/vite/traceViewer/uiMode.gGHHTsyL.js +1730 -0
- package/lib/vite/traceViewer/uiMode.html +5 -4
- package/lib/vite/traceViewer/uiMode.iq7CyYy7.js +1490 -0
- package/lib/vite/traceViewer/uiMode.jY2s-9ps.js +10 -0
- package/lib/vite/traceViewer/uiMode.xvJHbkzl.css +1324 -0
- package/lib/vite/traceViewer/workbench.B3X2QtYa.css +3702 -0
- package/lib/vite/traceViewer/workbench.DjbIuxix.css +1 -0
- package/lib/vite/traceViewer/workbench.DyTpxWVb.css +1 -0
- package/lib/vite/traceViewer/workbench.wuxQoE2z.css +3703 -0
- package/lib/vite/traceViewer/wsPort.p5jUwABW.css +3450 -0
- package/lib/vite/traceViewer/xtermModule.4oRVGWQ-.css +209 -0
- package/lib/vite/traceViewer/xtermModule.OKEVRlkP.css +209 -0
- package/package.json +2 -2
- package/types/protocol.d.ts +960 -78
- package/types/structs.d.ts +1 -1
- package/types/types.d.ts +3083 -2448
- package/lib/vite/recorder/assets/codeMirrorModule-I9ks4y7D.js +0 -24
- package/lib/vite/recorder/assets/index-ljsTwXtJ.css +0 -1
- package/lib/vite/recorder/assets/index-yg8ypzl6.js +0 -47
- package/lib/vite/traceViewer/assets/codeMirrorModule-0bpaqixv.js +0 -24
- package/lib/vite/traceViewer/assets/wsPort-_JBDEilC.js +0 -69
- package/lib/vite/traceViewer/index.u51inEcm.js +0 -2
- package/lib/vite/traceViewer/uiMode.Fb0bNA4H.js +0 -10
- package/lib/vite/traceViewer/uiMode.pWy0Re7G.css +0 -1
- package/lib/vite/traceViewer/wsPort.zR1WIy9-.css +0 -1
- /package/lib/vite/recorder/assets/{codeMirrorModule-Hs9-1ZG4.css → codeMirrorModule-ez37Vkbh.css} +0 -0
- /package/lib/vite/traceViewer/assets/{xtermModule-Yt6xwiJ_.js → xtermModule-BeNbaIVa.js} +0 -0
- /package/lib/vite/traceViewer/{codeMirrorModule.Hs9-1ZG4.css → codeMirrorModule.ez37Vkbh.css} +0 -0
- /package/lib/vite/traceViewer/{xtermModule.0lwXJFHT.css → xtermModule.DSXBckUd.css} +0 -0
|
@@ -64,6 +64,7 @@ class CRPage {
|
|
|
64
64
|
this.rawTouchscreen = void 0;
|
|
65
65
|
this._targetId = void 0;
|
|
66
66
|
this._opener = void 0;
|
|
67
|
+
this._networkManager = void 0;
|
|
67
68
|
this._pdf = void 0;
|
|
68
69
|
this._coverage = void 0;
|
|
69
70
|
this._browserContext = void 0;
|
|
@@ -87,6 +88,13 @@ class CRPage {
|
|
|
87
88
|
this._coverage = new _crCoverage.CRCoverage(client);
|
|
88
89
|
this._browserContext = browserContext;
|
|
89
90
|
this._page = new _page.Page(this, browserContext);
|
|
91
|
+
this._networkManager = new _crNetworkManager.CRNetworkManager(this._page, null);
|
|
92
|
+
// Sync any browser context state to the network manager. This does not talk over CDP because
|
|
93
|
+
// we have not connected any sessions to the network manager yet.
|
|
94
|
+
this.updateOffline();
|
|
95
|
+
this.updateExtraHTTPHeaders();
|
|
96
|
+
this.updateHttpCredentials();
|
|
97
|
+
this.updateRequestInterception();
|
|
90
98
|
this._mainFrameSession = new FrameSession(this, client, targetId, null);
|
|
91
99
|
this._sessions.set(targetId, this._mainFrameSession);
|
|
92
100
|
if (opener && !browserContext._options.noDefaultViewport) {
|
|
@@ -157,24 +165,18 @@ class CRPage {
|
|
|
157
165
|
async navigateFrame(frame, url, referrer) {
|
|
158
166
|
return this._sessionForFrame(frame)._navigate(frame, url, referrer);
|
|
159
167
|
}
|
|
160
|
-
async exposeBinding(binding) {
|
|
161
|
-
await this._forAllFrameSessions(frame => frame._initBinding(binding));
|
|
162
|
-
await Promise.all(this._page.frames().map(frame => frame.evaluateExpression(binding.source).catch(e => {})));
|
|
163
|
-
}
|
|
164
|
-
async removeExposedBindings() {
|
|
165
|
-
await this._forAllFrameSessions(frame => frame._removeExposedBindings());
|
|
166
|
-
}
|
|
167
168
|
async updateExtraHTTPHeaders() {
|
|
168
|
-
|
|
169
|
+
const headers = network.mergeHeaders([this._browserContext._options.extraHTTPHeaders, this._page.extraHTTPHeaders()]);
|
|
170
|
+
await this._networkManager.setExtraHTTPHeaders(headers);
|
|
169
171
|
}
|
|
170
172
|
async updateGeolocation() {
|
|
171
173
|
await this._forAllFrameSessions(frame => frame._updateGeolocation(false));
|
|
172
174
|
}
|
|
173
175
|
async updateOffline() {
|
|
174
|
-
await this.
|
|
176
|
+
await this._networkManager.setOffline(!!this._browserContext._options.offline);
|
|
175
177
|
}
|
|
176
178
|
async updateHttpCredentials() {
|
|
177
|
-
await this.
|
|
179
|
+
await this._networkManager.authenticate(this._browserContext._options.httpCredentials || null);
|
|
178
180
|
}
|
|
179
181
|
async updateEmulatedViewportSize(preserveWindowBoundaries) {
|
|
180
182
|
await this._mainFrameSession._updateViewport(preserveWindowBoundaries);
|
|
@@ -189,7 +191,7 @@ class CRPage {
|
|
|
189
191
|
await this._forAllFrameSessions(frame => frame._updateUserAgent());
|
|
190
192
|
}
|
|
191
193
|
async updateRequestInterception() {
|
|
192
|
-
await this.
|
|
194
|
+
await this._networkManager.setRequestInterception(this._page.needsRequestInterception());
|
|
193
195
|
}
|
|
194
196
|
async updateFileChooserInterception() {
|
|
195
197
|
await this._forAllFrameSessions(frame => frame._updateFileChooserInterception(false));
|
|
@@ -212,10 +214,10 @@ class CRPage {
|
|
|
212
214
|
goForward() {
|
|
213
215
|
return this._go(+1);
|
|
214
216
|
}
|
|
215
|
-
async addInitScript(
|
|
216
|
-
await this._forAllFrameSessions(frame => frame._evaluateOnNewDocument(
|
|
217
|
+
async addInitScript(initScript, world = 'main') {
|
|
218
|
+
await this._forAllFrameSessions(frame => frame._evaluateOnNewDocument(initScript, world));
|
|
217
219
|
}
|
|
218
|
-
async
|
|
220
|
+
async removeNonInternalInitScripts() {
|
|
219
221
|
await this._forAllFrameSessions(frame => frame._removeEvaluatesOnNewDocument());
|
|
220
222
|
}
|
|
221
223
|
async closePage(runBeforeUnload) {
|
|
@@ -295,7 +297,7 @@ class CRPage {
|
|
|
295
297
|
async setInputFiles(handle, files) {
|
|
296
298
|
await handle.evaluateInUtility(([injected, node, files]) => injected.setInputFiles(node, files), files);
|
|
297
299
|
}
|
|
298
|
-
async setInputFilePaths(
|
|
300
|
+
async setInputFilePaths(handle, files) {
|
|
299
301
|
const frame = await handle.ownerFrame();
|
|
300
302
|
if (!frame) throw new Error('Cannot set input files to detached input element');
|
|
301
303
|
const parentSession = this._sessionForFrame(frame);
|
|
@@ -346,7 +348,6 @@ class FrameSession {
|
|
|
346
348
|
this._client = void 0;
|
|
347
349
|
this._crPage = void 0;
|
|
348
350
|
this._page = void 0;
|
|
349
|
-
this._networkManager = void 0;
|
|
350
351
|
this._parentSession = void 0;
|
|
351
352
|
this._childSessions = new Set();
|
|
352
353
|
this._contextIdToContext = new Map();
|
|
@@ -363,14 +364,12 @@ class FrameSession {
|
|
|
363
364
|
this._screencastId = null;
|
|
364
365
|
this._screencastClients = new Set();
|
|
365
366
|
this._evaluateOnNewDocumentIdentifiers = [];
|
|
366
|
-
this._exposedBindingNames = [];
|
|
367
367
|
this._metricsOverride = void 0;
|
|
368
368
|
this._workerSessions = new Map();
|
|
369
369
|
this._client = client;
|
|
370
370
|
this._crPage = crPage;
|
|
371
371
|
this._page = crPage._page;
|
|
372
372
|
this._targetId = targetId;
|
|
373
|
-
this._networkManager = new _crNetworkManager.CRNetworkManager(client, this._page, null, parentSession ? parentSession._networkManager : null);
|
|
374
373
|
this._parentSession = parentSession;
|
|
375
374
|
if (parentSession) parentSession._childSessions.add(this);
|
|
376
375
|
this._firstNonInitialNavigationCommittedPromise = new Promise((f, r) => {
|
|
@@ -430,12 +429,11 @@ class FrameSession {
|
|
|
430
429
|
grantUniveralAccess: true,
|
|
431
430
|
worldName: UTILITY_WORLD_NAME
|
|
432
431
|
});
|
|
433
|
-
for (const
|
|
434
|
-
for (const source of this._crPage._browserContext.initScripts) frame.evaluateExpression(source).catch(e => {});
|
|
432
|
+
for (const initScript of this._crPage._page.allInitScripts()) frame.evaluateExpression(initScript.source).catch(e => {});
|
|
435
433
|
}
|
|
436
434
|
const isInitialEmptyPage = this._isMainFrame() && this._page.mainFrame().url() === ':';
|
|
437
435
|
if (isInitialEmptyPage) {
|
|
438
|
-
// Ignore lifecycle events for the initial empty page. It is never the final page
|
|
436
|
+
// Ignore lifecycle events, worlds and bindings for the initial empty page. It is never the final page
|
|
439
437
|
// hence we are going to get more lifecycle updates after the actual navigation has
|
|
440
438
|
// started (even if the target url is about:blank).
|
|
441
439
|
lifecycleEventsEnabled.catch(e => {}).then(() => {
|
|
@@ -447,10 +445,12 @@ class FrameSession {
|
|
|
447
445
|
}
|
|
448
446
|
}), this._client.send('Log.enable', {}), lifecycleEventsEnabled = this._client.send('Page.setLifecycleEventsEnabled', {
|
|
449
447
|
enabled: true
|
|
450
|
-
}), this._client.send('Runtime.enable', {}), this._client.send('
|
|
448
|
+
}), this._client.send('Runtime.enable', {}), this._client.send('Runtime.addBinding', {
|
|
449
|
+
name: _page.PageBinding.kPlaywrightBinding
|
|
450
|
+
}), this._client.send('Page.addScriptToEvaluateOnNewDocument', {
|
|
451
451
|
source: '',
|
|
452
452
|
worldName: UTILITY_WORLD_NAME
|
|
453
|
-
}), this._networkManager.
|
|
453
|
+
}), this._crPage._networkManager.addSession(this._client, undefined, this._isMainFrame()), this._client.send('Target.setAutoAttach', {
|
|
454
454
|
autoAttach: true,
|
|
455
455
|
waitForDebuggerOnStart: true,
|
|
456
456
|
flatten: true
|
|
@@ -478,15 +478,9 @@ class FrameSession {
|
|
|
478
478
|
if (options.timezoneId) promises.push(emulateTimezone(this._client, options.timezoneId));
|
|
479
479
|
if (!this._crPage._browserContext._browser.options.headful) promises.push(this._setDefaultFontFamilies(this._client));
|
|
480
480
|
promises.push(this._updateGeolocation(true));
|
|
481
|
-
promises.push(this._updateExtraHTTPHeaders(true));
|
|
482
|
-
promises.push(this._updateRequestInterception());
|
|
483
|
-
promises.push(this._updateOffline(true));
|
|
484
|
-
promises.push(this._updateHttpCredentials(true));
|
|
485
481
|
promises.push(this._updateEmulateMedia());
|
|
486
482
|
promises.push(this._updateFileChooserInterception(true));
|
|
487
|
-
for (const
|
|
488
|
-
for (const source of this._crPage._browserContext.initScripts) promises.push(this._evaluateOnNewDocument(source, 'main'));
|
|
489
|
-
for (const source of this._crPage._page.initScripts) promises.push(this._evaluateOnNewDocument(source, 'main'));
|
|
483
|
+
for (const initScript of this._crPage._page.allInitScripts()) promises.push(this._evaluateOnNewDocument(initScript, 'main'));
|
|
490
484
|
if (screencastOptions) promises.push(this._startVideoRecording(screencastOptions));
|
|
491
485
|
}
|
|
492
486
|
promises.push(this._client.send('Runtime.runIfWaitingForDebugger'));
|
|
@@ -498,7 +492,7 @@ class FrameSession {
|
|
|
498
492
|
for (const childSession of this._childSessions) childSession.dispose();
|
|
499
493
|
if (this._parentSession) this._parentSession._childSessions.delete(this);
|
|
500
494
|
_eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);
|
|
501
|
-
this._networkManager.
|
|
495
|
+
this._crPage._networkManager.removeSession(this._client);
|
|
502
496
|
this._crPage._sessions.delete(this._targetId);
|
|
503
497
|
this._client.dispose();
|
|
504
498
|
}
|
|
@@ -575,7 +569,7 @@ class FrameSession {
|
|
|
575
569
|
return;
|
|
576
570
|
}
|
|
577
571
|
if (reason === 'swap') {
|
|
578
|
-
// This is a local -> remote frame
|
|
572
|
+
// This is a local -> remote frame transition, where
|
|
579
573
|
// Page.frameDetached arrives before Target.attachedToTarget.
|
|
580
574
|
// We should keep the frame in the tree, and it will be used for the new target.
|
|
581
575
|
const frame = this._page._frameManager.frame(frameId);
|
|
@@ -589,11 +583,11 @@ class FrameSession {
|
|
|
589
583
|
const frame = contextPayload.auxData ? this._page._frameManager.frame(contextPayload.auxData.frameId) : null;
|
|
590
584
|
if (!frame || this._eventBelongsToStaleFrame(frame._id)) return;
|
|
591
585
|
const delegate = new _crExecutionContext.CRExecutionContext(this._client, contextPayload);
|
|
592
|
-
let worldName
|
|
593
|
-
if (contextPayload.auxData && !!contextPayload.auxData.isDefault) worldName = 'main';else if (contextPayload.name === UTILITY_WORLD_NAME) worldName = 'utility';
|
|
586
|
+
let worldName;
|
|
587
|
+
if (contextPayload.auxData && !!contextPayload.auxData.isDefault) worldName = 'main';else if (contextPayload.name === UTILITY_WORLD_NAME) worldName = 'utility';else return;
|
|
594
588
|
const context = new dom.FrameExecutionContext(delegate, frame, worldName);
|
|
595
589
|
context[contextDelegateSymbol] = delegate;
|
|
596
|
-
|
|
590
|
+
frame._contextCreated(worldName, context);
|
|
597
591
|
this._contextIdToContext.set(contextPayload.id, context);
|
|
598
592
|
}
|
|
599
593
|
_onExecutionContextDestroyed(executionContextId) {
|
|
@@ -632,7 +626,8 @@ class FrameSession {
|
|
|
632
626
|
});
|
|
633
627
|
// This might fail if the target is closed before we initialize.
|
|
634
628
|
session._sendMayFail('Runtime.enable');
|
|
635
|
-
|
|
629
|
+
// TODO: attribute workers to the right frame.
|
|
630
|
+
this._crPage._networkManager.addSession(session, (_this$_page$_frameMan = this._page._frameManager.frame(this._targetId)) !== null && _this$_page$_frameMan !== void 0 ? _this$_page$_frameMan : undefined).catch(() => {});
|
|
636
631
|
session._sendMayFail('Runtime.runIfWaitingForDebugger');
|
|
637
632
|
session._sendMayFail('Target.setAutoAttach', {
|
|
638
633
|
autoAttach: true,
|
|
@@ -646,11 +641,6 @@ class FrameSession {
|
|
|
646
641
|
this._page._addConsoleMessage(event.type, args, (0, _crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
|
|
647
642
|
});
|
|
648
643
|
session.on('Runtime.exceptionThrown', exception => this._page.emitOnContextOnceInitialized(_browserContext.BrowserContext.Events.PageError, (0, _crProtocolHelper.exceptionToError)(exception.exceptionDetails), this._page));
|
|
649
|
-
// TODO: attribute workers to the right frame.
|
|
650
|
-
this._networkManager.instrumentNetworkEvents({
|
|
651
|
-
session,
|
|
652
|
-
workerFrame: (_this$_page$_frameMan = this._page._frameManager.frame(this._targetId)) !== null && _this$_page$_frameMan !== void 0 ? _this$_page$_frameMan : undefined
|
|
653
|
-
});
|
|
654
644
|
}
|
|
655
645
|
_onDetachedFromTarget(event) {
|
|
656
646
|
// This might be a worker...
|
|
@@ -707,24 +697,6 @@ class FrameSession {
|
|
|
707
697
|
const values = event.args.map(arg => context.createHandle(arg));
|
|
708
698
|
this._page._addConsoleMessage(event.type, values, (0, _crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
|
|
709
699
|
}
|
|
710
|
-
async _initBinding(binding) {
|
|
711
|
-
const [, response] = await Promise.all([this._client.send('Runtime.addBinding', {
|
|
712
|
-
name: binding.name
|
|
713
|
-
}), this._client.send('Page.addScriptToEvaluateOnNewDocument', {
|
|
714
|
-
source: binding.source
|
|
715
|
-
})]);
|
|
716
|
-
this._exposedBindingNames.push(binding.name);
|
|
717
|
-
if (!binding.name.startsWith('__pw')) this._evaluateOnNewDocumentIdentifiers.push(response.identifier);
|
|
718
|
-
}
|
|
719
|
-
async _removeExposedBindings() {
|
|
720
|
-
const toRetain = [];
|
|
721
|
-
const toRemove = [];
|
|
722
|
-
for (const name of this._exposedBindingNames) (name.startsWith('__pw_') ? toRetain : toRemove).push(name);
|
|
723
|
-
this._exposedBindingNames = toRetain;
|
|
724
|
-
await Promise.all(toRemove.map(name => this._client.send('Runtime.removeBinding', {
|
|
725
|
-
name
|
|
726
|
-
})));
|
|
727
|
-
}
|
|
728
700
|
async _onBindingCalled(event) {
|
|
729
701
|
const pageOrError = await this._crPage.pageOrError();
|
|
730
702
|
if (!(pageOrError instanceof Error)) {
|
|
@@ -846,24 +818,10 @@ class FrameSession {
|
|
|
846
818
|
this._screencastClients.delete(client);
|
|
847
819
|
if (!this._screencastClients.size) await this._client._sendMayFail('Page.stopScreencast');
|
|
848
820
|
}
|
|
849
|
-
async _updateExtraHTTPHeaders(initial) {
|
|
850
|
-
const headers = network.mergeHeaders([this._crPage._browserContext._options.extraHTTPHeaders, this._page.extraHTTPHeaders()]);
|
|
851
|
-
if (!initial || headers.length) await this._client.send('Network.setExtraHTTPHeaders', {
|
|
852
|
-
headers: (0, _utils.headersArrayToObject)(headers, false /* lowerCase */)
|
|
853
|
-
});
|
|
854
|
-
}
|
|
855
821
|
async _updateGeolocation(initial) {
|
|
856
822
|
const geolocation = this._crPage._browserContext._options.geolocation;
|
|
857
823
|
if (!initial || geolocation) await this._client.send('Emulation.setGeolocationOverride', geolocation || {});
|
|
858
824
|
}
|
|
859
|
-
async _updateOffline(initial) {
|
|
860
|
-
const offline = !!this._crPage._browserContext._options.offline;
|
|
861
|
-
if (!initial || offline) await this._networkManager.setOffline(offline);
|
|
862
|
-
}
|
|
863
|
-
async _updateHttpCredentials(initial) {
|
|
864
|
-
const credentials = this._crPage._browserContext._options.httpCredentials || null;
|
|
865
|
-
if (!initial || credentials) await this._networkManager.authenticate(credentials);
|
|
866
|
-
}
|
|
867
825
|
async _updateViewport(preserveWindowBoundaries) {
|
|
868
826
|
if (this._crPage._browserContext._browser.isClank()) return;
|
|
869
827
|
(0, _utils.assert)(this._isMainFrame());
|
|
@@ -978,9 +936,6 @@ class FrameSession {
|
|
|
978
936
|
const fontFamilies = _defaultFontFamilies.platformToFontFamilies[this._crPage._browserContext._browser._platform()];
|
|
979
937
|
await session.send('Page.setFontFamilies', fontFamilies);
|
|
980
938
|
}
|
|
981
|
-
async _updateRequestInterception() {
|
|
982
|
-
await this._networkManager.setRequestInterception(this._page.needsRequestInterception());
|
|
983
|
-
}
|
|
984
939
|
async _updateFileChooserInterception(initial) {
|
|
985
940
|
const enabled = this._page.fileChooserIntercepted();
|
|
986
941
|
if (initial && !enabled) return;
|
|
@@ -988,15 +943,15 @@ class FrameSession {
|
|
|
988
943
|
enabled
|
|
989
944
|
}).catch(() => {}); // target can be closed.
|
|
990
945
|
}
|
|
991
|
-
async _evaluateOnNewDocument(
|
|
946
|
+
async _evaluateOnNewDocument(initScript, world) {
|
|
992
947
|
const worldName = world === 'utility' ? UTILITY_WORLD_NAME : undefined;
|
|
993
948
|
const {
|
|
994
949
|
identifier
|
|
995
950
|
} = await this._client.send('Page.addScriptToEvaluateOnNewDocument', {
|
|
996
|
-
source,
|
|
951
|
+
source: initScript.source,
|
|
997
952
|
worldName
|
|
998
953
|
});
|
|
999
|
-
this._evaluateOnNewDocumentIdentifiers.push(identifier);
|
|
954
|
+
if (!initScript.internal) this._evaluateOnNewDocumentIdentifiers.push(identifier);
|
|
1000
955
|
}
|
|
1001
956
|
async _removeEvaluatesOnNewDocument() {
|
|
1002
957
|
const identifiers = this._evaluateOnNewDocumentIdentifiers;
|
|
@@ -94,6 +94,7 @@ function toConsoleMessageLocation(stackTrace) {
|
|
|
94
94
|
};
|
|
95
95
|
}
|
|
96
96
|
function exceptionToError(exceptionDetails) {
|
|
97
|
+
var _exceptionDetails$exc, _nameOverride$value;
|
|
97
98
|
const messageWithStack = getExceptionMessage(exceptionDetails);
|
|
98
99
|
const lines = messageWithStack.split('\n');
|
|
99
100
|
const firstStackTraceLine = lines.findIndex(line => line.startsWith(' at'));
|
|
@@ -111,7 +112,8 @@ function exceptionToError(exceptionDetails) {
|
|
|
111
112
|
} = (0, _stackTrace.splitErrorMessage)(messageWithName);
|
|
112
113
|
const err = new Error(message);
|
|
113
114
|
err.stack = stack;
|
|
114
|
-
|
|
115
|
+
const nameOverride = (_exceptionDetails$exc = exceptionDetails.exception) === null || _exceptionDetails$exc === void 0 || (_exceptionDetails$exc = _exceptionDetails$exc.preview) === null || _exceptionDetails$exc === void 0 ? void 0 : _exceptionDetails$exc.properties.find(o => o.name === 'name');
|
|
116
|
+
err.name = nameOverride ? (_nameOverride$value = nameOverride.value) !== null && _nameOverride$value !== void 0 ? _nameOverride$value : 'Error' : name;
|
|
115
117
|
return err;
|
|
116
118
|
}
|
|
117
119
|
function toModifiersMask(modifiers) {
|
|
@@ -9,7 +9,6 @@ var _crExecutionContext = require("./crExecutionContext");
|
|
|
9
9
|
var _crNetworkManager = require("./crNetworkManager");
|
|
10
10
|
var network = _interopRequireWildcard(require("../network"));
|
|
11
11
|
var _browserContext = require("../browserContext");
|
|
12
|
-
var _utils = require("../../utils");
|
|
13
12
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
14
13
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
15
14
|
/**
|
|
@@ -34,19 +33,18 @@ class CRServiceWorker extends _page.Worker {
|
|
|
34
33
|
this._browserContext = void 0;
|
|
35
34
|
this._networkManager = void 0;
|
|
36
35
|
this._session = void 0;
|
|
37
|
-
this._extraHTTPHeaders = null;
|
|
38
36
|
this._session = session;
|
|
39
37
|
this._browserContext = browserContext;
|
|
40
|
-
if (!!process.env.PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS) this._networkManager = new _crNetworkManager.CRNetworkManager(
|
|
38
|
+
if (!!process.env.PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS) this._networkManager = new _crNetworkManager.CRNetworkManager(null, this);
|
|
41
39
|
session.once('Runtime.executionContextCreated', event => {
|
|
42
40
|
this._createExecutionContext(new _crExecutionContext.CRExecutionContext(session, event.context));
|
|
43
41
|
});
|
|
44
42
|
if (this._networkManager && this._isNetworkInspectionEnabled()) {
|
|
45
|
-
this._networkManager.initialize().catch(() => {});
|
|
46
43
|
this.updateRequestInterception();
|
|
47
|
-
this.updateExtraHTTPHeaders(
|
|
48
|
-
this.updateHttpCredentials(
|
|
49
|
-
this.updateOffline(
|
|
44
|
+
this.updateExtraHTTPHeaders();
|
|
45
|
+
this.updateHttpCredentials();
|
|
46
|
+
this.updateOffline();
|
|
47
|
+
this._networkManager.addSession(session, undefined, true /* isMain */).catch(() => {});
|
|
50
48
|
}
|
|
51
49
|
session.send('Runtime.enable', {}).catch(e => {});
|
|
52
50
|
session.send('Runtime.runIfWaitingForDebugger').catch(e => {});
|
|
@@ -56,31 +54,30 @@ class CRServiceWorker extends _page.Worker {
|
|
|
56
54
|
});
|
|
57
55
|
}
|
|
58
56
|
didClose() {
|
|
57
|
+
var _this$_networkManager;
|
|
58
|
+
(_this$_networkManager = this._networkManager) === null || _this$_networkManager === void 0 || _this$_networkManager.removeSession(this._session);
|
|
59
59
|
this._session.dispose();
|
|
60
60
|
super.didClose();
|
|
61
61
|
}
|
|
62
|
-
async updateOffline(
|
|
63
|
-
var _this$
|
|
62
|
+
async updateOffline() {
|
|
63
|
+
var _this$_networkManager2;
|
|
64
64
|
if (!this._isNetworkInspectionEnabled()) return;
|
|
65
|
-
|
|
66
|
-
if (!initial || offline) await ((_this$_networkManager = this._networkManager) === null || _this$_networkManager === void 0 ? void 0 : _this$_networkManager.setOffline(offline));
|
|
65
|
+
await ((_this$_networkManager2 = this._networkManager) === null || _this$_networkManager2 === void 0 ? void 0 : _this$_networkManager2.setOffline(!!this._browserContext._options.offline).catch(() => {}));
|
|
67
66
|
}
|
|
68
|
-
async updateHttpCredentials(
|
|
69
|
-
var _this$
|
|
67
|
+
async updateHttpCredentials() {
|
|
68
|
+
var _this$_networkManager3;
|
|
70
69
|
if (!this._isNetworkInspectionEnabled()) return;
|
|
71
|
-
|
|
72
|
-
if (!initial || credentials) await ((_this$_networkManager2 = this._networkManager) === null || _this$_networkManager2 === void 0 ? void 0 : _this$_networkManager2.authenticate(credentials));
|
|
70
|
+
await ((_this$_networkManager3 = this._networkManager) === null || _this$_networkManager3 === void 0 ? void 0 : _this$_networkManager3.authenticate(this._browserContext._options.httpCredentials || null).catch(() => {}));
|
|
73
71
|
}
|
|
74
|
-
async updateExtraHTTPHeaders(
|
|
72
|
+
async updateExtraHTTPHeaders() {
|
|
73
|
+
var _this$_networkManager4;
|
|
75
74
|
if (!this._isNetworkInspectionEnabled()) return;
|
|
76
|
-
|
|
77
|
-
if (!initial || headers.length) await this._session.send('Network.setExtraHTTPHeaders', {
|
|
78
|
-
headers: (0, _utils.headersArrayToObject)(headers, false /* lowerCase */)
|
|
79
|
-
});
|
|
75
|
+
await ((_this$_networkManager4 = this._networkManager) === null || _this$_networkManager4 === void 0 ? void 0 : _this$_networkManager4.setExtraHTTPHeaders(this._browserContext._options.extraHTTPHeaders || []).catch(() => {}));
|
|
80
76
|
}
|
|
81
|
-
updateRequestInterception() {
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
async updateRequestInterception() {
|
|
78
|
+
var _this$_networkManager5;
|
|
79
|
+
if (!this._isNetworkInspectionEnabled()) return;
|
|
80
|
+
await ((_this$_networkManager5 = this._networkManager) === null || _this$_networkManager5 === void 0 ? void 0 : _this$_networkManager5.setRequestInterception(this.needsRequestInterception()).catch(() => {}));
|
|
84
81
|
}
|
|
85
82
|
needsRequestInterception() {
|
|
86
83
|
return this._isNetworkInspectionEnabled() && !!this._browserContext._requestInterceptor;
|
|
@@ -94,7 +94,7 @@ class VideoRecorder {
|
|
|
94
94
|
|
|
95
95
|
const w = options.width;
|
|
96
96
|
const h = options.height;
|
|
97
|
-
const args = `-loglevel error -f image2pipe -avioflags direct -fpsprobesize 0 -probesize 32 -analyzeduration 0 -c:v mjpeg -i
|
|
97
|
+
const args = `-loglevel error -f image2pipe -avioflags direct -fpsprobesize 0 -probesize 32 -analyzeduration 0 -c:v mjpeg -i pipe:0 -y -an -r ${fps} -c:v vp8 -qmin 0 -qmax 50 -crf 8 -deadline realtime -speed 8 -b:v 1M -threads 1 -vf pad=${w}:${h}:0:0:gray,crop=${w}:${h}:0:0`.split(' ');
|
|
98
98
|
args.push(options.outputFile);
|
|
99
99
|
const progress = this._progress;
|
|
100
100
|
const {
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Clock = void 0;
|
|
7
|
+
var clockSource = _interopRequireWildcard(require("../generated/clockSource"));
|
|
8
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
9
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
10
|
+
/**
|
|
11
|
+
* Copyright (c) Microsoft Corporation.
|
|
12
|
+
*
|
|
13
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
14
|
+
* you may not use this file except in compliance with the License.
|
|
15
|
+
* You may obtain a copy of the License at
|
|
16
|
+
*
|
|
17
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
18
|
+
*
|
|
19
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
20
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
21
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
22
|
+
* See the License for the specific language governing permissions and
|
|
23
|
+
* limitations under the License.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
class Clock {
|
|
27
|
+
constructor(browserContext) {
|
|
28
|
+
this._browserContext = void 0;
|
|
29
|
+
this._scriptInstalled = false;
|
|
30
|
+
this._browserContext = browserContext;
|
|
31
|
+
}
|
|
32
|
+
markAsUninstalled() {
|
|
33
|
+
this._scriptInstalled = false;
|
|
34
|
+
}
|
|
35
|
+
async fastForward(ticks) {
|
|
36
|
+
await this._installIfNeeded();
|
|
37
|
+
const ticksMillis = parseTicks(ticks);
|
|
38
|
+
await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('fastForward', ${Date.now()}, ${ticksMillis})`);
|
|
39
|
+
await this._evaluateInFrames(`globalThis.__pwClock.controller.fastForward(${ticksMillis})`);
|
|
40
|
+
}
|
|
41
|
+
async install(time) {
|
|
42
|
+
await this._installIfNeeded();
|
|
43
|
+
const timeMillis = time !== undefined ? parseTime(time) : Date.now();
|
|
44
|
+
await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('install', ${Date.now()}, ${timeMillis})`);
|
|
45
|
+
await this._evaluateInFrames(`globalThis.__pwClock.controller.install(${timeMillis})`);
|
|
46
|
+
}
|
|
47
|
+
async pauseAt(ticks) {
|
|
48
|
+
await this._installIfNeeded();
|
|
49
|
+
const timeMillis = parseTime(ticks);
|
|
50
|
+
await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('pauseAt', ${Date.now()}, ${timeMillis})`);
|
|
51
|
+
await this._evaluateInFrames(`globalThis.__pwClock.controller.pauseAt(${timeMillis})`);
|
|
52
|
+
}
|
|
53
|
+
async resume() {
|
|
54
|
+
await this._installIfNeeded();
|
|
55
|
+
await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('resume', ${Date.now()})`);
|
|
56
|
+
await this._evaluateInFrames(`globalThis.__pwClock.controller.resume()`);
|
|
57
|
+
}
|
|
58
|
+
async setFixedTime(time) {
|
|
59
|
+
await this._installIfNeeded();
|
|
60
|
+
const timeMillis = parseTime(time);
|
|
61
|
+
await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('setFixedTime', ${Date.now()}, ${timeMillis})`);
|
|
62
|
+
await this._evaluateInFrames(`globalThis.__pwClock.controller.setFixedTime(${timeMillis})`);
|
|
63
|
+
}
|
|
64
|
+
async setSystemTime(time) {
|
|
65
|
+
await this._installIfNeeded();
|
|
66
|
+
const timeMillis = parseTime(time);
|
|
67
|
+
await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('setSystemTime', ${Date.now()}, ${timeMillis})`);
|
|
68
|
+
await this._evaluateInFrames(`globalThis.__pwClock.controller.setSystemTime(${timeMillis})`);
|
|
69
|
+
}
|
|
70
|
+
async runFor(ticks) {
|
|
71
|
+
await this._installIfNeeded();
|
|
72
|
+
const ticksMillis = parseTicks(ticks);
|
|
73
|
+
await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('runFor', ${Date.now()}, ${ticksMillis})`);
|
|
74
|
+
await this._evaluateInFrames(`globalThis.__pwClock.controller.runFor(${ticksMillis})`);
|
|
75
|
+
}
|
|
76
|
+
async _installIfNeeded() {
|
|
77
|
+
if (this._scriptInstalled) return;
|
|
78
|
+
this._scriptInstalled = true;
|
|
79
|
+
const script = `(() => {
|
|
80
|
+
const module = {};
|
|
81
|
+
${clockSource.source}
|
|
82
|
+
globalThis.__pwClock = (module.exports.inject())(globalThis);
|
|
83
|
+
})();`;
|
|
84
|
+
await this._browserContext.addInitScript(script);
|
|
85
|
+
await this._evaluateInFrames(script);
|
|
86
|
+
}
|
|
87
|
+
async _evaluateInFrames(script) {
|
|
88
|
+
await this._browserContext.safeNonStallingEvaluateInAllFrames(script, 'main', {
|
|
89
|
+
throwOnJSErrors: true
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Parse strings like '01:10:00' (meaning 1 hour, 10 minutes, 0 seconds) into
|
|
96
|
+
* number of milliseconds. This is used to support human-readable strings passed
|
|
97
|
+
* to clock.tick()
|
|
98
|
+
*/
|
|
99
|
+
exports.Clock = Clock;
|
|
100
|
+
function parseTicks(value) {
|
|
101
|
+
if (typeof value === 'number') return value;
|
|
102
|
+
if (!value) return 0;
|
|
103
|
+
const str = value;
|
|
104
|
+
const strings = str.split(':');
|
|
105
|
+
const l = strings.length;
|
|
106
|
+
let i = l;
|
|
107
|
+
let ms = 0;
|
|
108
|
+
let parsed;
|
|
109
|
+
if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
|
|
110
|
+
throw new Error(`Clock only understands numbers, 'mm:ss' and 'hh:mm:ss'`);
|
|
111
|
+
}
|
|
112
|
+
while (i--) {
|
|
113
|
+
parsed = parseInt(strings[i], 10);
|
|
114
|
+
if (parsed >= 60) throw new Error(`Invalid time ${str}`);
|
|
115
|
+
ms += parsed * Math.pow(60, l - i - 1);
|
|
116
|
+
}
|
|
117
|
+
return ms * 1000;
|
|
118
|
+
}
|
|
119
|
+
function parseTime(epoch) {
|
|
120
|
+
if (!epoch) return 0;
|
|
121
|
+
if (typeof epoch === 'number') return epoch;
|
|
122
|
+
const parsed = new Date(epoch);
|
|
123
|
+
if (!isFinite(parsed.getTime())) throw new Error(`Invalid date: ${epoch}`);
|
|
124
|
+
return parsed.getTime();
|
|
125
|
+
}
|