phantomwright-driver-core 1.57.0
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/README.md +3 -0
- package/ThirdPartyNotices.txt +1161 -0
- package/bin/install_media_pack.ps1 +5 -0
- package/bin/install_webkit_wsl.ps1 +33 -0
- package/bin/reinstall_chrome_beta_linux.sh +42 -0
- package/bin/reinstall_chrome_beta_mac.sh +13 -0
- package/bin/reinstall_chrome_beta_win.ps1 +24 -0
- package/bin/reinstall_chrome_stable_linux.sh +42 -0
- package/bin/reinstall_chrome_stable_mac.sh +12 -0
- package/bin/reinstall_chrome_stable_win.ps1 +24 -0
- package/bin/reinstall_msedge_beta_linux.sh +48 -0
- package/bin/reinstall_msedge_beta_mac.sh +11 -0
- package/bin/reinstall_msedge_beta_win.ps1 +23 -0
- package/bin/reinstall_msedge_dev_linux.sh +48 -0
- package/bin/reinstall_msedge_dev_mac.sh +11 -0
- package/bin/reinstall_msedge_dev_win.ps1 +23 -0
- package/bin/reinstall_msedge_stable_linux.sh +48 -0
- package/bin/reinstall_msedge_stable_mac.sh +11 -0
- package/bin/reinstall_msedge_stable_win.ps1 +24 -0
- package/browsers.json +80 -0
- package/cli.js +18 -0
- package/index.d.ts +17 -0
- package/index.js +32 -0
- package/index.mjs +28 -0
- package/lib/androidServerImpl.js +65 -0
- package/lib/browserServerImpl.js +120 -0
- package/lib/cli/driver.js +97 -0
- package/lib/cli/program.js +590 -0
- package/lib/cli/programWithTestStub.js +74 -0
- package/lib/client/android.js +361 -0
- package/lib/client/api.js +134 -0
- package/lib/client/artifact.js +79 -0
- package/lib/client/browser.js +163 -0
- package/lib/client/browserContext.js +547 -0
- package/lib/client/browserType.js +184 -0
- package/lib/client/cdpSession.js +51 -0
- package/lib/client/channelOwner.js +194 -0
- package/lib/client/clientHelper.js +64 -0
- package/lib/client/clientInstrumentation.js +55 -0
- package/lib/client/clientStackTrace.js +69 -0
- package/lib/client/clock.js +68 -0
- package/lib/client/connection.js +314 -0
- package/lib/client/consoleMessage.js +58 -0
- package/lib/client/coverage.js +44 -0
- package/lib/client/dialog.js +56 -0
- package/lib/client/download.js +62 -0
- package/lib/client/electron.js +138 -0
- package/lib/client/elementHandle.js +281 -0
- package/lib/client/errors.js +77 -0
- package/lib/client/eventEmitter.js +314 -0
- package/lib/client/events.js +100 -0
- package/lib/client/fetch.js +369 -0
- package/lib/client/fileChooser.js +46 -0
- package/lib/client/fileUtils.js +34 -0
- package/lib/client/frame.js +408 -0
- package/lib/client/harRouter.js +87 -0
- package/lib/client/input.js +84 -0
- package/lib/client/jsHandle.js +109 -0
- package/lib/client/jsonPipe.js +39 -0
- package/lib/client/localUtils.js +60 -0
- package/lib/client/locator.js +369 -0
- package/lib/client/network.js +747 -0
- package/lib/client/page.js +718 -0
- package/lib/client/platform.js +74 -0
- package/lib/client/playwright.js +71 -0
- package/lib/client/selectors.js +55 -0
- package/lib/client/stream.js +39 -0
- package/lib/client/timeoutSettings.js +79 -0
- package/lib/client/tracing.js +119 -0
- package/lib/client/types.js +28 -0
- package/lib/client/video.js +59 -0
- package/lib/client/waiter.js +142 -0
- package/lib/client/webError.js +39 -0
- package/lib/client/webSocket.js +93 -0
- package/lib/client/worker.js +85 -0
- package/lib/client/writableStream.js +39 -0
- package/lib/generated/bindingsControllerSource.js +28 -0
- package/lib/generated/clockSource.js +28 -0
- package/lib/generated/injectedScriptSource.js +28 -0
- package/lib/generated/pollingRecorderSource.js +28 -0
- package/lib/generated/storageScriptSource.js +28 -0
- package/lib/generated/utilityScriptSource.js +28 -0
- package/lib/generated/webSocketMockSource.js +336 -0
- package/lib/inProcessFactory.js +60 -0
- package/lib/inprocess.js +3 -0
- package/lib/outofprocess.js +76 -0
- package/lib/protocol/serializers.js +192 -0
- package/lib/protocol/validator.js +2890 -0
- package/lib/protocol/validatorPrimitives.js +193 -0
- package/lib/remote/playwrightConnection.js +129 -0
- package/lib/remote/playwrightServer.js +335 -0
- package/lib/server/android/android.js +465 -0
- package/lib/server/android/backendAdb.js +177 -0
- package/lib/server/artifact.js +127 -0
- package/lib/server/bidi/bidiBrowser.js +505 -0
- package/lib/server/bidi/bidiChromium.js +153 -0
- package/lib/server/bidi/bidiConnection.js +212 -0
- package/lib/server/bidi/bidiExecutionContext.js +221 -0
- package/lib/server/bidi/bidiFirefox.js +130 -0
- package/lib/server/bidi/bidiInput.js +146 -0
- package/lib/server/bidi/bidiNetworkManager.js +383 -0
- package/lib/server/bidi/bidiOverCdp.js +102 -0
- package/lib/server/bidi/bidiPage.js +572 -0
- package/lib/server/bidi/bidiPdf.js +106 -0
- package/lib/server/bidi/third_party/bidiCommands.d.js +22 -0
- package/lib/server/bidi/third_party/bidiDeserializer.js +98 -0
- package/lib/server/bidi/third_party/bidiKeyboard.js +256 -0
- package/lib/server/bidi/third_party/bidiProtocol.js +24 -0
- package/lib/server/bidi/third_party/bidiProtocolCore.js +179 -0
- package/lib/server/bidi/third_party/bidiProtocolPermissions.js +42 -0
- package/lib/server/bidi/third_party/bidiSerializer.js +148 -0
- package/lib/server/bidi/third_party/firefoxPrefs.js +259 -0
- package/lib/server/browser.js +149 -0
- package/lib/server/browserContext.js +695 -0
- package/lib/server/browserType.js +328 -0
- package/lib/server/callLog.js +82 -0
- package/lib/server/chromium/appIcon.png +0 -0
- package/lib/server/chromium/chromium.js +402 -0
- package/lib/server/chromium/chromiumSwitches.js +104 -0
- package/lib/server/chromium/crBrowser.js +510 -0
- package/lib/server/chromium/crConnection.js +202 -0
- package/lib/server/chromium/crCoverage.js +235 -0
- package/lib/server/chromium/crDevTools.js +113 -0
- package/lib/server/chromium/crDragDrop.js +131 -0
- package/lib/server/chromium/crExecutionContext.js +146 -0
- package/lib/server/chromium/crInput.js +187 -0
- package/lib/server/chromium/crNetworkManager.js +666 -0
- package/lib/server/chromium/crPage.js +1069 -0
- package/lib/server/chromium/crPdf.js +121 -0
- package/lib/server/chromium/crProtocolHelper.js +145 -0
- package/lib/server/chromium/crServiceWorker.js +136 -0
- package/lib/server/chromium/defaultFontFamilies.js +162 -0
- package/lib/server/chromium/protocol.d.js +16 -0
- package/lib/server/chromium/videoRecorder.js +115 -0
- package/lib/server/clock.js +149 -0
- package/lib/server/codegen/csharp.js +327 -0
- package/lib/server/codegen/java.js +274 -0
- package/lib/server/codegen/javascript.js +270 -0
- package/lib/server/codegen/jsonl.js +52 -0
- package/lib/server/codegen/language.js +132 -0
- package/lib/server/codegen/languages.js +68 -0
- package/lib/server/codegen/python.js +279 -0
- package/lib/server/codegen/types.js +16 -0
- package/lib/server/console.js +57 -0
- package/lib/server/cookieStore.js +206 -0
- package/lib/server/debugController.js +191 -0
- package/lib/server/debugger.js +119 -0
- package/lib/server/deviceDescriptors.js +39 -0
- package/lib/server/deviceDescriptorsSource.json +1779 -0
- package/lib/server/dialog.js +116 -0
- package/lib/server/dispatchers/androidDispatcher.js +325 -0
- package/lib/server/dispatchers/artifactDispatcher.js +118 -0
- package/lib/server/dispatchers/browserContextDispatcher.js +381 -0
- package/lib/server/dispatchers/browserDispatcher.js +118 -0
- package/lib/server/dispatchers/browserTypeDispatcher.js +64 -0
- package/lib/server/dispatchers/cdpSessionDispatcher.js +44 -0
- package/lib/server/dispatchers/debugControllerDispatcher.js +78 -0
- package/lib/server/dispatchers/dialogDispatcher.js +47 -0
- package/lib/server/dispatchers/dispatcher.js +371 -0
- package/lib/server/dispatchers/electronDispatcher.js +89 -0
- package/lib/server/dispatchers/elementHandlerDispatcher.js +181 -0
- package/lib/server/dispatchers/frameDispatcher.js +227 -0
- package/lib/server/dispatchers/jsHandleDispatcher.js +85 -0
- package/lib/server/dispatchers/jsonPipeDispatcher.js +58 -0
- package/lib/server/dispatchers/localUtilsDispatcher.js +149 -0
- package/lib/server/dispatchers/networkDispatchers.js +213 -0
- package/lib/server/dispatchers/pageDispatcher.js +389 -0
- package/lib/server/dispatchers/playwrightDispatcher.js +108 -0
- package/lib/server/dispatchers/streamDispatcher.js +67 -0
- package/lib/server/dispatchers/tracingDispatcher.js +68 -0
- package/lib/server/dispatchers/webSocketRouteDispatcher.js +165 -0
- package/lib/server/dispatchers/writableStreamDispatcher.js +79 -0
- package/lib/server/dom.js +806 -0
- package/lib/server/download.js +70 -0
- package/lib/server/electron/electron.js +270 -0
- package/lib/server/electron/loader.js +29 -0
- package/lib/server/errors.js +69 -0
- package/lib/server/fetch.js +621 -0
- package/lib/server/fileChooser.js +43 -0
- package/lib/server/fileUploadUtils.js +84 -0
- package/lib/server/firefox/ffBrowser.js +428 -0
- package/lib/server/firefox/ffConnection.js +147 -0
- package/lib/server/firefox/ffExecutionContext.js +150 -0
- package/lib/server/firefox/ffInput.js +159 -0
- package/lib/server/firefox/ffNetworkManager.js +256 -0
- package/lib/server/firefox/ffPage.js +500 -0
- package/lib/server/firefox/firefox.js +116 -0
- package/lib/server/firefox/protocol.d.js +16 -0
- package/lib/server/formData.js +147 -0
- package/lib/server/frameSelectors.js +154 -0
- package/lib/server/frames.js +1455 -0
- package/lib/server/har/harRecorder.js +147 -0
- package/lib/server/har/harTracer.js +607 -0
- package/lib/server/harBackend.js +157 -0
- package/lib/server/helper.js +96 -0
- package/lib/server/index.js +58 -0
- package/lib/server/input.js +277 -0
- package/lib/server/instrumentation.js +69 -0
- package/lib/server/javascript.js +291 -0
- package/lib/server/launchApp.js +128 -0
- package/lib/server/localUtils.js +214 -0
- package/lib/server/macEditingCommands.js +143 -0
- package/lib/server/network.js +629 -0
- package/lib/server/page.js +886 -0
- package/lib/server/pipeTransport.js +89 -0
- package/lib/server/playwright.js +69 -0
- package/lib/server/progress.js +112 -0
- package/lib/server/protocolError.js +52 -0
- package/lib/server/recorder/chat.js +161 -0
- package/lib/server/recorder/recorderApp.js +387 -0
- package/lib/server/recorder/recorderRunner.js +138 -0
- package/lib/server/recorder/recorderSignalProcessor.js +83 -0
- package/lib/server/recorder/recorderUtils.js +157 -0
- package/lib/server/recorder/throttledFile.js +57 -0
- package/lib/server/recorder.js +499 -0
- package/lib/server/registry/browserFetcher.js +175 -0
- package/lib/server/registry/dependencies.js +371 -0
- package/lib/server/registry/index.js +1399 -0
- package/lib/server/registry/nativeDeps.js +1280 -0
- package/lib/server/registry/oopDownloadBrowserMain.js +124 -0
- package/lib/server/screenshotter.js +333 -0
- package/lib/server/selectors.js +112 -0
- package/lib/server/socksClientCertificatesInterceptor.js +383 -0
- package/lib/server/socksInterceptor.js +95 -0
- package/lib/server/trace/recorder/snapshotter.js +147 -0
- package/lib/server/trace/recorder/snapshotterInjected.js +541 -0
- package/lib/server/trace/recorder/tracing.js +604 -0
- package/lib/server/trace/test/inMemorySnapshotter.js +87 -0
- package/lib/server/trace/viewer/traceViewer.js +241 -0
- package/lib/server/transport.js +181 -0
- package/lib/server/types.js +28 -0
- package/lib/server/usKeyboardLayout.js +145 -0
- package/lib/server/utils/ascii.js +44 -0
- package/lib/server/utils/comparators.js +139 -0
- package/lib/server/utils/crypto.js +216 -0
- package/lib/server/utils/debug.js +42 -0
- package/lib/server/utils/debugLogger.js +122 -0
- package/lib/server/utils/env.js +73 -0
- package/lib/server/utils/eventsHelper.js +39 -0
- package/lib/server/utils/expectUtils.js +38 -0
- package/lib/server/utils/fileUtils.js +191 -0
- package/lib/server/utils/happyEyeballs.js +207 -0
- package/lib/server/utils/hostPlatform.js +123 -0
- package/lib/server/utils/httpServer.js +218 -0
- package/lib/server/utils/imageUtils.js +141 -0
- package/lib/server/utils/image_tools/colorUtils.js +89 -0
- package/lib/server/utils/image_tools/compare.js +109 -0
- package/lib/server/utils/image_tools/imageChannel.js +78 -0
- package/lib/server/utils/image_tools/stats.js +102 -0
- package/lib/server/utils/linuxUtils.js +71 -0
- package/lib/server/utils/network.js +233 -0
- package/lib/server/utils/nodePlatform.js +148 -0
- package/lib/server/utils/pipeTransport.js +84 -0
- package/lib/server/utils/processLauncher.js +241 -0
- package/lib/server/utils/profiler.js +65 -0
- package/lib/server/utils/socksProxy.js +511 -0
- package/lib/server/utils/spawnAsync.js +41 -0
- package/lib/server/utils/task.js +51 -0
- package/lib/server/utils/userAgent.js +98 -0
- package/lib/server/utils/wsServer.js +121 -0
- package/lib/server/utils/zipFile.js +74 -0
- package/lib/server/utils/zones.js +57 -0
- package/lib/server/webkit/protocol.d.js +16 -0
- package/lib/server/webkit/webkit.js +110 -0
- package/lib/server/webkit/wkBrowser.js +339 -0
- package/lib/server/webkit/wkConnection.js +149 -0
- package/lib/server/webkit/wkExecutionContext.js +154 -0
- package/lib/server/webkit/wkInput.js +181 -0
- package/lib/server/webkit/wkInterceptableRequest.js +169 -0
- package/lib/server/webkit/wkPage.js +1130 -0
- package/lib/server/webkit/wkProvisionalPage.js +83 -0
- package/lib/server/webkit/wkWorkers.js +105 -0
- package/lib/third_party/pixelmatch.js +255 -0
- package/lib/utils/isomorphic/ariaSnapshot.js +397 -0
- package/lib/utils/isomorphic/assert.js +31 -0
- package/lib/utils/isomorphic/colors.js +72 -0
- package/lib/utils/isomorphic/cssParser.js +245 -0
- package/lib/utils/isomorphic/cssTokenizer.js +1051 -0
- package/lib/utils/isomorphic/headers.js +53 -0
- package/lib/utils/isomorphic/locatorGenerators.js +689 -0
- package/lib/utils/isomorphic/locatorParser.js +176 -0
- package/lib/utils/isomorphic/locatorUtils.js +81 -0
- package/lib/utils/isomorphic/manualPromise.js +114 -0
- package/lib/utils/isomorphic/mimeType.js +459 -0
- package/lib/utils/isomorphic/multimap.js +80 -0
- package/lib/utils/isomorphic/protocolFormatter.js +81 -0
- package/lib/utils/isomorphic/protocolMetainfo.js +322 -0
- package/lib/utils/isomorphic/rtti.js +43 -0
- package/lib/utils/isomorphic/selectorParser.js +386 -0
- package/lib/utils/isomorphic/semaphore.js +54 -0
- package/lib/utils/isomorphic/stackTrace.js +158 -0
- package/lib/utils/isomorphic/stringUtils.js +155 -0
- package/lib/utils/isomorphic/time.js +49 -0
- package/lib/utils/isomorphic/timeoutRunner.js +66 -0
- package/lib/utils/isomorphic/traceUtils.js +58 -0
- package/lib/utils/isomorphic/types.js +16 -0
- package/lib/utils/isomorphic/urlMatch.js +190 -0
- package/lib/utils/isomorphic/utilityScriptSerializers.js +251 -0
- package/lib/utils.js +109 -0
- package/lib/utilsBundle.js +112 -0
- package/lib/utilsBundleImpl/index.js +218 -0
- package/lib/utilsBundleImpl/xdg-open +1066 -0
- package/lib/vite/htmlReport/index.html +84 -0
- package/lib/vite/recorder/assets/codeMirrorModule-BoWUGj0J.js +25 -0
- package/lib/vite/recorder/assets/codeMirrorModule-C3UTv-Ge.css +1 -0
- package/lib/vite/recorder/assets/codicon-DCmgc-ay.ttf +0 -0
- package/lib/vite/recorder/assets/index-DJqDAOZp.js +193 -0
- package/lib/vite/recorder/assets/index-Ri0uHF7I.css +1 -0
- package/lib/vite/recorder/index.html +29 -0
- package/lib/vite/recorder/playwright-logo.svg +9 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-Bucv2d7q.js +25 -0
- package/lib/vite/traceViewer/assets/defaultSettingsView-BEpdCv1S.js +266 -0
- package/lib/vite/traceViewer/assets/xtermModule-CsJ4vdCR.js +9 -0
- package/lib/vite/traceViewer/codeMirrorModule.C3UTv-Ge.css +1 -0
- package/lib/vite/traceViewer/codicon.DCmgc-ay.ttf +0 -0
- package/lib/vite/traceViewer/defaultSettingsView.ConWv5KN.css +1 -0
- package/lib/vite/traceViewer/index.BxQ34UMZ.js +2 -0
- package/lib/vite/traceViewer/index.C4Y3Aw8n.css +1 -0
- package/lib/vite/traceViewer/index.html +43 -0
- package/lib/vite/traceViewer/manifest.webmanifest +16 -0
- package/lib/vite/traceViewer/playwright-logo.svg +9 -0
- package/lib/vite/traceViewer/snapshot.html +21 -0
- package/lib/vite/traceViewer/sw.bundle.js +3 -0
- package/lib/vite/traceViewer/uiMode.BWTwXl41.js +5 -0
- package/lib/vite/traceViewer/uiMode.Btcz36p_.css +1 -0
- package/lib/vite/traceViewer/uiMode.html +17 -0
- package/lib/vite/traceViewer/xtermModule.DYP7pi_n.css +32 -0
- package/lib/zipBundle.js +34 -0
- package/lib/zipBundleImpl.js +5 -0
- package/package.json +42 -0
- package/types/protocol.d.ts +23245 -0
- package/types/structs.d.ts +45 -0
- package/types/types.d.ts +22856 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var videoRecorder_exports = {};
|
|
20
|
+
__export(videoRecorder_exports, {
|
|
21
|
+
VideoRecorder: () => VideoRecorder
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(videoRecorder_exports);
|
|
24
|
+
var import_utils = require("../../utils");
|
|
25
|
+
var import_page = require("../page");
|
|
26
|
+
var import_processLauncher = require("../utils/processLauncher");
|
|
27
|
+
const fps = 25;
|
|
28
|
+
class VideoRecorder {
|
|
29
|
+
constructor(page, ffmpegPath) {
|
|
30
|
+
this._process = null;
|
|
31
|
+
this._gracefullyClose = null;
|
|
32
|
+
this._lastWritePromise = Promise.resolve();
|
|
33
|
+
this._firstFrameTimestamp = 0;
|
|
34
|
+
this._lastFrame = null;
|
|
35
|
+
this._lastWriteNodeTime = 0;
|
|
36
|
+
this._frameQueue = [];
|
|
37
|
+
this._isStopped = false;
|
|
38
|
+
this._ffmpegPath = ffmpegPath;
|
|
39
|
+
page.on(import_page.Page.Events.ScreencastFrame, (frame) => this.writeFrame(frame.buffer, frame.frameSwapWallTime / 1e3));
|
|
40
|
+
}
|
|
41
|
+
static async launch(page, ffmpegPath, options) {
|
|
42
|
+
if (!options.outputFile.endsWith(".webm"))
|
|
43
|
+
throw new Error("File must have .webm extension");
|
|
44
|
+
const recorder = new VideoRecorder(page, ffmpegPath);
|
|
45
|
+
await recorder._launch(options);
|
|
46
|
+
return recorder;
|
|
47
|
+
}
|
|
48
|
+
async _launch(options) {
|
|
49
|
+
const w = options.width;
|
|
50
|
+
const h = options.height;
|
|
51
|
+
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(" ");
|
|
52
|
+
args.push(options.outputFile);
|
|
53
|
+
const { launchedProcess, gracefullyClose } = await (0, import_processLauncher.launchProcess)({
|
|
54
|
+
command: this._ffmpegPath,
|
|
55
|
+
args,
|
|
56
|
+
stdio: "stdin",
|
|
57
|
+
log: (message) => import_utils.debugLogger.log("browser", message),
|
|
58
|
+
tempDirectories: [],
|
|
59
|
+
attemptToGracefullyClose: async () => {
|
|
60
|
+
import_utils.debugLogger.log("browser", "Closing stdin...");
|
|
61
|
+
launchedProcess.stdin.end();
|
|
62
|
+
},
|
|
63
|
+
onExit: (exitCode, signal) => {
|
|
64
|
+
import_utils.debugLogger.log("browser", `ffmpeg onkill exitCode=${exitCode} signal=${signal}`);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
launchedProcess.stdin.on("finish", () => {
|
|
68
|
+
import_utils.debugLogger.log("browser", "ffmpeg finished input.");
|
|
69
|
+
});
|
|
70
|
+
launchedProcess.stdin.on("error", () => {
|
|
71
|
+
import_utils.debugLogger.log("browser", "ffmpeg error.");
|
|
72
|
+
});
|
|
73
|
+
this._process = launchedProcess;
|
|
74
|
+
this._gracefullyClose = gracefullyClose;
|
|
75
|
+
}
|
|
76
|
+
writeFrame(frame, timestamp) {
|
|
77
|
+
(0, import_utils.assert)(this._process);
|
|
78
|
+
if (this._isStopped)
|
|
79
|
+
return;
|
|
80
|
+
if (!this._firstFrameTimestamp)
|
|
81
|
+
this._firstFrameTimestamp = timestamp;
|
|
82
|
+
const frameNumber = Math.floor((timestamp - this._firstFrameTimestamp) * fps);
|
|
83
|
+
if (this._lastFrame) {
|
|
84
|
+
const repeatCount = frameNumber - this._lastFrame.frameNumber;
|
|
85
|
+
for (let i = 0; i < repeatCount; ++i)
|
|
86
|
+
this._frameQueue.push(this._lastFrame.buffer);
|
|
87
|
+
this._lastWritePromise = this._lastWritePromise.then(() => this._sendFrames());
|
|
88
|
+
}
|
|
89
|
+
this._lastFrame = { buffer: frame, timestamp, frameNumber };
|
|
90
|
+
this._lastWriteNodeTime = (0, import_utils.monotonicTime)();
|
|
91
|
+
}
|
|
92
|
+
async _sendFrames() {
|
|
93
|
+
while (this._frameQueue.length)
|
|
94
|
+
await this._sendFrame(this._frameQueue.shift());
|
|
95
|
+
}
|
|
96
|
+
async _sendFrame(frame) {
|
|
97
|
+
return new Promise((f) => this._process.stdin.write(frame, f)).then((error) => {
|
|
98
|
+
if (error)
|
|
99
|
+
import_utils.debugLogger.log("browser", `ffmpeg failed to write: ${String(error)}`);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
async stop() {
|
|
103
|
+
if (this._isStopped || !this._lastFrame)
|
|
104
|
+
return;
|
|
105
|
+
const addTime = Math.max(((0, import_utils.monotonicTime)() - this._lastWriteNodeTime) / 1e3, 1);
|
|
106
|
+
this.writeFrame(Buffer.from([]), this._lastFrame.timestamp + addTime);
|
|
107
|
+
this._isStopped = true;
|
|
108
|
+
await this._lastWritePromise;
|
|
109
|
+
await this._gracefullyClose();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
113
|
+
0 && (module.exports = {
|
|
114
|
+
VideoRecorder
|
|
115
|
+
});
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var clock_exports = {};
|
|
30
|
+
__export(clock_exports, {
|
|
31
|
+
Clock: () => Clock
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(clock_exports);
|
|
34
|
+
var rawClockSource = __toESM(require("../generated/clockSource"));
|
|
35
|
+
class Clock {
|
|
36
|
+
constructor(browserContext) {
|
|
37
|
+
this._initScripts = [];
|
|
38
|
+
this._browserContext = browserContext;
|
|
39
|
+
}
|
|
40
|
+
async uninstall(progress) {
|
|
41
|
+
await progress.race(this._browserContext.removeInitScripts(this._initScripts));
|
|
42
|
+
this._initScripts = [];
|
|
43
|
+
}
|
|
44
|
+
async fastForward(progress, ticks) {
|
|
45
|
+
await this._installIfNeeded(progress);
|
|
46
|
+
const ticksMillis = parseTicks(ticks);
|
|
47
|
+
this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('fastForward', ${Date.now()}, ${ticksMillis})`));
|
|
48
|
+
await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.fastForward(${ticksMillis})`));
|
|
49
|
+
}
|
|
50
|
+
async install(progress, time) {
|
|
51
|
+
await this._installIfNeeded(progress);
|
|
52
|
+
const timeMillis = time !== void 0 ? parseTime(time) : Date.now();
|
|
53
|
+
this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('install', ${Date.now()}, ${timeMillis})`));
|
|
54
|
+
await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.install(${timeMillis})`));
|
|
55
|
+
}
|
|
56
|
+
async pauseAt(progress, ticks) {
|
|
57
|
+
await this._installIfNeeded(progress);
|
|
58
|
+
const timeMillis = parseTime(ticks);
|
|
59
|
+
this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('pauseAt', ${Date.now()}, ${timeMillis})`));
|
|
60
|
+
await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.pauseAt(${timeMillis})`));
|
|
61
|
+
}
|
|
62
|
+
resumeNoReply() {
|
|
63
|
+
if (!this._initScripts.length)
|
|
64
|
+
return;
|
|
65
|
+
const doResume = async () => {
|
|
66
|
+
this._initScripts.push(await this._browserContext.addInitScript(void 0, `globalThis.__pwClock.controller.log('resume', ${Date.now()})`));
|
|
67
|
+
await this._evaluateInFrames(`globalThis.__pwClock.controller.resume()`);
|
|
68
|
+
};
|
|
69
|
+
doResume().catch(() => {
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
async resume(progress) {
|
|
73
|
+
await this._installIfNeeded(progress);
|
|
74
|
+
this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('resume', ${Date.now()})`));
|
|
75
|
+
await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.resume()`));
|
|
76
|
+
}
|
|
77
|
+
async setFixedTime(progress, time) {
|
|
78
|
+
await this._installIfNeeded(progress);
|
|
79
|
+
const timeMillis = parseTime(time);
|
|
80
|
+
this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('setFixedTime', ${Date.now()}, ${timeMillis})`));
|
|
81
|
+
await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.setFixedTime(${timeMillis})`));
|
|
82
|
+
}
|
|
83
|
+
async setSystemTime(progress, time) {
|
|
84
|
+
await this._installIfNeeded(progress);
|
|
85
|
+
const timeMillis = parseTime(time);
|
|
86
|
+
this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('setSystemTime', ${Date.now()}, ${timeMillis})`));
|
|
87
|
+
await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.setSystemTime(${timeMillis})`));
|
|
88
|
+
}
|
|
89
|
+
async runFor(progress, ticks) {
|
|
90
|
+
await this._installIfNeeded(progress);
|
|
91
|
+
const ticksMillis = parseTicks(ticks);
|
|
92
|
+
this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('runFor', ${Date.now()}, ${ticksMillis})`));
|
|
93
|
+
await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.runFor(${ticksMillis})`));
|
|
94
|
+
}
|
|
95
|
+
async _installIfNeeded(progress) {
|
|
96
|
+
if (this._initScripts.length)
|
|
97
|
+
return;
|
|
98
|
+
const script = `(() => {
|
|
99
|
+
const module = {};
|
|
100
|
+
${rawClockSource.source}
|
|
101
|
+
if (!globalThis.__pwClock)
|
|
102
|
+
globalThis.__pwClock = (module.exports.inject())(globalThis);
|
|
103
|
+
})();`;
|
|
104
|
+
const initScript = await this._browserContext.addInitScript(progress, script);
|
|
105
|
+
await progress.race(this._evaluateInFrames(script));
|
|
106
|
+
this._initScripts.push(initScript);
|
|
107
|
+
}
|
|
108
|
+
async _evaluateInFrames(script) {
|
|
109
|
+
await this._browserContext.safeNonStallingEvaluateInAllFrames(script, "main", { throwOnJSErrors: true });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function parseTicks(value) {
|
|
113
|
+
if (typeof value === "number")
|
|
114
|
+
return value;
|
|
115
|
+
if (!value)
|
|
116
|
+
return 0;
|
|
117
|
+
const str = value;
|
|
118
|
+
const strings = str.split(":");
|
|
119
|
+
const l = strings.length;
|
|
120
|
+
let i = l;
|
|
121
|
+
let ms = 0;
|
|
122
|
+
let parsed;
|
|
123
|
+
if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
|
|
124
|
+
throw new Error(
|
|
125
|
+
`Clock only understands numbers, 'mm:ss' and 'hh:mm:ss'`
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
while (i--) {
|
|
129
|
+
parsed = parseInt(strings[i], 10);
|
|
130
|
+
if (parsed >= 60)
|
|
131
|
+
throw new Error(`Invalid time ${str}`);
|
|
132
|
+
ms += parsed * Math.pow(60, l - i - 1);
|
|
133
|
+
}
|
|
134
|
+
return ms * 1e3;
|
|
135
|
+
}
|
|
136
|
+
function parseTime(epoch) {
|
|
137
|
+
if (!epoch)
|
|
138
|
+
return 0;
|
|
139
|
+
if (typeof epoch === "number")
|
|
140
|
+
return epoch;
|
|
141
|
+
const parsed = new Date(epoch);
|
|
142
|
+
if (!isFinite(parsed.getTime()))
|
|
143
|
+
throw new Error(`Invalid date: ${epoch}`);
|
|
144
|
+
return parsed.getTime();
|
|
145
|
+
}
|
|
146
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
147
|
+
0 && (module.exports = {
|
|
148
|
+
Clock
|
|
149
|
+
});
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var csharp_exports = {};
|
|
20
|
+
__export(csharp_exports, {
|
|
21
|
+
CSharpLanguageGenerator: () => CSharpLanguageGenerator
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(csharp_exports);
|
|
24
|
+
var import_language = require("./language");
|
|
25
|
+
var import_utils = require("../../utils");
|
|
26
|
+
var import_deviceDescriptors = require("../deviceDescriptors");
|
|
27
|
+
class CSharpLanguageGenerator {
|
|
28
|
+
constructor(mode) {
|
|
29
|
+
this.groupName = ".NET C#";
|
|
30
|
+
this.highlighter = "csharp";
|
|
31
|
+
if (mode === "library") {
|
|
32
|
+
this.name = "Library";
|
|
33
|
+
this.id = "csharp";
|
|
34
|
+
} else if (mode === "mstest") {
|
|
35
|
+
this.name = "MSTest";
|
|
36
|
+
this.id = "csharp-mstest";
|
|
37
|
+
} else if (mode === "nunit") {
|
|
38
|
+
this.name = "NUnit";
|
|
39
|
+
this.id = "csharp-nunit";
|
|
40
|
+
} else {
|
|
41
|
+
throw new Error(`Unknown C# language mode: ${mode}`);
|
|
42
|
+
}
|
|
43
|
+
this._mode = mode;
|
|
44
|
+
}
|
|
45
|
+
generateAction(actionInContext) {
|
|
46
|
+
const action = this._generateActionInner(actionInContext);
|
|
47
|
+
if (action)
|
|
48
|
+
return action;
|
|
49
|
+
return "";
|
|
50
|
+
}
|
|
51
|
+
_generateActionInner(actionInContext) {
|
|
52
|
+
const action = actionInContext.action;
|
|
53
|
+
if (this._mode !== "library" && (action.name === "openPage" || action.name === "closePage"))
|
|
54
|
+
return "";
|
|
55
|
+
const pageAlias = this._formatPageAlias(actionInContext.frame.pageAlias);
|
|
56
|
+
const formatter = new CSharpFormatter(this._mode === "library" ? 0 : 8);
|
|
57
|
+
if (action.name === "openPage") {
|
|
58
|
+
formatter.add(`var ${pageAlias} = await context.NewPageAsync();`);
|
|
59
|
+
if (action.url && action.url !== "about:blank" && action.url !== "chrome://newtab/")
|
|
60
|
+
formatter.add(`await ${pageAlias}.GotoAsync(${quote(action.url)});`);
|
|
61
|
+
return formatter.format();
|
|
62
|
+
}
|
|
63
|
+
const locators = actionInContext.frame.framePath.map((selector) => `.${this._asLocator(selector)}.ContentFrame`);
|
|
64
|
+
const subject = `${pageAlias}${locators.join("")}`;
|
|
65
|
+
const signals = (0, import_language.toSignalMap)(action);
|
|
66
|
+
if (signals.dialog) {
|
|
67
|
+
formatter.add(` void ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler(object sender, IDialog dialog)
|
|
68
|
+
{
|
|
69
|
+
Console.WriteLine($"Dialog message: {dialog.Message}");
|
|
70
|
+
dialog.DismissAsync();
|
|
71
|
+
${pageAlias}.Dialog -= ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler;
|
|
72
|
+
}
|
|
73
|
+
${pageAlias}.Dialog += ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler;`);
|
|
74
|
+
}
|
|
75
|
+
const lines = [];
|
|
76
|
+
lines.push(this._generateActionCall(subject, actionInContext));
|
|
77
|
+
if (signals.download) {
|
|
78
|
+
lines.unshift(`var download${signals.download.downloadAlias} = await ${pageAlias}.RunAndWaitForDownloadAsync(async () =>
|
|
79
|
+
{`);
|
|
80
|
+
lines.push(`});`);
|
|
81
|
+
}
|
|
82
|
+
if (signals.popup) {
|
|
83
|
+
lines.unshift(`var ${this._formatPageAlias(signals.popup.popupAlias)} = await ${pageAlias}.RunAndWaitForPopupAsync(async () =>
|
|
84
|
+
{`);
|
|
85
|
+
lines.push(`});`);
|
|
86
|
+
}
|
|
87
|
+
for (const line of lines)
|
|
88
|
+
formatter.add(line);
|
|
89
|
+
return formatter.format();
|
|
90
|
+
}
|
|
91
|
+
_formatPageAlias(pageAlias) {
|
|
92
|
+
if (this._mode === "library")
|
|
93
|
+
return pageAlias;
|
|
94
|
+
if (pageAlias === "page")
|
|
95
|
+
return "Page";
|
|
96
|
+
return pageAlias;
|
|
97
|
+
}
|
|
98
|
+
_generateActionCall(subject, actionInContext) {
|
|
99
|
+
const action = actionInContext.action;
|
|
100
|
+
switch (action.name) {
|
|
101
|
+
case "openPage":
|
|
102
|
+
throw Error("Not reached");
|
|
103
|
+
case "closePage":
|
|
104
|
+
return `await ${subject}.CloseAsync();`;
|
|
105
|
+
case "click": {
|
|
106
|
+
let method = "Click";
|
|
107
|
+
if (action.clickCount === 2)
|
|
108
|
+
method = "DblClick";
|
|
109
|
+
const options = (0, import_language.toClickOptionsForSourceCode)(action);
|
|
110
|
+
if (!Object.entries(options).length)
|
|
111
|
+
return `await ${subject}.${this._asLocator(action.selector)}.${method}Async();`;
|
|
112
|
+
const optionsString = formatObject(options, " ");
|
|
113
|
+
return `await ${subject}.${this._asLocator(action.selector)}.${method}Async(${optionsString});`;
|
|
114
|
+
}
|
|
115
|
+
case "hover": {
|
|
116
|
+
const optionsString = action.position ? formatObject({ position: action.position }, " ") : "";
|
|
117
|
+
return `await ${subject}.${this._asLocator(action.selector)}.HoverAsync(${optionsString});`;
|
|
118
|
+
}
|
|
119
|
+
case "check":
|
|
120
|
+
return `await ${subject}.${this._asLocator(action.selector)}.CheckAsync();`;
|
|
121
|
+
case "uncheck":
|
|
122
|
+
return `await ${subject}.${this._asLocator(action.selector)}.UncheckAsync();`;
|
|
123
|
+
case "fill":
|
|
124
|
+
return `await ${subject}.${this._asLocator(action.selector)}.FillAsync(${quote(action.text)});`;
|
|
125
|
+
case "setInputFiles":
|
|
126
|
+
return `await ${subject}.${this._asLocator(action.selector)}.SetInputFilesAsync(${formatObject(action.files)});`;
|
|
127
|
+
case "press": {
|
|
128
|
+
const modifiers = (0, import_language.toKeyboardModifiers)(action.modifiers);
|
|
129
|
+
const shortcut = [...modifiers, action.key].join("+");
|
|
130
|
+
return `await ${subject}.${this._asLocator(action.selector)}.PressAsync(${quote(shortcut)});`;
|
|
131
|
+
}
|
|
132
|
+
case "navigate":
|
|
133
|
+
return `await ${subject}.GotoAsync(${quote(action.url)});`;
|
|
134
|
+
case "select":
|
|
135
|
+
return `await ${subject}.${this._asLocator(action.selector)}.SelectOptionAsync(${formatObject(action.options)});`;
|
|
136
|
+
case "assertText":
|
|
137
|
+
return `await Expect(${subject}.${this._asLocator(action.selector)}).${action.substring ? "ToContainTextAsync" : "ToHaveTextAsync"}(${quote(action.text)});`;
|
|
138
|
+
case "assertChecked":
|
|
139
|
+
return `await Expect(${subject}.${this._asLocator(action.selector)})${action.checked ? "" : ".Not"}.ToBeCheckedAsync();`;
|
|
140
|
+
case "assertVisible":
|
|
141
|
+
return `await Expect(${subject}.${this._asLocator(action.selector)}).ToBeVisibleAsync();`;
|
|
142
|
+
case "assertValue": {
|
|
143
|
+
const assertion = action.value ? `ToHaveValueAsync(${quote(action.value)})` : `ToBeEmptyAsync()`;
|
|
144
|
+
return `await Expect(${subject}.${this._asLocator(action.selector)}).${assertion};`;
|
|
145
|
+
}
|
|
146
|
+
case "assertSnapshot":
|
|
147
|
+
return `await Expect(${subject}.${this._asLocator(action.selector)}).ToMatchAriaSnapshotAsync(${quote(action.ariaSnapshot)});`;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
_asLocator(selector) {
|
|
151
|
+
return (0, import_utils.asLocator)("csharp", selector);
|
|
152
|
+
}
|
|
153
|
+
generateHeader(options) {
|
|
154
|
+
if (this._mode === "library")
|
|
155
|
+
return this.generateStandaloneHeader(options);
|
|
156
|
+
return this.generateTestRunnerHeader(options);
|
|
157
|
+
}
|
|
158
|
+
generateStandaloneHeader(options) {
|
|
159
|
+
const formatter = new CSharpFormatter(0);
|
|
160
|
+
formatter.add(`
|
|
161
|
+
using Microsoft.Playwright;
|
|
162
|
+
using System;
|
|
163
|
+
using System.Threading.Tasks;
|
|
164
|
+
|
|
165
|
+
using var playwright = await Playwright.CreateAsync();
|
|
166
|
+
await using var browser = await playwright.${toPascal(options.browserName)}.LaunchAsync(${formatObject(options.launchOptions, " ")});
|
|
167
|
+
var context = await browser.NewContextAsync(${formatContextOptions(options.contextOptions, options.deviceName)});`);
|
|
168
|
+
if (options.contextOptions.recordHar) {
|
|
169
|
+
const url = options.contextOptions.recordHar.urlFilter;
|
|
170
|
+
formatter.add(` await context.RouteFromHARAsync(${quote(options.contextOptions.recordHar.path)}${url ? `, ${formatObject({ url }, " ")}` : ""});`);
|
|
171
|
+
}
|
|
172
|
+
formatter.newLine();
|
|
173
|
+
return formatter.format();
|
|
174
|
+
}
|
|
175
|
+
generateTestRunnerHeader(options) {
|
|
176
|
+
const formatter = new CSharpFormatter(0);
|
|
177
|
+
formatter.add(`
|
|
178
|
+
using Microsoft.Playwright.${this._mode === "nunit" ? "NUnit" : "MSTest"};
|
|
179
|
+
using Microsoft.Playwright;
|
|
180
|
+
|
|
181
|
+
${this._mode === "nunit" ? `[Parallelizable(ParallelScope.Self)]
|
|
182
|
+
[TestFixture]` : "[TestClass]"}
|
|
183
|
+
public class Tests : PageTest
|
|
184
|
+
{`);
|
|
185
|
+
const formattedContextOptions = formatContextOptions(options.contextOptions, options.deviceName);
|
|
186
|
+
if (formattedContextOptions) {
|
|
187
|
+
formatter.add(`public override BrowserNewContextOptions ContextOptions()
|
|
188
|
+
{
|
|
189
|
+
return ${formattedContextOptions};
|
|
190
|
+
}`);
|
|
191
|
+
formatter.newLine();
|
|
192
|
+
}
|
|
193
|
+
formatter.add(` [${this._mode === "nunit" ? "Test" : "TestMethod"}]
|
|
194
|
+
public async Task MyTest()
|
|
195
|
+
{`);
|
|
196
|
+
if (options.contextOptions.recordHar) {
|
|
197
|
+
const url = options.contextOptions.recordHar.urlFilter;
|
|
198
|
+
formatter.add(` await Context.RouteFromHARAsync(${quote(options.contextOptions.recordHar.path)}${url ? `, ${formatObject({ url }, " ")}` : ""});`);
|
|
199
|
+
}
|
|
200
|
+
return formatter.format();
|
|
201
|
+
}
|
|
202
|
+
generateFooter(saveStorage) {
|
|
203
|
+
const offset = this._mode === "library" ? "" : " ";
|
|
204
|
+
let storageStateLine = saveStorage ? `
|
|
205
|
+
${offset}await context.StorageStateAsync(new()
|
|
206
|
+
${offset}{
|
|
207
|
+
${offset} Path = ${quote(saveStorage)}
|
|
208
|
+
${offset}});
|
|
209
|
+
` : "";
|
|
210
|
+
if (this._mode !== "library")
|
|
211
|
+
storageStateLine += ` }
|
|
212
|
+
}
|
|
213
|
+
`;
|
|
214
|
+
return storageStateLine;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function formatObject(value, indent = " ", name = "") {
|
|
218
|
+
if (typeof value === "string") {
|
|
219
|
+
if (["colorScheme", "modifiers", "button", "recordHarContent", "recordHarMode", "serviceWorkers"].includes(name))
|
|
220
|
+
return `${getEnumName(name)}.${toPascal(value)}`;
|
|
221
|
+
return quote(value);
|
|
222
|
+
}
|
|
223
|
+
if (Array.isArray(value))
|
|
224
|
+
return `new[] { ${value.map((o) => formatObject(o, indent, name)).join(", ")} }`;
|
|
225
|
+
if (typeof value === "object") {
|
|
226
|
+
const keys = Object.keys(value).filter((key) => value[key] !== void 0).sort();
|
|
227
|
+
if (!keys.length)
|
|
228
|
+
return `new()`;
|
|
229
|
+
const tokens = [];
|
|
230
|
+
for (const key of keys) {
|
|
231
|
+
const property = getPropertyName(key);
|
|
232
|
+
tokens.push(`${property} = ${formatObject(value[key], indent, key)},`);
|
|
233
|
+
}
|
|
234
|
+
return `new()
|
|
235
|
+
{
|
|
236
|
+
${indent}${tokens.join(`
|
|
237
|
+
${indent}`)}
|
|
238
|
+
${indent}}`;
|
|
239
|
+
}
|
|
240
|
+
if (name === "latitude" || name === "longitude")
|
|
241
|
+
return String(value) + "m";
|
|
242
|
+
return String(value);
|
|
243
|
+
}
|
|
244
|
+
function getEnumName(value) {
|
|
245
|
+
switch (value) {
|
|
246
|
+
case "modifiers":
|
|
247
|
+
return "KeyboardModifier";
|
|
248
|
+
case "button":
|
|
249
|
+
return "MouseButton";
|
|
250
|
+
case "recordHarMode":
|
|
251
|
+
return "HarMode";
|
|
252
|
+
case "recordHarContent":
|
|
253
|
+
return "HarContentPolicy";
|
|
254
|
+
case "serviceWorkers":
|
|
255
|
+
return "ServiceWorkerPolicy";
|
|
256
|
+
default:
|
|
257
|
+
return toPascal(value);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
function getPropertyName(key) {
|
|
261
|
+
switch (key) {
|
|
262
|
+
case "storageState":
|
|
263
|
+
return "StorageStatePath";
|
|
264
|
+
case "viewport":
|
|
265
|
+
return "ViewportSize";
|
|
266
|
+
default:
|
|
267
|
+
return toPascal(key);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
function toPascal(value) {
|
|
271
|
+
return value[0].toUpperCase() + value.slice(1);
|
|
272
|
+
}
|
|
273
|
+
function formatContextOptions(contextOptions, deviceName) {
|
|
274
|
+
const options = { ...contextOptions };
|
|
275
|
+
delete options.recordHar;
|
|
276
|
+
const device = deviceName && import_deviceDescriptors.deviceDescriptors[deviceName];
|
|
277
|
+
if (!device) {
|
|
278
|
+
if (!Object.entries(options).length)
|
|
279
|
+
return "";
|
|
280
|
+
return formatObject(options, " ");
|
|
281
|
+
}
|
|
282
|
+
if (!Object.entries((0, import_language.sanitizeDeviceOptions)(device, options)).length)
|
|
283
|
+
return `playwright.Devices[${quote(deviceName)}]`;
|
|
284
|
+
delete options["defaultBrowserType"];
|
|
285
|
+
return formatObject(options, " ");
|
|
286
|
+
}
|
|
287
|
+
class CSharpFormatter {
|
|
288
|
+
constructor(offset = 0) {
|
|
289
|
+
this._lines = [];
|
|
290
|
+
this._baseIndent = " ".repeat(4);
|
|
291
|
+
this._baseOffset = " ".repeat(offset);
|
|
292
|
+
}
|
|
293
|
+
prepend(text) {
|
|
294
|
+
this._lines = text.trim().split("\n").map((line) => line.trim()).concat(this._lines);
|
|
295
|
+
}
|
|
296
|
+
add(text) {
|
|
297
|
+
this._lines.push(...text.trim().split("\n").map((line) => line.trim()));
|
|
298
|
+
}
|
|
299
|
+
newLine() {
|
|
300
|
+
this._lines.push("");
|
|
301
|
+
}
|
|
302
|
+
format() {
|
|
303
|
+
let spaces = "";
|
|
304
|
+
let previousLine = "";
|
|
305
|
+
return this._lines.map((line) => {
|
|
306
|
+
if (line === "")
|
|
307
|
+
return line;
|
|
308
|
+
if (line.startsWith("}") || line.startsWith("]") || line.includes("});") || line === ");")
|
|
309
|
+
spaces = spaces.substring(this._baseIndent.length);
|
|
310
|
+
const extraSpaces = /^(for|while|if).*\(.*\)$/.test(previousLine) ? this._baseIndent : "";
|
|
311
|
+
previousLine = line;
|
|
312
|
+
line = spaces + extraSpaces + line;
|
|
313
|
+
if (line.endsWith("{") || line.endsWith("[") || line.endsWith("("))
|
|
314
|
+
spaces += this._baseIndent;
|
|
315
|
+
if (line.endsWith("));"))
|
|
316
|
+
spaces = spaces.substring(this._baseIndent.length);
|
|
317
|
+
return this._baseOffset + line;
|
|
318
|
+
}).join("\n");
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
function quote(text) {
|
|
322
|
+
return (0, import_utils.escapeWithQuotes)(text, '"');
|
|
323
|
+
}
|
|
324
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
325
|
+
0 && (module.exports = {
|
|
326
|
+
CSharpLanguageGenerator
|
|
327
|
+
});
|