@pedropaulovc/playwright-core 1.59.0-next
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 +4076 -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 +79 -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 +603 -0
- package/lib/cli/programWithTestStub.js +74 -0
- package/lib/client/android.js +361 -0
- package/lib/client/api.js +137 -0
- package/lib/client/artifact.js +79 -0
- package/lib/client/browser.js +161 -0
- package/lib/client/browserContext.js +582 -0
- package/lib/client/browserType.js +185 -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 +318 -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 +284 -0
- package/lib/client/errors.js +77 -0
- package/lib/client/eventEmitter.js +314 -0
- package/lib/client/events.js +103 -0
- package/lib/client/fetch.js +368 -0
- package/lib/client/fileChooser.js +46 -0
- package/lib/client/fileUtils.js +34 -0
- package/lib/client/frame.js +409 -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 +745 -0
- package/lib/client/pageAgent.js +64 -0
- package/lib/client/platform.js +77 -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/mcpBundle.js +84 -0
- package/lib/mcpBundleImpl/index.js +147 -0
- package/lib/outofprocess.js +76 -0
- package/lib/protocol/serializers.js +197 -0
- package/lib/protocol/validator.js +2969 -0
- package/lib/protocol/validatorPrimitives.js +193 -0
- package/lib/remote/playwrightConnection.js +129 -0
- package/lib/remote/playwrightServer.js +334 -0
- package/lib/server/agent/actionRunner.js +335 -0
- package/lib/server/agent/actions.js +128 -0
- package/lib/server/agent/codegen.js +111 -0
- package/lib/server/agent/context.js +150 -0
- package/lib/server/agent/expectTools.js +156 -0
- package/lib/server/agent/pageAgent.js +204 -0
- package/lib/server/agent/performTools.js +262 -0
- package/lib/server/agent/tool.js +109 -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 +549 -0
- package/lib/server/bidi/bidiChromium.js +148 -0
- package/lib/server/bidi/bidiConnection.js +213 -0
- package/lib/server/bidi/bidiDeserializer.js +116 -0
- package/lib/server/bidi/bidiExecutionContext.js +267 -0
- package/lib/server/bidi/bidiFirefox.js +128 -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 +583 -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/bidiKeyboard.js +256 -0
- package/lib/server/bidi/third_party/bidiProtocol.js +24 -0
- package/lib/server/bidi/third_party/bidiProtocolCore.js +180 -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 +702 -0
- package/lib/server/browserType.js +336 -0
- package/lib/server/callLog.js +82 -0
- package/lib/server/chromium/appIcon.png +0 -0
- package/lib/server/chromium/chromium.js +395 -0
- package/lib/server/chromium/chromiumSwitches.js +104 -0
- package/lib/server/chromium/crBrowser.js +511 -0
- package/lib/server/chromium/crConnection.js +197 -0
- package/lib/server/chromium/crCoverage.js +235 -0
- package/lib/server/chromium/crDevTools.js +111 -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 +707 -0
- package/lib/server/chromium/crPage.js +1001 -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/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 +247 -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 +384 -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 +364 -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/pageAgentDispatcher.js +96 -0
- package/lib/server/dispatchers/pageDispatcher.js +393 -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 +815 -0
- package/lib/server/download.js +70 -0
- package/lib/server/electron/electron.js +273 -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 +418 -0
- package/lib/server/firefox/ffConnection.js +142 -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 +497 -0
- package/lib/server/firefox/firefox.js +114 -0
- package/lib/server/firefox/protocol.d.js +16 -0
- package/lib/server/formData.js +147 -0
- package/lib/server/frameSelectors.js +160 -0
- package/lib/server/frames.js +1471 -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 +72 -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 +667 -0
- package/lib/server/page.js +830 -0
- package/lib/server/pipeTransport.js +89 -0
- package/lib/server/playwright.js +69 -0
- package/lib/server/progress.js +132 -0
- package/lib/server/protocolError.js +52 -0
- package/lib/server/recorder/chat.js +161 -0
- package/lib/server/recorder/recorderApp.js +366 -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 +177 -0
- package/lib/server/registry/dependencies.js +371 -0
- package/lib/server/registry/index.js +1422 -0
- package/lib/server/registry/nativeDeps.js +1280 -0
- package/lib/server/registry/oopDownloadBrowserMain.js +127 -0
- package/lib/server/screencast.js +190 -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 +561 -0
- package/lib/server/trace/recorder/tracing.js +604 -0
- package/lib/server/trace/viewer/traceExporter.js +679 -0
- package/lib/server/trace/viewer/traceParser.js +72 -0
- package/lib/server/trace/viewer/traceViewer.js +245 -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 +123 -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 +203 -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 +242 -0
- package/lib/server/utils/nodePlatform.js +154 -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/videoRecorder.js +124 -0
- package/lib/server/webkit/protocol.d.js +16 -0
- package/lib/server/webkit/webkit.js +108 -0
- package/lib/server/webkit/wkBrowser.js +335 -0
- package/lib/server/webkit/wkConnection.js +144 -0
- package/lib/server/webkit/wkExecutionContext.js +154 -0
- package/lib/server/webkit/wkInput.js +181 -0
- package/lib/server/webkit/wkInterceptableRequest.js +197 -0
- package/lib/server/webkit/wkPage.js +1158 -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 +455 -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/lruCache.js +51 -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 +330 -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 +204 -0
- package/lib/utils/isomorphic/time.js +49 -0
- package/lib/utils/isomorphic/timeoutRunner.js +66 -0
- package/lib/utils/isomorphic/trace/entries.js +16 -0
- package/lib/utils/isomorphic/trace/snapshotRenderer.js +499 -0
- package/lib/utils/isomorphic/trace/snapshotServer.js +120 -0
- package/lib/utils/isomorphic/trace/snapshotStorage.js +89 -0
- package/lib/utils/isomorphic/trace/traceLoader.js +131 -0
- package/lib/utils/isomorphic/trace/traceModel.js +365 -0
- package/lib/utils/isomorphic/trace/traceModernizer.js +400 -0
- package/lib/utils/isomorphic/trace/versions/traceV3.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV4.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV5.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV6.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV7.js +16 -0
- package/lib/utils/isomorphic/trace/versions/traceV8.js +16 -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/isomorphic/yaml.js +84 -0
- package/lib/utils.js +111 -0
- package/lib/utilsBundle.js +109 -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-DYBRYzYX.css +1 -0
- package/lib/vite/recorder/assets/codeMirrorModule-DadYNm1I.js +32 -0
- package/lib/vite/recorder/assets/codicon-DCmgc-ay.ttf +0 -0
- package/lib/vite/recorder/assets/index-BSjZa4pk.css +1 -0
- package/lib/vite/recorder/assets/index-BhTWtUlo.js +193 -0
- package/lib/vite/recorder/index.html +29 -0
- package/lib/vite/recorder/playwright-logo.svg +9 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-DwzBH9eL.js +32 -0
- package/lib/vite/traceViewer/assets/codeMirrorModule-a5XoALAZ.js +32 -0
- package/lib/vite/traceViewer/assets/defaultSettingsView-CJSZINFr.js +266 -0
- package/lib/vite/traceViewer/assets/defaultSettingsView-CdCX8877.js +266 -0
- package/lib/vite/traceViewer/assets/xtermModule-CsJ4vdCR.js +9 -0
- package/lib/vite/traceViewer/codeMirrorModule.DYBRYzYX.css +1 -0
- package/lib/vite/traceViewer/codicon.DCmgc-ay.ttf +0 -0
- package/lib/vite/traceViewer/defaultSettingsView.7ch9cixO.css +1 -0
- package/lib/vite/traceViewer/index.BVu7tZDe.css +1 -0
- package/lib/vite/traceViewer/index.Dd9jebqr.js +2 -0
- package/lib/vite/traceViewer/index.f4OcrOqs.js +2 -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 +5 -0
- package/lib/vite/traceViewer/uiMode.Btcz36p_.css +1 -0
- package/lib/vite/traceViewer/uiMode.CQJ9SCIQ.js +5 -0
- package/lib/vite/traceViewer/uiMode.html +17 -0
- package/lib/vite/traceViewer/uiMode.qcahlSup.js +5 -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 +43 -0
- package/types/protocol.d.ts +23824 -0
- package/types/structs.d.ts +45 -0
- package/types/types.d.ts +22843 -0
|
@@ -0,0 +1,499 @@
|
|
|
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 snapshotRenderer_exports = {};
|
|
20
|
+
__export(snapshotRenderer_exports, {
|
|
21
|
+
SnapshotRenderer: () => SnapshotRenderer,
|
|
22
|
+
rewriteURLForCustomProtocol: () => rewriteURLForCustomProtocol
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(snapshotRenderer_exports);
|
|
25
|
+
var import_stringUtils = require("../stringUtils");
|
|
26
|
+
function findClosest(items, metric, target) {
|
|
27
|
+
return items.find((item, index) => {
|
|
28
|
+
if (index === items.length - 1)
|
|
29
|
+
return true;
|
|
30
|
+
const next = items[index + 1];
|
|
31
|
+
return Math.abs(metric(item) - target) < Math.abs(metric(next) - target);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function isNodeNameAttributesChildNodesSnapshot(n) {
|
|
35
|
+
return Array.isArray(n) && typeof n[0] === "string";
|
|
36
|
+
}
|
|
37
|
+
function isSubtreeReferenceSnapshot(n) {
|
|
38
|
+
return Array.isArray(n) && Array.isArray(n[0]);
|
|
39
|
+
}
|
|
40
|
+
class SnapshotRenderer {
|
|
41
|
+
constructor(htmlCache, resources, snapshots, screencastFrames, index) {
|
|
42
|
+
this._htmlCache = htmlCache;
|
|
43
|
+
this._resources = resources;
|
|
44
|
+
this._snapshots = snapshots;
|
|
45
|
+
this._index = index;
|
|
46
|
+
this._snapshot = snapshots[index];
|
|
47
|
+
this._callId = snapshots[index].callId;
|
|
48
|
+
this._screencastFrames = screencastFrames;
|
|
49
|
+
this.snapshotName = snapshots[index].snapshotName;
|
|
50
|
+
}
|
|
51
|
+
snapshot() {
|
|
52
|
+
return this._snapshots[this._index];
|
|
53
|
+
}
|
|
54
|
+
viewport() {
|
|
55
|
+
return this._snapshots[this._index].viewport;
|
|
56
|
+
}
|
|
57
|
+
closestScreenshot() {
|
|
58
|
+
const { wallTime, timestamp } = this.snapshot();
|
|
59
|
+
const closestFrame = wallTime && this._screencastFrames[0]?.frameSwapWallTime ? findClosest(this._screencastFrames, (frame) => frame.frameSwapWallTime, wallTime) : findClosest(this._screencastFrames, (frame) => frame.timestamp, timestamp);
|
|
60
|
+
return closestFrame?.sha1;
|
|
61
|
+
}
|
|
62
|
+
render() {
|
|
63
|
+
const result = [];
|
|
64
|
+
const visit = (n, snapshotIndex, parentTag, parentAttrs) => {
|
|
65
|
+
if (typeof n === "string") {
|
|
66
|
+
if (parentTag === "STYLE" || parentTag === "style")
|
|
67
|
+
result.push(escapeURLsInStyleSheet(rewriteURLsInStyleSheetForCustomProtocol(n)));
|
|
68
|
+
else
|
|
69
|
+
result.push((0, import_stringUtils.escapeHTML)(n));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (isSubtreeReferenceSnapshot(n)) {
|
|
73
|
+
const referenceIndex = snapshotIndex - n[0][0];
|
|
74
|
+
if (referenceIndex >= 0 && referenceIndex <= snapshotIndex) {
|
|
75
|
+
const nodes = snapshotNodes(this._snapshots[referenceIndex]);
|
|
76
|
+
const nodeIndex = n[0][1];
|
|
77
|
+
if (nodeIndex >= 0 && nodeIndex < nodes.length)
|
|
78
|
+
return visit(nodes[nodeIndex], referenceIndex, parentTag, parentAttrs);
|
|
79
|
+
}
|
|
80
|
+
} else if (isNodeNameAttributesChildNodesSnapshot(n)) {
|
|
81
|
+
const [name, nodeAttrs, ...children] = n;
|
|
82
|
+
const nodeName = name === "NOSCRIPT" ? "X-NOSCRIPT" : name;
|
|
83
|
+
const attrs = Object.entries(nodeAttrs || {});
|
|
84
|
+
result.push("<", nodeName);
|
|
85
|
+
const kCurrentSrcAttribute = "__playwright_current_src__";
|
|
86
|
+
const isFrame = nodeName === "IFRAME" || nodeName === "FRAME";
|
|
87
|
+
const isAnchor = nodeName === "A";
|
|
88
|
+
const isImg = nodeName === "IMG";
|
|
89
|
+
const isImgWithCurrentSrc = isImg && attrs.some((a) => a[0] === kCurrentSrcAttribute);
|
|
90
|
+
const isSourceInsidePictureWithCurrentSrc = nodeName === "SOURCE" && parentTag === "PICTURE" && parentAttrs?.some((a) => a[0] === kCurrentSrcAttribute);
|
|
91
|
+
for (const [attr, value] of attrs) {
|
|
92
|
+
let attrName = attr;
|
|
93
|
+
if (isFrame && attr.toLowerCase() === "src") {
|
|
94
|
+
attrName = "__playwright_src__";
|
|
95
|
+
}
|
|
96
|
+
if (isImg && attr === kCurrentSrcAttribute) {
|
|
97
|
+
attrName = "src";
|
|
98
|
+
}
|
|
99
|
+
if (["src", "srcset"].includes(attr.toLowerCase()) && (isImgWithCurrentSrc || isSourceInsidePictureWithCurrentSrc)) {
|
|
100
|
+
attrName = "_" + attrName;
|
|
101
|
+
}
|
|
102
|
+
let attrValue = value;
|
|
103
|
+
if (!isAnchor && (attr.toLowerCase() === "href" || attr.toLowerCase() === "src" || attr === kCurrentSrcAttribute))
|
|
104
|
+
attrValue = rewriteURLForCustomProtocol(value);
|
|
105
|
+
result.push(" ", attrName, '="', (0, import_stringUtils.escapeHTMLAttribute)(attrValue), '"');
|
|
106
|
+
}
|
|
107
|
+
result.push(">");
|
|
108
|
+
for (const child of children)
|
|
109
|
+
visit(child, snapshotIndex, nodeName, attrs);
|
|
110
|
+
if (!autoClosing.has(nodeName))
|
|
111
|
+
result.push("</", nodeName, ">");
|
|
112
|
+
return;
|
|
113
|
+
} else {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
const snapshot = this._snapshot;
|
|
118
|
+
const html = this._htmlCache.getOrCompute(this, () => {
|
|
119
|
+
visit(snapshot.html, this._index, void 0, void 0);
|
|
120
|
+
const prefix = snapshot.doctype ? `<!DOCTYPE ${snapshot.doctype}>` : "";
|
|
121
|
+
const html2 = prefix + [
|
|
122
|
+
// Hide the document in order to prevent flickering. We will unhide once script has processed shadow.
|
|
123
|
+
"<style>*,*::before,*::after { visibility: hidden }</style>",
|
|
124
|
+
`<script>${snapshotScript(this.viewport(), this._callId, this.snapshotName)}</script>`
|
|
125
|
+
].join("") + result.join("");
|
|
126
|
+
return { value: html2, size: html2.length };
|
|
127
|
+
});
|
|
128
|
+
return { html, pageId: snapshot.pageId, frameId: snapshot.frameId, index: this._index };
|
|
129
|
+
}
|
|
130
|
+
resourceByUrl(url, method) {
|
|
131
|
+
const snapshot = this._snapshot;
|
|
132
|
+
let sameFrameResource;
|
|
133
|
+
let otherFrameResource;
|
|
134
|
+
for (const resource of this._resources) {
|
|
135
|
+
if (typeof resource._monotonicTime === "number" && resource._monotonicTime >= snapshot.timestamp)
|
|
136
|
+
break;
|
|
137
|
+
if (resource.response.status === 304) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (resource.request.url === url && resource.request.method === method) {
|
|
141
|
+
if (resource._frameref === snapshot.frameId)
|
|
142
|
+
sameFrameResource = resource;
|
|
143
|
+
else
|
|
144
|
+
otherFrameResource = resource;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
let result = sameFrameResource ?? otherFrameResource;
|
|
148
|
+
if (result && method.toUpperCase() === "GET") {
|
|
149
|
+
let override = snapshot.resourceOverrides.find((o) => o.url === url);
|
|
150
|
+
if (override?.ref) {
|
|
151
|
+
const index = this._index - override.ref;
|
|
152
|
+
if (index >= 0 && index < this._snapshots.length)
|
|
153
|
+
override = this._snapshots[index].resourceOverrides.find((o) => o.url === url);
|
|
154
|
+
}
|
|
155
|
+
if (override?.sha1) {
|
|
156
|
+
result = {
|
|
157
|
+
...result,
|
|
158
|
+
response: {
|
|
159
|
+
...result.response,
|
|
160
|
+
content: {
|
|
161
|
+
...result.response.content,
|
|
162
|
+
_sha1: override.sha1
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const autoClosing = /* @__PURE__ */ new Set(["AREA", "BASE", "BR", "COL", "COMMAND", "EMBED", "HR", "IMG", "INPUT", "KEYGEN", "LINK", "MENUITEM", "META", "PARAM", "SOURCE", "TRACK", "WBR"]);
|
|
172
|
+
function snapshotNodes(snapshot) {
|
|
173
|
+
if (!snapshot._nodes) {
|
|
174
|
+
const nodes = [];
|
|
175
|
+
const visit = (n) => {
|
|
176
|
+
if (typeof n === "string") {
|
|
177
|
+
nodes.push(n);
|
|
178
|
+
} else if (isNodeNameAttributesChildNodesSnapshot(n)) {
|
|
179
|
+
const [, , ...children] = n;
|
|
180
|
+
for (const child of children)
|
|
181
|
+
visit(child);
|
|
182
|
+
nodes.push(n);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
visit(snapshot.html);
|
|
186
|
+
snapshot._nodes = nodes;
|
|
187
|
+
}
|
|
188
|
+
return snapshot._nodes;
|
|
189
|
+
}
|
|
190
|
+
function snapshotScript(viewport, ...targetIds) {
|
|
191
|
+
function applyPlaywrightAttributes(viewport2, ...targetIds2) {
|
|
192
|
+
const win = window;
|
|
193
|
+
const searchParams = new URLSearchParams(win.location.search);
|
|
194
|
+
const shouldPopulateCanvasFromScreenshot = searchParams.has("shouldPopulateCanvasFromScreenshot");
|
|
195
|
+
const isUnderTest = searchParams.has("isUnderTest");
|
|
196
|
+
const frameBoundingRectsInfo = {
|
|
197
|
+
viewport: viewport2,
|
|
198
|
+
frames: /* @__PURE__ */ new WeakMap()
|
|
199
|
+
};
|
|
200
|
+
win["__playwright_frame_bounding_rects__"] = frameBoundingRectsInfo;
|
|
201
|
+
const kPointerWarningTitle = "Recorded click position in absolute coordinates did not match the center of the clicked element. This is likely due to a difference between the test runner and the trace viewer operating systems.";
|
|
202
|
+
const scrollTops = [];
|
|
203
|
+
const scrollLefts = [];
|
|
204
|
+
const targetElements = [];
|
|
205
|
+
const canvasElements = [];
|
|
206
|
+
let topSnapshotWindow = win;
|
|
207
|
+
while (topSnapshotWindow !== topSnapshotWindow.parent && !topSnapshotWindow.location.pathname.match(/\/page@[a-z0-9]+$/))
|
|
208
|
+
topSnapshotWindow = topSnapshotWindow.parent;
|
|
209
|
+
const visit = (root) => {
|
|
210
|
+
for (const e of root.querySelectorAll(`[__playwright_scroll_top_]`))
|
|
211
|
+
scrollTops.push(e);
|
|
212
|
+
for (const e of root.querySelectorAll(`[__playwright_scroll_left_]`))
|
|
213
|
+
scrollLefts.push(e);
|
|
214
|
+
for (const element of root.querySelectorAll(`[__playwright_value_]`)) {
|
|
215
|
+
const inputElement = element;
|
|
216
|
+
if (inputElement.type !== "file")
|
|
217
|
+
inputElement.value = inputElement.getAttribute("__playwright_value_");
|
|
218
|
+
element.removeAttribute("__playwright_value_");
|
|
219
|
+
}
|
|
220
|
+
for (const element of root.querySelectorAll(`[__playwright_checked_]`)) {
|
|
221
|
+
element.checked = element.getAttribute("__playwright_checked_") === "true";
|
|
222
|
+
element.removeAttribute("__playwright_checked_");
|
|
223
|
+
}
|
|
224
|
+
for (const element of root.querySelectorAll(`[__playwright_selected_]`)) {
|
|
225
|
+
element.selected = element.getAttribute("__playwright_selected_") === "true";
|
|
226
|
+
element.removeAttribute("__playwright_selected_");
|
|
227
|
+
}
|
|
228
|
+
for (const element of root.querySelectorAll(`[__playwright_popover_open_]`)) {
|
|
229
|
+
try {
|
|
230
|
+
element.showPopover();
|
|
231
|
+
} catch {
|
|
232
|
+
}
|
|
233
|
+
element.removeAttribute("__playwright_popover_open_");
|
|
234
|
+
}
|
|
235
|
+
for (const element of root.querySelectorAll(`[__playwright_dialog_open_]`)) {
|
|
236
|
+
try {
|
|
237
|
+
if (element.getAttribute("__playwright_dialog_open_") === "modal")
|
|
238
|
+
element.showModal();
|
|
239
|
+
else
|
|
240
|
+
element.show();
|
|
241
|
+
} catch {
|
|
242
|
+
}
|
|
243
|
+
element.removeAttribute("__playwright_dialog_open_");
|
|
244
|
+
}
|
|
245
|
+
for (const targetId of targetIds2) {
|
|
246
|
+
for (const target of root.querySelectorAll(`[__playwright_target__="${targetId}"]`)) {
|
|
247
|
+
const style = target.style;
|
|
248
|
+
style.outline = "2px solid #006ab1";
|
|
249
|
+
style.backgroundColor = "#6fa8dc7f";
|
|
250
|
+
targetElements.push(target);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
for (const iframe of root.querySelectorAll("iframe, frame")) {
|
|
254
|
+
const boundingRectJson = iframe.getAttribute("__playwright_bounding_rect__");
|
|
255
|
+
iframe.removeAttribute("__playwright_bounding_rect__");
|
|
256
|
+
const boundingRect = boundingRectJson ? JSON.parse(boundingRectJson) : void 0;
|
|
257
|
+
if (boundingRect)
|
|
258
|
+
frameBoundingRectsInfo.frames.set(iframe, { boundingRect, scrollLeft: 0, scrollTop: 0 });
|
|
259
|
+
const src = iframe.getAttribute("__playwright_src__");
|
|
260
|
+
if (!src) {
|
|
261
|
+
iframe.setAttribute("src", 'data:text/html,<body style="background: #ddd"></body>');
|
|
262
|
+
} else {
|
|
263
|
+
const url = new URL(win.location.href);
|
|
264
|
+
const index = url.pathname.lastIndexOf("/snapshot/");
|
|
265
|
+
if (index !== -1)
|
|
266
|
+
url.pathname = url.pathname.substring(0, index + 1);
|
|
267
|
+
url.pathname += src.substring(1);
|
|
268
|
+
iframe.setAttribute("src", url.toString());
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
{
|
|
272
|
+
const body = root.querySelector(`body[__playwright_custom_elements__]`);
|
|
273
|
+
if (body && win.customElements) {
|
|
274
|
+
const customElements = (body.getAttribute("__playwright_custom_elements__") || "").split(",");
|
|
275
|
+
for (const elementName of customElements)
|
|
276
|
+
win.customElements.define(elementName, class extends HTMLElement {
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
for (const element of root.querySelectorAll(`template[__playwright_shadow_root_]`)) {
|
|
281
|
+
const template = element;
|
|
282
|
+
const shadowRoot = template.parentElement.attachShadow({ mode: "open" });
|
|
283
|
+
shadowRoot.appendChild(template.content);
|
|
284
|
+
template.remove();
|
|
285
|
+
visit(shadowRoot);
|
|
286
|
+
}
|
|
287
|
+
for (const element of root.querySelectorAll("a"))
|
|
288
|
+
element.addEventListener("click", (event) => {
|
|
289
|
+
event.preventDefault();
|
|
290
|
+
});
|
|
291
|
+
if ("adoptedStyleSheets" in root) {
|
|
292
|
+
const adoptedSheets = [...root.adoptedStyleSheets];
|
|
293
|
+
for (const element of root.querySelectorAll(`template[__playwright_style_sheet_]`)) {
|
|
294
|
+
const template = element;
|
|
295
|
+
const sheet = new CSSStyleSheet();
|
|
296
|
+
sheet.replaceSync(template.getAttribute("__playwright_style_sheet_"));
|
|
297
|
+
adoptedSheets.push(sheet);
|
|
298
|
+
}
|
|
299
|
+
root.adoptedStyleSheets = adoptedSheets;
|
|
300
|
+
}
|
|
301
|
+
canvasElements.push(...root.querySelectorAll("canvas"));
|
|
302
|
+
};
|
|
303
|
+
const onLoad = () => {
|
|
304
|
+
win.removeEventListener("load", onLoad);
|
|
305
|
+
for (const element of scrollTops) {
|
|
306
|
+
element.scrollTop = +element.getAttribute("__playwright_scroll_top_");
|
|
307
|
+
element.removeAttribute("__playwright_scroll_top_");
|
|
308
|
+
if (frameBoundingRectsInfo.frames.has(element))
|
|
309
|
+
frameBoundingRectsInfo.frames.get(element).scrollTop = element.scrollTop;
|
|
310
|
+
}
|
|
311
|
+
for (const element of scrollLefts) {
|
|
312
|
+
element.scrollLeft = +element.getAttribute("__playwright_scroll_left_");
|
|
313
|
+
element.removeAttribute("__playwright_scroll_left_");
|
|
314
|
+
if (frameBoundingRectsInfo.frames.has(element))
|
|
315
|
+
frameBoundingRectsInfo.frames.get(element).scrollLeft = element.scrollLeft;
|
|
316
|
+
}
|
|
317
|
+
win.document.styleSheets[0].disabled = true;
|
|
318
|
+
const search = new URL(win.location.href).searchParams;
|
|
319
|
+
const isTopFrame = win === topSnapshotWindow;
|
|
320
|
+
if (search.get("pointX") && search.get("pointY")) {
|
|
321
|
+
const pointX = +search.get("pointX");
|
|
322
|
+
const pointY = +search.get("pointY");
|
|
323
|
+
const hasInputTarget = search.has("hasInputTarget");
|
|
324
|
+
const hasTargetElements = targetElements.length > 0;
|
|
325
|
+
const roots = win.document.documentElement ? [win.document.documentElement] : [];
|
|
326
|
+
for (const target of hasTargetElements ? targetElements : roots) {
|
|
327
|
+
const pointElement = win.document.createElement("x-pw-pointer");
|
|
328
|
+
pointElement.style.position = "fixed";
|
|
329
|
+
pointElement.style.backgroundColor = "#f44336";
|
|
330
|
+
pointElement.style.width = "20px";
|
|
331
|
+
pointElement.style.height = "20px";
|
|
332
|
+
pointElement.style.borderRadius = "10px";
|
|
333
|
+
pointElement.style.margin = "-10px 0 0 -10px";
|
|
334
|
+
pointElement.style.zIndex = "2147483646";
|
|
335
|
+
pointElement.style.display = "flex";
|
|
336
|
+
pointElement.style.alignItems = "center";
|
|
337
|
+
pointElement.style.justifyContent = "center";
|
|
338
|
+
if (hasTargetElements) {
|
|
339
|
+
const box = target.getBoundingClientRect();
|
|
340
|
+
const centerX = box.left + box.width / 2;
|
|
341
|
+
const centerY = box.top + box.height / 2;
|
|
342
|
+
pointElement.style.left = centerX + "px";
|
|
343
|
+
pointElement.style.top = centerY + "px";
|
|
344
|
+
if (isTopFrame && (Math.abs(centerX - pointX) >= 10 || Math.abs(centerY - pointY) >= 10)) {
|
|
345
|
+
const warningElement = win.document.createElement("x-pw-pointer-warning");
|
|
346
|
+
warningElement.textContent = "\u26A0";
|
|
347
|
+
warningElement.style.fontSize = "19px";
|
|
348
|
+
warningElement.style.color = "white";
|
|
349
|
+
warningElement.style.marginTop = "-3.5px";
|
|
350
|
+
warningElement.style.userSelect = "none";
|
|
351
|
+
pointElement.appendChild(warningElement);
|
|
352
|
+
pointElement.setAttribute("title", kPointerWarningTitle);
|
|
353
|
+
}
|
|
354
|
+
win.document.documentElement.appendChild(pointElement);
|
|
355
|
+
} else if (isTopFrame && !hasInputTarget) {
|
|
356
|
+
pointElement.style.left = pointX + "px";
|
|
357
|
+
pointElement.style.top = pointY + "px";
|
|
358
|
+
win.document.documentElement.appendChild(pointElement);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if (canvasElements.length > 0) {
|
|
363
|
+
let drawCheckerboard2 = function(context, canvas) {
|
|
364
|
+
function createCheckerboardPattern() {
|
|
365
|
+
const pattern = win.document.createElement("canvas");
|
|
366
|
+
pattern.width = pattern.width / Math.floor(pattern.width / 24);
|
|
367
|
+
pattern.height = pattern.height / Math.floor(pattern.height / 24);
|
|
368
|
+
const context2 = pattern.getContext("2d");
|
|
369
|
+
context2.fillStyle = "lightgray";
|
|
370
|
+
context2.fillRect(0, 0, pattern.width, pattern.height);
|
|
371
|
+
context2.fillStyle = "white";
|
|
372
|
+
context2.fillRect(0, 0, pattern.width / 2, pattern.height / 2);
|
|
373
|
+
context2.fillRect(pattern.width / 2, pattern.height / 2, pattern.width, pattern.height);
|
|
374
|
+
return context2.createPattern(pattern, "repeat");
|
|
375
|
+
}
|
|
376
|
+
context.fillStyle = createCheckerboardPattern();
|
|
377
|
+
context.fillRect(0, 0, canvas.width, canvas.height);
|
|
378
|
+
};
|
|
379
|
+
var drawCheckerboard = drawCheckerboard2;
|
|
380
|
+
const img = new Image();
|
|
381
|
+
img.onload = () => {
|
|
382
|
+
for (const canvas of canvasElements) {
|
|
383
|
+
const context = canvas.getContext("2d");
|
|
384
|
+
const boundingRectAttribute = canvas.getAttribute("__playwright_bounding_rect__");
|
|
385
|
+
canvas.removeAttribute("__playwright_bounding_rect__");
|
|
386
|
+
if (!boundingRectAttribute)
|
|
387
|
+
continue;
|
|
388
|
+
let boundingRect;
|
|
389
|
+
try {
|
|
390
|
+
boundingRect = JSON.parse(boundingRectAttribute);
|
|
391
|
+
} catch (e) {
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
let currWindow = win;
|
|
395
|
+
while (currWindow !== topSnapshotWindow) {
|
|
396
|
+
const iframe = currWindow.frameElement;
|
|
397
|
+
currWindow = currWindow.parent;
|
|
398
|
+
const iframeInfo = currWindow["__playwright_frame_bounding_rects__"]?.frames.get(iframe);
|
|
399
|
+
if (!iframeInfo?.boundingRect)
|
|
400
|
+
break;
|
|
401
|
+
const leftOffset = iframeInfo.boundingRect.left - iframeInfo.scrollLeft;
|
|
402
|
+
const topOffset = iframeInfo.boundingRect.top - iframeInfo.scrollTop;
|
|
403
|
+
boundingRect.left += leftOffset;
|
|
404
|
+
boundingRect.top += topOffset;
|
|
405
|
+
boundingRect.right += leftOffset;
|
|
406
|
+
boundingRect.bottom += topOffset;
|
|
407
|
+
}
|
|
408
|
+
const { width, height } = topSnapshotWindow["__playwright_frame_bounding_rects__"].viewport;
|
|
409
|
+
boundingRect.left = boundingRect.left / width;
|
|
410
|
+
boundingRect.top = boundingRect.top / height;
|
|
411
|
+
boundingRect.right = boundingRect.right / width;
|
|
412
|
+
boundingRect.bottom = boundingRect.bottom / height;
|
|
413
|
+
const partiallyUncaptured = boundingRect.right > 1 || boundingRect.bottom > 1;
|
|
414
|
+
const fullyUncaptured = boundingRect.left > 1 || boundingRect.top > 1;
|
|
415
|
+
if (fullyUncaptured) {
|
|
416
|
+
canvas.title = `Playwright couldn't capture canvas contents because it's located outside the viewport.`;
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
drawCheckerboard2(context, canvas);
|
|
420
|
+
if (shouldPopulateCanvasFromScreenshot) {
|
|
421
|
+
context.drawImage(img, boundingRect.left * img.width, boundingRect.top * img.height, (boundingRect.right - boundingRect.left) * img.width, (boundingRect.bottom - boundingRect.top) * img.height, 0, 0, canvas.width, canvas.height);
|
|
422
|
+
if (partiallyUncaptured)
|
|
423
|
+
canvas.title = `Playwright couldn't capture full canvas contents because it's located partially outside the viewport.`;
|
|
424
|
+
else
|
|
425
|
+
canvas.title = `Canvas contents are displayed on a best-effort basis based on viewport screenshots taken during test execution.`;
|
|
426
|
+
} else {
|
|
427
|
+
canvas.title = "Canvas content display is disabled.";
|
|
428
|
+
}
|
|
429
|
+
if (isUnderTest)
|
|
430
|
+
console.log(`canvas drawn:`, JSON.stringify([boundingRect.left, boundingRect.top, boundingRect.right - boundingRect.left, boundingRect.bottom - boundingRect.top].map((v) => Math.floor(v * 100))));
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
img.onerror = () => {
|
|
434
|
+
for (const canvas of canvasElements) {
|
|
435
|
+
const context = canvas.getContext("2d");
|
|
436
|
+
drawCheckerboard2(context, canvas);
|
|
437
|
+
canvas.title = `Playwright couldn't show canvas contents because the screenshot failed to load.`;
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
img.src = location.href.replace("/snapshot", "/closest-screenshot");
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
const onDOMContentLoaded = () => visit(win.document);
|
|
444
|
+
win.addEventListener("load", onLoad);
|
|
445
|
+
win.addEventListener("DOMContentLoaded", onDOMContentLoaded);
|
|
446
|
+
}
|
|
447
|
+
return `
|
|
448
|
+
(${applyPlaywrightAttributes.toString()})(${JSON.stringify(viewport)}${targetIds.map((id) => `, "${id}"`).join("")})`;
|
|
449
|
+
}
|
|
450
|
+
const schemas = ["about:", "blob:", "data:", "file:", "ftp:", "http:", "https:", "mailto:", "sftp:", "ws:", "wss:"];
|
|
451
|
+
const kLegacyBlobPrefix = "http://playwright.bloburl/#";
|
|
452
|
+
function rewriteURLForCustomProtocol(href) {
|
|
453
|
+
if (href.startsWith(kLegacyBlobPrefix))
|
|
454
|
+
href = href.substring(kLegacyBlobPrefix.length);
|
|
455
|
+
try {
|
|
456
|
+
const url = new URL(href);
|
|
457
|
+
if (url.protocol === "javascript:" || url.protocol === "vbscript:")
|
|
458
|
+
return "javascript:void(0)";
|
|
459
|
+
const isBlob = url.protocol === "blob:";
|
|
460
|
+
const isFile = url.protocol === "file:";
|
|
461
|
+
if (!isBlob && !isFile && schemas.includes(url.protocol))
|
|
462
|
+
return href;
|
|
463
|
+
const prefix = "pw-" + url.protocol.slice(0, url.protocol.length - 1);
|
|
464
|
+
if (!isFile)
|
|
465
|
+
url.protocol = "https:";
|
|
466
|
+
url.hostname = url.hostname ? `${prefix}--${url.hostname}` : prefix;
|
|
467
|
+
if (isFile) {
|
|
468
|
+
url.protocol = "https:";
|
|
469
|
+
}
|
|
470
|
+
return url.toString();
|
|
471
|
+
} catch {
|
|
472
|
+
return href;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
const urlInCSSRegex = /url\(['"]?([\w-]+:)\/\//ig;
|
|
476
|
+
function rewriteURLsInStyleSheetForCustomProtocol(text) {
|
|
477
|
+
return text.replace(urlInCSSRegex, (match, protocol) => {
|
|
478
|
+
const isBlob = protocol === "blob:";
|
|
479
|
+
const isFile = protocol === "file:";
|
|
480
|
+
if (!isBlob && !isFile && schemas.includes(protocol))
|
|
481
|
+
return match;
|
|
482
|
+
return match.replace(protocol + "//", `https://pw-${protocol.slice(0, -1)}--`);
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
const urlToEscapeRegex1 = /url\(\s*'([^']*)'\s*\)/ig;
|
|
486
|
+
const urlToEscapeRegex2 = /url\(\s*"([^"]*)"\s*\)/ig;
|
|
487
|
+
function escapeURLsInStyleSheet(text) {
|
|
488
|
+
const replacer = (match, url) => {
|
|
489
|
+
if (url.includes("</"))
|
|
490
|
+
return match.replace(url, encodeURI(url));
|
|
491
|
+
return match;
|
|
492
|
+
};
|
|
493
|
+
return text.replace(urlToEscapeRegex1, replacer).replace(urlToEscapeRegex2, replacer);
|
|
494
|
+
}
|
|
495
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
496
|
+
0 && (module.exports = {
|
|
497
|
+
SnapshotRenderer,
|
|
498
|
+
rewriteURLForCustomProtocol
|
|
499
|
+
});
|
|
@@ -0,0 +1,120 @@
|
|
|
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 snapshotServer_exports = {};
|
|
20
|
+
__export(snapshotServer_exports, {
|
|
21
|
+
SnapshotServer: () => SnapshotServer
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(snapshotServer_exports);
|
|
24
|
+
class SnapshotServer {
|
|
25
|
+
constructor(snapshotStorage, resourceLoader) {
|
|
26
|
+
this._snapshotIds = /* @__PURE__ */ new Map();
|
|
27
|
+
this._snapshotStorage = snapshotStorage;
|
|
28
|
+
this._resourceLoader = resourceLoader;
|
|
29
|
+
}
|
|
30
|
+
serveSnapshot(pageOrFrameId, searchParams, snapshotUrl) {
|
|
31
|
+
const snapshot = this._snapshot(pageOrFrameId, searchParams);
|
|
32
|
+
if (!snapshot)
|
|
33
|
+
return new Response(null, { status: 404 });
|
|
34
|
+
const renderedSnapshot = snapshot.render();
|
|
35
|
+
this._snapshotIds.set(snapshotUrl, snapshot);
|
|
36
|
+
return new Response(renderedSnapshot.html, { status: 200, headers: { "Content-Type": "text/html; charset=utf-8" } });
|
|
37
|
+
}
|
|
38
|
+
async serveClosestScreenshot(pageOrFrameId, searchParams) {
|
|
39
|
+
const snapshot = this._snapshot(pageOrFrameId, searchParams);
|
|
40
|
+
const sha1 = snapshot?.closestScreenshot();
|
|
41
|
+
if (!sha1)
|
|
42
|
+
return new Response(null, { status: 404 });
|
|
43
|
+
return new Response(await this._resourceLoader(sha1));
|
|
44
|
+
}
|
|
45
|
+
serveSnapshotInfo(pageOrFrameId, searchParams) {
|
|
46
|
+
const snapshot = this._snapshot(pageOrFrameId, searchParams);
|
|
47
|
+
return this._respondWithJson(snapshot ? {
|
|
48
|
+
viewport: snapshot.viewport(),
|
|
49
|
+
url: snapshot.snapshot().frameUrl,
|
|
50
|
+
timestamp: snapshot.snapshot().timestamp,
|
|
51
|
+
wallTime: snapshot.snapshot().wallTime
|
|
52
|
+
} : {
|
|
53
|
+
error: "No snapshot found"
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
_snapshot(pageOrFrameId, params) {
|
|
57
|
+
const name = params.get("name");
|
|
58
|
+
return this._snapshotStorage.snapshotByName(pageOrFrameId, name);
|
|
59
|
+
}
|
|
60
|
+
_respondWithJson(object) {
|
|
61
|
+
return new Response(JSON.stringify(object), {
|
|
62
|
+
status: 200,
|
|
63
|
+
headers: {
|
|
64
|
+
"Cache-Control": "public, max-age=31536000",
|
|
65
|
+
"Content-Type": "application/json"
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
async serveResource(requestUrlAlternatives, method, snapshotUrl) {
|
|
70
|
+
let resource;
|
|
71
|
+
const snapshot = this._snapshotIds.get(snapshotUrl);
|
|
72
|
+
for (const requestUrl of requestUrlAlternatives) {
|
|
73
|
+
resource = snapshot?.resourceByUrl(removeHash(requestUrl), method);
|
|
74
|
+
if (resource)
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
if (!resource)
|
|
78
|
+
return new Response(null, { status: 404 });
|
|
79
|
+
const sha1 = resource.response.content._sha1;
|
|
80
|
+
const content = sha1 ? await this._resourceLoader(sha1) || new Blob([]) : new Blob([]);
|
|
81
|
+
let contentType = resource.response.content.mimeType;
|
|
82
|
+
const isTextEncoding = /^text\/|^application\/(javascript|json)/.test(contentType);
|
|
83
|
+
if (isTextEncoding && !contentType.includes("charset"))
|
|
84
|
+
contentType = `${contentType}; charset=utf-8`;
|
|
85
|
+
const headers = new Headers();
|
|
86
|
+
if (contentType !== "x-unknown")
|
|
87
|
+
headers.set("Content-Type", contentType);
|
|
88
|
+
for (const { name, value } of resource.response.headers)
|
|
89
|
+
headers.set(name, value);
|
|
90
|
+
headers.delete("Content-Encoding");
|
|
91
|
+
headers.delete("Access-Control-Allow-Origin");
|
|
92
|
+
headers.set("Access-Control-Allow-Origin", "*");
|
|
93
|
+
headers.delete("Content-Length");
|
|
94
|
+
headers.set("Content-Length", String(content.size));
|
|
95
|
+
if (this._snapshotStorage.hasResourceOverride(resource.request.url))
|
|
96
|
+
headers.set("Cache-Control", "no-store, no-cache, max-age=0");
|
|
97
|
+
else
|
|
98
|
+
headers.set("Cache-Control", "public, max-age=31536000");
|
|
99
|
+
const { status } = resource.response;
|
|
100
|
+
const isNullBodyStatus = status === 101 || status === 204 || status === 205 || status === 304;
|
|
101
|
+
return new Response(isNullBodyStatus ? null : content, {
|
|
102
|
+
headers,
|
|
103
|
+
status: resource.response.status,
|
|
104
|
+
statusText: resource.response.statusText
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function removeHash(url) {
|
|
109
|
+
try {
|
|
110
|
+
const u = new URL(url);
|
|
111
|
+
u.hash = "";
|
|
112
|
+
return u.toString();
|
|
113
|
+
} catch (e) {
|
|
114
|
+
return url;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
118
|
+
0 && (module.exports = {
|
|
119
|
+
SnapshotServer
|
|
120
|
+
});
|