@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.
- 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-C-fQ5QZD.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-D-5S5PPN.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-CqYUz5ms.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-DrQjKdyE.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.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.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.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.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.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.DyTpxWVb.css +1 -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-W69B4LBB.js +0 -24
- package/lib/vite/recorder/assets/index-Ly3PcVUb.js +0 -47
- package/lib/vite/recorder/assets/index-ljsTwXtJ.css +0 -1
- package/lib/vite/traceViewer/assets/codeMirrorModule-0bpaqixv.js +0 -24
- package/lib/vite/traceViewer/assets/codeMirrorModule-wLpsbIhd.js +0 -24
- package/lib/vite/traceViewer/assets/wsPort-_JBDEilC.js +0 -69
- package/lib/vite/traceViewer/assets/wsPort-f2dAQL4I.js +0 -69
- package/lib/vite/traceViewer/index.-_8-eHEE.js +0 -2
- package/lib/vite/traceViewer/index.u51inEcm.js +0 -2
- package/lib/vite/traceViewer/uiMode.9CwNsWc6.js +0 -10
- 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
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ContextRecorder = void 0;
|
|
7
|
+
exports.generateFrameSelector = generateFrameSelector;
|
|
8
|
+
var _events = require("events");
|
|
9
|
+
var recorderSource = _interopRequireWildcard(require("../../generated/recorderSource"));
|
|
10
|
+
var _utils = require("../../utils");
|
|
11
|
+
var _timeoutRunner = require("../../utils/timeoutRunner");
|
|
12
|
+
var _browserContext = require("../browserContext");
|
|
13
|
+
var _languages = require("../codegen/languages");
|
|
14
|
+
var _frames = require("../frames");
|
|
15
|
+
var _page = require("../page");
|
|
16
|
+
var _recorderRunner = require("./recorderRunner");
|
|
17
|
+
var _throttledFile = require("./throttledFile");
|
|
18
|
+
var _recorderCollection = require("./recorderCollection");
|
|
19
|
+
var _language = require("../codegen/language");
|
|
20
|
+
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); }
|
|
21
|
+
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; }
|
|
22
|
+
/**
|
|
23
|
+
* Copyright (c) Microsoft Corporation.
|
|
24
|
+
*
|
|
25
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
26
|
+
* you may not use this file except in compliance with the License.
|
|
27
|
+
* You may obtain a copy of the License at
|
|
28
|
+
*
|
|
29
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
30
|
+
*
|
|
31
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
32
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
33
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
34
|
+
* See the License for the specific language governing permissions and
|
|
35
|
+
* limitations under the License.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
class ContextRecorder extends _events.EventEmitter {
|
|
39
|
+
constructor(context, params, delegate) {
|
|
40
|
+
super();
|
|
41
|
+
this._collection = void 0;
|
|
42
|
+
this._pageAliases = new Map();
|
|
43
|
+
this._lastPopupOrdinal = 0;
|
|
44
|
+
this._lastDialogOrdinal = -1;
|
|
45
|
+
this._lastDownloadOrdinal = -1;
|
|
46
|
+
this._timers = new Set();
|
|
47
|
+
this._context = void 0;
|
|
48
|
+
this._params = void 0;
|
|
49
|
+
this._delegate = void 0;
|
|
50
|
+
this._recorderSources = void 0;
|
|
51
|
+
this._throttledOutputFile = null;
|
|
52
|
+
this._orderedLanguages = [];
|
|
53
|
+
this._listeners = [];
|
|
54
|
+
this._context = context;
|
|
55
|
+
this._params = params;
|
|
56
|
+
this._delegate = delegate;
|
|
57
|
+
this._recorderSources = [];
|
|
58
|
+
const language = params.language || context.attribution.playwright.options.sdkLanguage;
|
|
59
|
+
this.setOutput(language, params.outputFile);
|
|
60
|
+
|
|
61
|
+
// Make a copy of options to modify them later.
|
|
62
|
+
const languageGeneratorOptions = {
|
|
63
|
+
browserName: context._browser.options.name,
|
|
64
|
+
launchOptions: {
|
|
65
|
+
headless: false,
|
|
66
|
+
...params.launchOptions
|
|
67
|
+
},
|
|
68
|
+
contextOptions: {
|
|
69
|
+
...params.contextOptions
|
|
70
|
+
},
|
|
71
|
+
deviceName: params.device,
|
|
72
|
+
saveStorage: params.saveStorage
|
|
73
|
+
};
|
|
74
|
+
const collection = new _recorderCollection.RecorderCollection(params.mode === 'recording');
|
|
75
|
+
collection.on('change', () => {
|
|
76
|
+
this._recorderSources = [];
|
|
77
|
+
for (const languageGenerator of this._orderedLanguages) {
|
|
78
|
+
var _this$_throttledOutpu;
|
|
79
|
+
const {
|
|
80
|
+
header,
|
|
81
|
+
footer,
|
|
82
|
+
actionTexts,
|
|
83
|
+
text
|
|
84
|
+
} = (0, _language.generateCode)(collection.actions(), languageGenerator, languageGeneratorOptions);
|
|
85
|
+
const source = {
|
|
86
|
+
isRecorded: true,
|
|
87
|
+
label: languageGenerator.name,
|
|
88
|
+
group: languageGenerator.groupName,
|
|
89
|
+
id: languageGenerator.id,
|
|
90
|
+
text,
|
|
91
|
+
header,
|
|
92
|
+
footer,
|
|
93
|
+
actions: actionTexts,
|
|
94
|
+
language: languageGenerator.highlighter,
|
|
95
|
+
highlight: []
|
|
96
|
+
};
|
|
97
|
+
source.revealLine = text.split('\n').length - 1;
|
|
98
|
+
this._recorderSources.push(source);
|
|
99
|
+
if (languageGenerator === this._orderedLanguages[0]) (_this$_throttledOutpu = this._throttledOutputFile) === null || _this$_throttledOutpu === void 0 || _this$_throttledOutpu.setContent(source.text);
|
|
100
|
+
}
|
|
101
|
+
this.emit(ContextRecorder.Events.Change, {
|
|
102
|
+
sources: this._recorderSources,
|
|
103
|
+
primaryFileName: this._orderedLanguages[0].id
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
context.on(_browserContext.BrowserContext.Events.BeforeClose, () => {
|
|
107
|
+
var _this$_throttledOutpu2;
|
|
108
|
+
(_this$_throttledOutpu2 = this._throttledOutputFile) === null || _this$_throttledOutpu2 === void 0 || _this$_throttledOutpu2.flush();
|
|
109
|
+
});
|
|
110
|
+
this._listeners.push(_utils.eventsHelper.addEventListener(process, 'exit', () => {
|
|
111
|
+
var _this$_throttledOutpu3;
|
|
112
|
+
(_this$_throttledOutpu3 = this._throttledOutputFile) === null || _this$_throttledOutpu3 === void 0 || _this$_throttledOutpu3.flush();
|
|
113
|
+
}));
|
|
114
|
+
this._collection = collection;
|
|
115
|
+
}
|
|
116
|
+
setOutput(codegenId, outputFile) {
|
|
117
|
+
var _this$_collection;
|
|
118
|
+
const languages = (0, _languages.languageSet)();
|
|
119
|
+
const primaryLanguage = [...languages].find(l => l.id === codegenId);
|
|
120
|
+
if (!primaryLanguage) throw new Error(`\n===============================\nUnsupported language: '${codegenId}'\n===============================\n`);
|
|
121
|
+
languages.delete(primaryLanguage);
|
|
122
|
+
this._orderedLanguages = [primaryLanguage, ...languages];
|
|
123
|
+
this._throttledOutputFile = outputFile ? new _throttledFile.ThrottledFile(outputFile) : null;
|
|
124
|
+
(_this$_collection = this._collection) === null || _this$_collection === void 0 || _this$_collection.restart();
|
|
125
|
+
}
|
|
126
|
+
languageName(id) {
|
|
127
|
+
for (const lang of this._orderedLanguages) {
|
|
128
|
+
if (!id || lang.id === id) return lang.highlighter;
|
|
129
|
+
}
|
|
130
|
+
return 'javascript';
|
|
131
|
+
}
|
|
132
|
+
async install() {
|
|
133
|
+
this._context.on(_browserContext.BrowserContext.Events.Page, page => this._onPage(page));
|
|
134
|
+
for (const page of this._context.pages()) this._onPage(page);
|
|
135
|
+
this._context.on(_browserContext.BrowserContext.Events.Dialog, dialog => this._onDialog(dialog.page()));
|
|
136
|
+
|
|
137
|
+
// Input actions that potentially lead to navigation are intercepted on the page and are
|
|
138
|
+
// performed by the Playwright.
|
|
139
|
+
await this._context.exposeBinding('__pw_recorderPerformAction', false, (source, action) => this._performAction(source.frame, action));
|
|
140
|
+
|
|
141
|
+
// Other non-essential actions are simply being recorded.
|
|
142
|
+
await this._context.exposeBinding('__pw_recorderRecordAction', false, (source, action) => this._recordAction(source.frame, action));
|
|
143
|
+
await this._context.extendInjectedScript(recorderSource.source);
|
|
144
|
+
}
|
|
145
|
+
setEnabled(enabled) {
|
|
146
|
+
this._collection.setEnabled(enabled);
|
|
147
|
+
}
|
|
148
|
+
dispose() {
|
|
149
|
+
for (const timer of this._timers) clearTimeout(timer);
|
|
150
|
+
this._timers.clear();
|
|
151
|
+
_utils.eventsHelper.removeEventListeners(this._listeners);
|
|
152
|
+
}
|
|
153
|
+
async _onPage(page) {
|
|
154
|
+
// First page is called page, others are called popup1, popup2, etc.
|
|
155
|
+
const frame = page.mainFrame();
|
|
156
|
+
page.on('close', () => {
|
|
157
|
+
this._collection.addAction({
|
|
158
|
+
frame: this._describeMainFrame(page),
|
|
159
|
+
committed: true,
|
|
160
|
+
action: {
|
|
161
|
+
name: 'closePage',
|
|
162
|
+
signals: []
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
this._pageAliases.delete(page);
|
|
166
|
+
});
|
|
167
|
+
frame.on(_frames.Frame.Events.InternalNavigation, event => {
|
|
168
|
+
if (event.isPublic) this._onFrameNavigated(frame, page);
|
|
169
|
+
});
|
|
170
|
+
page.on(_page.Page.Events.Download, () => this._onDownload(page));
|
|
171
|
+
const suffix = this._pageAliases.size ? String(++this._lastPopupOrdinal) : '';
|
|
172
|
+
const pageAlias = 'page' + suffix;
|
|
173
|
+
this._pageAliases.set(page, pageAlias);
|
|
174
|
+
if (page.opener()) {
|
|
175
|
+
this._onPopup(page.opener(), page);
|
|
176
|
+
} else {
|
|
177
|
+
this._collection.addAction({
|
|
178
|
+
frame: this._describeMainFrame(page),
|
|
179
|
+
committed: true,
|
|
180
|
+
action: {
|
|
181
|
+
name: 'openPage',
|
|
182
|
+
url: page.mainFrame().url(),
|
|
183
|
+
signals: []
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
clearScript() {
|
|
189
|
+
this._collection.restart();
|
|
190
|
+
if (this._params.mode === 'recording') {
|
|
191
|
+
for (const page of this._context.pages()) this._onFrameNavigated(page.mainFrame(), page);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
_describeMainFrame(page) {
|
|
195
|
+
return {
|
|
196
|
+
pageAlias: this._pageAliases.get(page),
|
|
197
|
+
framePath: []
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
async _describeFrame(frame) {
|
|
201
|
+
return {
|
|
202
|
+
pageAlias: this._pageAliases.get(frame._page),
|
|
203
|
+
framePath: await generateFrameSelector(frame)
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
testIdAttributeName() {
|
|
207
|
+
return this._params.testIdAttributeName || this._context.selectors().testIdAttributeName() || 'data-testid';
|
|
208
|
+
}
|
|
209
|
+
async _performAction(frame, action) {
|
|
210
|
+
var _this$_delegate$rewri, _this$_delegate;
|
|
211
|
+
// Commit last action so that no further signals are added to it.
|
|
212
|
+
this._collection.commitLastAction();
|
|
213
|
+
const frameDescription = await this._describeFrame(frame);
|
|
214
|
+
const actionInContext = {
|
|
215
|
+
frame: frameDescription,
|
|
216
|
+
action,
|
|
217
|
+
description: undefined
|
|
218
|
+
};
|
|
219
|
+
await ((_this$_delegate$rewri = (_this$_delegate = this._delegate).rewriteActionInContext) === null || _this$_delegate$rewri === void 0 ? void 0 : _this$_delegate$rewri.call(_this$_delegate, this._pageAliases, actionInContext));
|
|
220
|
+
this._collection.willPerformAction(actionInContext);
|
|
221
|
+
const success = await (0, _recorderRunner.performAction)(this._pageAliases, actionInContext);
|
|
222
|
+
if (success) {
|
|
223
|
+
this._collection.didPerformAction(actionInContext);
|
|
224
|
+
this._setCommittedAfterTimeout(actionInContext);
|
|
225
|
+
} else {
|
|
226
|
+
this._collection.performedActionFailed(actionInContext);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
async _recordAction(frame, action) {
|
|
230
|
+
var _this$_delegate$rewri2, _this$_delegate2;
|
|
231
|
+
// Commit last action so that no further signals are added to it.
|
|
232
|
+
this._collection.commitLastAction();
|
|
233
|
+
const frameDescription = await this._describeFrame(frame);
|
|
234
|
+
const actionInContext = {
|
|
235
|
+
frame: frameDescription,
|
|
236
|
+
action,
|
|
237
|
+
description: undefined
|
|
238
|
+
};
|
|
239
|
+
await ((_this$_delegate$rewri2 = (_this$_delegate2 = this._delegate).rewriteActionInContext) === null || _this$_delegate$rewri2 === void 0 ? void 0 : _this$_delegate$rewri2.call(_this$_delegate2, this._pageAliases, actionInContext));
|
|
240
|
+
this._setCommittedAfterTimeout(actionInContext);
|
|
241
|
+
this._collection.addAction(actionInContext);
|
|
242
|
+
}
|
|
243
|
+
_setCommittedAfterTimeout(actionInContext) {
|
|
244
|
+
const timer = setTimeout(() => {
|
|
245
|
+
// Commit the action after 5 seconds so that no further signals are added to it.
|
|
246
|
+
actionInContext.committed = true;
|
|
247
|
+
this._timers.delete(timer);
|
|
248
|
+
}, (0, _utils.isUnderTest)() ? 500 : 5000);
|
|
249
|
+
this._timers.add(timer);
|
|
250
|
+
}
|
|
251
|
+
_onFrameNavigated(frame, page) {
|
|
252
|
+
const pageAlias = this._pageAliases.get(page);
|
|
253
|
+
this._collection.signal(pageAlias, frame, {
|
|
254
|
+
name: 'navigation',
|
|
255
|
+
url: frame.url()
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
_onPopup(page, popup) {
|
|
259
|
+
const pageAlias = this._pageAliases.get(page);
|
|
260
|
+
const popupAlias = this._pageAliases.get(popup);
|
|
261
|
+
this._collection.signal(pageAlias, page.mainFrame(), {
|
|
262
|
+
name: 'popup',
|
|
263
|
+
popupAlias
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
_onDownload(page) {
|
|
267
|
+
const pageAlias = this._pageAliases.get(page);
|
|
268
|
+
++this._lastDownloadOrdinal;
|
|
269
|
+
this._collection.signal(pageAlias, page.mainFrame(), {
|
|
270
|
+
name: 'download',
|
|
271
|
+
downloadAlias: this._lastDownloadOrdinal ? String(this._lastDownloadOrdinal) : ''
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
_onDialog(page) {
|
|
275
|
+
const pageAlias = this._pageAliases.get(page);
|
|
276
|
+
++this._lastDialogOrdinal;
|
|
277
|
+
this._collection.signal(pageAlias, page.mainFrame(), {
|
|
278
|
+
name: 'dialog',
|
|
279
|
+
dialogAlias: this._lastDialogOrdinal ? String(this._lastDialogOrdinal) : ''
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
exports.ContextRecorder = ContextRecorder;
|
|
284
|
+
ContextRecorder.Events = {
|
|
285
|
+
Change: 'change'
|
|
286
|
+
};
|
|
287
|
+
async function generateFrameSelector(frame) {
|
|
288
|
+
const selectorPromises = [];
|
|
289
|
+
while (frame) {
|
|
290
|
+
const parent = frame.parentFrame();
|
|
291
|
+
if (!parent) break;
|
|
292
|
+
selectorPromises.push(generateFrameSelectorInParent(parent, frame));
|
|
293
|
+
frame = parent;
|
|
294
|
+
}
|
|
295
|
+
const result = await Promise.all(selectorPromises);
|
|
296
|
+
return result.reverse();
|
|
297
|
+
}
|
|
298
|
+
async function generateFrameSelectorInParent(parent, frame) {
|
|
299
|
+
const result = await (0, _timeoutRunner.raceAgainstDeadline)(async () => {
|
|
300
|
+
try {
|
|
301
|
+
const frameElement = await frame.frameElement();
|
|
302
|
+
if (!frameElement || !parent) return;
|
|
303
|
+
const utility = await parent._utilityContext();
|
|
304
|
+
const injected = await utility.injectedScript();
|
|
305
|
+
const selector = await injected.evaluate((injected, element) => {
|
|
306
|
+
return injected.generateSelectorSimple(element);
|
|
307
|
+
}, frameElement);
|
|
308
|
+
return selector;
|
|
309
|
+
} catch (e) {
|
|
310
|
+
return e.toString();
|
|
311
|
+
}
|
|
312
|
+
}, (0, _utils.monotonicTime)() + 2000);
|
|
313
|
+
if (!result.timedOut && result.result) return result.result;
|
|
314
|
+
if (frame.name()) return `iframe[name=${(0, _utils.quoteCSSAttributeValue)(frame.name())}]`;
|
|
315
|
+
return `iframe[src=${(0, _utils.quoteCSSAttributeValue)(frame.url())}]`;
|
|
316
|
+
}
|
|
@@ -85,7 +85,13 @@ class RecorderApp extends _events.EventEmitter {
|
|
|
85
85
|
const mainFrame = this._page.mainFrame();
|
|
86
86
|
await mainFrame.goto((0, _instrumentation.serverSideCallMetadata)(), 'https://playwright/index.html');
|
|
87
87
|
}
|
|
88
|
-
static
|
|
88
|
+
static factory(context) {
|
|
89
|
+
return async recorder => {
|
|
90
|
+
if (process.env.PW_CODEGEN_NO_INSPECTOR) return new EmptyRecorderApp();
|
|
91
|
+
return await RecorderApp._open(recorder, context);
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
static async _open(recorder, inspectedContext) {
|
|
89
95
|
const sdkLanguage = inspectedContext.attribution.playwright.options.sdkLanguage;
|
|
90
96
|
const headed = !!inspectedContext._browser.options.headful;
|
|
91
97
|
const recorderPlaywright = require('../playwright').createPlaywright({
|
|
@@ -109,8 +115,9 @@ class RecorderApp extends _events.EventEmitter {
|
|
|
109
115
|
noDefaultViewport: true,
|
|
110
116
|
headless: !!process.env.PWTEST_CLI_HEADLESS || (0, _utils.isUnderTest)() && !headed,
|
|
111
117
|
useWebSocket: !!process.env.PWTEST_RECORDER_PORT,
|
|
112
|
-
handleSIGINT,
|
|
113
|
-
args: process.env.PWTEST_RECORDER_PORT ? [`--remote-debugging-port=${process.env.PWTEST_RECORDER_PORT}`] : []
|
|
118
|
+
handleSIGINT: false,
|
|
119
|
+
args: process.env.PWTEST_RECORDER_PORT ? [`--remote-debugging-port=${process.env.PWTEST_RECORDER_PORT}`] : [],
|
|
120
|
+
executablePath: inspectedContext._browser.options.isChromium ? inspectedContext._browser.options.customExecutablePath : undefined
|
|
114
121
|
}
|
|
115
122
|
});
|
|
116
123
|
const controller = new _progress.ProgressController((0, _instrumentation.serverSideCallMetadata)(), context._browser);
|
|
@@ -154,11 +161,13 @@ class RecorderApp extends _events.EventEmitter {
|
|
|
154
161
|
}
|
|
155
162
|
async setSelector(selector, userGesture) {
|
|
156
163
|
if (userGesture) {
|
|
157
|
-
|
|
164
|
+
var _this$_recorder;
|
|
165
|
+
if (((_this$_recorder = this._recorder) === null || _this$_recorder === void 0 ? void 0 : _this$_recorder.mode()) === 'inspecting') {
|
|
158
166
|
this._recorder.setMode('standby');
|
|
159
167
|
this._page.bringToFront();
|
|
160
168
|
} else {
|
|
161
|
-
|
|
169
|
+
var _this$_recorder2;
|
|
170
|
+
(_this$_recorder2 = this._recorder) === null || _this$_recorder2 === void 0 || _this$_recorder2.setMode('recording');
|
|
162
171
|
}
|
|
163
172
|
}
|
|
164
173
|
await this._page.mainFrame().evaluateExpression((data => {
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.RecorderCollection = void 0;
|
|
7
|
+
var _events = require("events");
|
|
8
|
+
/**
|
|
9
|
+
* Copyright (c) Microsoft Corporation.
|
|
10
|
+
*
|
|
11
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
12
|
+
* you may not use this file except in compliance with the License.
|
|
13
|
+
* You may obtain a copy of the License at
|
|
14
|
+
*
|
|
15
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
16
|
+
*
|
|
17
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
18
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
19
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
20
|
+
* See the License for the specific language governing permissions and
|
|
21
|
+
* limitations under the License.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
class RecorderCollection extends _events.EventEmitter {
|
|
25
|
+
constructor(enabled) {
|
|
26
|
+
super();
|
|
27
|
+
this._currentAction = null;
|
|
28
|
+
this._lastAction = null;
|
|
29
|
+
this._actions = [];
|
|
30
|
+
this._enabled = void 0;
|
|
31
|
+
this._enabled = enabled;
|
|
32
|
+
this.restart();
|
|
33
|
+
}
|
|
34
|
+
restart() {
|
|
35
|
+
this._currentAction = null;
|
|
36
|
+
this._lastAction = null;
|
|
37
|
+
this._actions = [];
|
|
38
|
+
this.emit('change');
|
|
39
|
+
}
|
|
40
|
+
actions() {
|
|
41
|
+
return this._actions;
|
|
42
|
+
}
|
|
43
|
+
setEnabled(enabled) {
|
|
44
|
+
this._enabled = enabled;
|
|
45
|
+
}
|
|
46
|
+
addAction(action) {
|
|
47
|
+
if (!this._enabled) return;
|
|
48
|
+
this.willPerformAction(action);
|
|
49
|
+
this.didPerformAction(action);
|
|
50
|
+
}
|
|
51
|
+
willPerformAction(action) {
|
|
52
|
+
if (!this._enabled) return;
|
|
53
|
+
this._currentAction = action;
|
|
54
|
+
}
|
|
55
|
+
performedActionFailed(action) {
|
|
56
|
+
if (!this._enabled) return;
|
|
57
|
+
if (this._currentAction === action) this._currentAction = null;
|
|
58
|
+
}
|
|
59
|
+
didPerformAction(actionInContext) {
|
|
60
|
+
if (!this._enabled) return;
|
|
61
|
+
const action = actionInContext.action;
|
|
62
|
+
let eraseLastAction = false;
|
|
63
|
+
if (this._lastAction && this._lastAction.frame.pageAlias === actionInContext.frame.pageAlias) {
|
|
64
|
+
const lastAction = this._lastAction.action;
|
|
65
|
+
// We augment last action based on the type.
|
|
66
|
+
if (this._lastAction && action.name === 'fill' && lastAction.name === 'fill') {
|
|
67
|
+
if (action.selector === lastAction.selector) eraseLastAction = true;
|
|
68
|
+
}
|
|
69
|
+
if (lastAction && action.name === 'click' && lastAction.name === 'click') {
|
|
70
|
+
if (action.selector === lastAction.selector && action.clickCount > lastAction.clickCount) eraseLastAction = true;
|
|
71
|
+
}
|
|
72
|
+
if (lastAction && action.name === 'navigate' && lastAction.name === 'navigate') {
|
|
73
|
+
if (action.url === lastAction.url) {
|
|
74
|
+
// Already at a target URL.
|
|
75
|
+
this._currentAction = null;
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Check and uncheck erase click.
|
|
80
|
+
if (lastAction && (action.name === 'check' || action.name === 'uncheck') && lastAction.name === 'click') {
|
|
81
|
+
if (action.selector === lastAction.selector) eraseLastAction = true;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
this._lastAction = actionInContext;
|
|
85
|
+
this._currentAction = null;
|
|
86
|
+
if (eraseLastAction) this._actions.pop();
|
|
87
|
+
this._actions.push(actionInContext);
|
|
88
|
+
this.emit('change');
|
|
89
|
+
}
|
|
90
|
+
commitLastAction() {
|
|
91
|
+
if (!this._enabled) return;
|
|
92
|
+
const action = this._lastAction;
|
|
93
|
+
if (action) action.committed = true;
|
|
94
|
+
}
|
|
95
|
+
signal(pageAlias, frame, signal) {
|
|
96
|
+
if (!this._enabled) return;
|
|
97
|
+
|
|
98
|
+
// Signal either arrives while action is being performed or shortly after.
|
|
99
|
+
if (this._currentAction) {
|
|
100
|
+
this._currentAction.action.signals.push(signal);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (this._lastAction && (!this._lastAction.committed || signal.name !== 'navigation')) {
|
|
104
|
+
const signals = this._lastAction.action.signals;
|
|
105
|
+
if (signal.name === 'navigation' && signals.length && signals[signals.length - 1].name === 'download') return;
|
|
106
|
+
if (signal.name === 'download' && signals.length && signals[signals.length - 1].name === 'navigation') signals.length = signals.length - 1;
|
|
107
|
+
this._lastAction.action.signals.push(signal);
|
|
108
|
+
this.emit('change');
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (signal.name === 'navigation' && frame._page.mainFrame() === frame) {
|
|
112
|
+
this.addAction({
|
|
113
|
+
frame: {
|
|
114
|
+
pageAlias,
|
|
115
|
+
framePath: []
|
|
116
|
+
},
|
|
117
|
+
committed: true,
|
|
118
|
+
action: {
|
|
119
|
+
name: 'navigate',
|
|
120
|
+
url: frame.url(),
|
|
121
|
+
signals: []
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
exports.RecorderCollection = RecorderCollection;
|