patchright-core 1.56.1 → 1.58.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/ThirdPartyNotices.txt +3134 -560
  2. package/bin/install_webkit_wsl.ps1 +1 -3
  3. package/browsers.json +21 -22
  4. package/lib/cli/program.js +16 -60
  5. package/lib/client/api.js +3 -3
  6. package/lib/client/browser.js +3 -5
  7. package/lib/client/browserContext.js +62 -8
  8. package/lib/client/browserType.js +4 -3
  9. package/lib/client/connection.js +4 -0
  10. package/lib/client/consoleMessage.js +5 -1
  11. package/lib/client/electron.js +1 -1
  12. package/lib/client/elementHandle.js +3 -0
  13. package/lib/client/events.js +5 -1
  14. package/lib/client/fetch.js +3 -4
  15. package/lib/client/frame.js +10 -1
  16. package/lib/client/locator.js +12 -1
  17. package/lib/client/network.js +5 -1
  18. package/lib/client/page.js +31 -6
  19. package/lib/client/pageAgent.js +64 -0
  20. package/lib/client/platform.js +3 -0
  21. package/lib/client/playwright.js +1 -5
  22. package/lib/client/tracing.js +7 -5
  23. package/lib/client/worker.js +22 -0
  24. package/lib/generated/clockSource.js +1 -1
  25. package/lib/generated/injectedScriptSource.js +1 -1
  26. package/lib/generated/pollingRecorderSource.js +1 -1
  27. package/lib/inProcessFactory.js +0 -2
  28. package/lib/mcpBundle.js +84 -0
  29. package/lib/mcpBundleImpl/index.js +147 -0
  30. package/lib/protocol/serializers.js +5 -0
  31. package/lib/protocol/validator.js +112 -50
  32. package/lib/remote/playwrightServer.js +1 -2
  33. package/lib/server/agent/actionRunner.js +335 -0
  34. package/lib/server/agent/actions.js +128 -0
  35. package/lib/server/agent/codegen.js +111 -0
  36. package/lib/server/agent/context.js +150 -0
  37. package/lib/server/agent/expectTools.js +156 -0
  38. package/lib/server/agent/pageAgent.js +204 -0
  39. package/lib/server/agent/performTools.js +262 -0
  40. package/lib/server/agent/tool.js +109 -0
  41. package/lib/server/android/android.js +1 -1
  42. package/lib/server/artifact.js +1 -1
  43. package/lib/server/bidi/bidiBrowser.js +81 -22
  44. package/lib/server/bidi/bidiChromium.js +9 -13
  45. package/lib/server/bidi/bidiConnection.js +1 -0
  46. package/lib/server/bidi/bidiDeserializer.js +116 -0
  47. package/lib/server/bidi/bidiExecutionContext.js +75 -29
  48. package/lib/server/bidi/bidiFirefox.js +7 -9
  49. package/lib/server/bidi/bidiNetworkManager.js +1 -1
  50. package/lib/server/bidi/bidiPage.js +61 -30
  51. package/lib/server/bidi/third_party/bidiProtocolCore.js +1 -0
  52. package/lib/server/browserContext.js +43 -36
  53. package/lib/server/browserType.js +12 -4
  54. package/lib/server/chromium/chromium.js +26 -21
  55. package/lib/server/chromium/chromiumSwitches.js +12 -3
  56. package/lib/server/chromium/crBrowser.js +30 -12
  57. package/lib/server/chromium/crConnection.js +0 -5
  58. package/lib/server/chromium/crCoverage.js +13 -1
  59. package/lib/server/chromium/crDevTools.js +0 -2
  60. package/lib/server/chromium/crNetworkManager.js +107 -18
  61. package/lib/server/chromium/crPage.js +68 -124
  62. package/lib/server/chromium/crServiceWorker.js +14 -1
  63. package/lib/server/codegen/javascript.js +6 -29
  64. package/lib/server/console.js +5 -1
  65. package/lib/server/deviceDescriptorsSource.json +56 -56
  66. package/lib/server/dispatchers/browserContextDispatcher.js +26 -8
  67. package/lib/server/dispatchers/dispatcher.js +6 -13
  68. package/lib/server/dispatchers/frameDispatcher.js +1 -1
  69. package/lib/server/dispatchers/jsHandleDispatcher.js +2 -2
  70. package/lib/server/dispatchers/pageAgentDispatcher.js +96 -0
  71. package/lib/server/dispatchers/pageDispatcher.js +14 -22
  72. package/lib/server/dispatchers/playwrightDispatcher.js +0 -4
  73. package/lib/server/dom.js +12 -3
  74. package/lib/server/electron/electron.js +6 -3
  75. package/lib/server/firefox/ffBrowser.js +10 -20
  76. package/lib/server/firefox/ffConnection.js +0 -5
  77. package/lib/server/firefox/ffNetworkManager.js +2 -2
  78. package/lib/server/firefox/ffPage.js +18 -24
  79. package/lib/server/firefox/firefox.js +18 -9
  80. package/lib/server/frameSelectors.js +18 -8
  81. package/lib/server/frames.js +257 -87
  82. package/lib/server/input.js +7 -3
  83. package/lib/server/instrumentation.js +3 -0
  84. package/lib/server/javascript.js +8 -4
  85. package/lib/server/launchApp.js +2 -1
  86. package/lib/server/localUtils.js +4 -8
  87. package/lib/server/network.js +50 -12
  88. package/lib/server/page.js +112 -126
  89. package/lib/server/playwright.js +2 -4
  90. package/lib/server/progress.js +26 -6
  91. package/lib/server/recorder/recorderApp.js +80 -101
  92. package/lib/server/recorder.js +3 -2
  93. package/lib/server/registry/browserFetcher.js +6 -4
  94. package/lib/server/registry/index.js +278 -189
  95. package/lib/server/registry/oopDownloadBrowserMain.js +9 -2
  96. package/lib/server/screencast.js +190 -0
  97. package/lib/server/screenshotter.js +6 -0
  98. package/lib/server/socksClientCertificatesInterceptor.js +1 -1
  99. package/lib/server/trace/recorder/snapshotter.js +17 -8
  100. package/lib/server/trace/recorder/snapshotterInjected.js +30 -72
  101. package/lib/server/trace/recorder/tracing.js +31 -21
  102. package/lib/server/trace/viewer/traceParser.js +72 -0
  103. package/lib/server/trace/viewer/traceViewer.js +45 -40
  104. package/lib/server/utils/comparators.js +3 -25
  105. package/lib/server/utils/expectUtils.js +87 -2
  106. package/lib/server/utils/hostPlatform.js +30 -3
  107. package/lib/server/utils/httpServer.js +5 -20
  108. package/lib/server/utils/imageUtils.js +141 -0
  109. package/lib/server/utils/network.js +55 -40
  110. package/lib/server/utils/nodePlatform.js +6 -0
  111. package/lib/server/{chromium/videoRecorder.js → videoRecorder.js} +35 -24
  112. package/lib/server/webkit/webkit.js +5 -16
  113. package/lib/server/webkit/wkBrowser.js +2 -6
  114. package/lib/server/webkit/wkConnection.js +1 -6
  115. package/lib/server/webkit/wkInterceptableRequest.js +29 -1
  116. package/lib/server/webkit/wkPage.js +76 -51
  117. package/lib/server/webkit/wkWorkers.js +2 -1
  118. package/lib/utils/isomorphic/ariaSnapshot.js +63 -0
  119. package/lib/utils/isomorphic/locatorGenerators.js +24 -8
  120. package/lib/utils/isomorphic/lruCache.js +51 -0
  121. package/lib/utils/isomorphic/mimeType.js +1 -1
  122. package/lib/utils/isomorphic/protocolFormatter.js +3 -0
  123. package/lib/utils/isomorphic/protocolMetainfo.js +11 -2
  124. package/lib/utils/isomorphic/stringUtils.js +49 -0
  125. package/lib/utils/isomorphic/trace/entries.js +16 -0
  126. package/lib/utils/isomorphic/trace/snapshotRenderer.js +499 -0
  127. package/lib/utils/isomorphic/trace/snapshotServer.js +120 -0
  128. package/lib/utils/isomorphic/trace/snapshotStorage.js +89 -0
  129. package/lib/utils/isomorphic/trace/traceLoader.js +131 -0
  130. package/lib/utils/isomorphic/trace/traceModel.js +365 -0
  131. package/lib/utils/isomorphic/trace/traceModernizer.js +400 -0
  132. package/lib/utils/isomorphic/trace/versions/traceV3.js +16 -0
  133. package/lib/utils/isomorphic/trace/versions/traceV4.js +16 -0
  134. package/lib/utils/isomorphic/trace/versions/traceV5.js +16 -0
  135. package/lib/utils/isomorphic/trace/versions/traceV6.js +16 -0
  136. package/lib/utils/isomorphic/trace/versions/traceV7.js +16 -0
  137. package/lib/utils/isomorphic/trace/versions/traceV8.js +16 -0
  138. package/lib/utils/isomorphic/urlMatch.js +19 -5
  139. package/lib/utils/isomorphic/yaml.js +84 -0
  140. package/lib/utils.js +4 -0
  141. package/lib/utilsBundle.js +1 -1
  142. package/lib/utilsBundleImpl/index.js +124 -124
  143. package/lib/vite/htmlReport/index.html +21 -21
  144. package/lib/vite/recorder/assets/codeMirrorModule-CFUTFUO7.js +32 -0
  145. package/lib/vite/recorder/assets/{codeMirrorModule-C3UTv-Ge.css → codeMirrorModule-DYBRYzYX.css} +1 -1
  146. package/lib/vite/recorder/assets/{index-Ri0uHF7I.css → index-BSjZa4pk.css} +1 -1
  147. package/lib/vite/recorder/assets/index-CVkBxsGf.js +193 -0
  148. package/lib/vite/recorder/index.html +2 -2
  149. package/lib/vite/traceViewer/assets/codeMirrorModule-BVA4h_ZY.js +32 -0
  150. package/lib/vite/traceViewer/assets/defaultSettingsView-CjfmcdOz.js +266 -0
  151. package/lib/vite/traceViewer/{codeMirrorModule.C3UTv-Ge.css → codeMirrorModule.DYBRYzYX.css} +1 -1
  152. package/lib/vite/traceViewer/defaultSettingsView.7ch9cixO.css +1 -0
  153. package/lib/vite/traceViewer/index.BVu7tZDe.css +1 -0
  154. package/lib/vite/traceViewer/index.BtyWtaE-.js +2 -0
  155. package/lib/vite/traceViewer/index.html +6 -6
  156. package/lib/vite/traceViewer/manifest.webmanifest +16 -0
  157. package/lib/vite/traceViewer/snapshot.html +3 -3
  158. package/lib/vite/traceViewer/sw.bundle.js +5 -3
  159. package/lib/vite/traceViewer/uiMode.fyrXARf2.js +5 -0
  160. package/lib/vite/traceViewer/uiMode.html +3 -3
  161. package/package.json +2 -1
  162. package/types/protocol.d.ts +939 -245
  163. package/types/types.d.ts +143 -153
  164. package/lib/client/accessibility.js +0 -49
  165. package/lib/server/accessibility.js +0 -69
  166. package/lib/server/bidi/third_party/bidiDeserializer.js +0 -98
  167. package/lib/server/chromium/crAccessibility.js +0 -263
  168. package/lib/server/firefox/ffAccessibility.js +0 -238
  169. package/lib/server/trace/test/inMemorySnapshotter.js +0 -87
  170. package/lib/server/webkit/wkAccessibility.js +0 -237
  171. package/lib/server/webkit/wsl/webkit-wsl-transport-client.js +0 -74
  172. package/lib/server/webkit/wsl/webkit-wsl-transport-server.js +0 -113
  173. package/lib/vite/recorder/assets/codeMirrorModule-RJCXzfmE.js +0 -24
  174. package/lib/vite/recorder/assets/index-Y-X2TGJv.js +0 -193
  175. package/lib/vite/traceViewer/assets/codeMirrorModule-rbQPefq7.js +0 -24
  176. package/lib/vite/traceViewer/assets/defaultSettingsView-CLbol9XR.js +0 -265
  177. package/lib/vite/traceViewer/defaultSettingsView.TQ8_7ybu.css +0 -1
  178. package/lib/vite/traceViewer/index.I8N9v4jT.css +0 -1
  179. package/lib/vite/traceViewer/index.zIVi6mN9.js +0 -2
  180. package/lib/vite/traceViewer/uiMode.B_CpmIpF.js +0 -5
@@ -0,0 +1,72 @@
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 traceParser_exports = {};
30
+ __export(traceParser_exports, {
31
+ ZipTraceLoaderBackend: () => ZipTraceLoaderBackend
32
+ });
33
+ module.exports = __toCommonJS(traceParser_exports);
34
+ var import_url = __toESM(require("url"));
35
+ var import_zipFile = require("../../utils/zipFile");
36
+ class ZipTraceLoaderBackend {
37
+ constructor(traceFile) {
38
+ this._traceFile = traceFile;
39
+ this._zipFile = new import_zipFile.ZipFile(traceFile);
40
+ }
41
+ isLive() {
42
+ return false;
43
+ }
44
+ traceURL() {
45
+ return import_url.default.pathToFileURL(this._traceFile).toString();
46
+ }
47
+ async entryNames() {
48
+ return await this._zipFile.entries();
49
+ }
50
+ async hasEntry(entryName) {
51
+ const entries = await this.entryNames();
52
+ return entries.includes(entryName);
53
+ }
54
+ async readText(entryName) {
55
+ try {
56
+ const buffer = await this._zipFile.read(entryName);
57
+ return buffer.toString("utf-8");
58
+ } catch {
59
+ }
60
+ }
61
+ async readBlob(entryName) {
62
+ try {
63
+ const buffer = await this._zipFile.read(entryName);
64
+ return new Blob([new Uint8Array(buffer)]);
65
+ } catch {
66
+ }
67
+ }
68
+ }
69
+ // Annotate the CommonJS export names for ESM import in node:
70
+ 0 && (module.exports = {
71
+ ZipTraceLoaderBackend
72
+ });
@@ -46,13 +46,22 @@ var import_launchApp = require("../../launchApp");
46
46
  var import_launchApp2 = require("../../launchApp");
47
47
  var import_playwright = require("../../playwright");
48
48
  var import_progress = require("../../progress");
49
- function validateTraceUrls(traceUrls) {
50
- for (const traceUrl of traceUrls) {
51
- let traceFile = traceUrl;
52
- if (traceUrl.endsWith(".json"))
53
- traceFile = traceUrl.substring(0, traceUrl.length - ".json".length);
54
- if (!traceUrl.startsWith("http://") && !traceUrl.startsWith("https://") && !import_fs.default.existsSync(traceFile) && !import_fs.default.existsSync(traceFile + ".trace"))
55
- throw new Error(`Trace file ${traceUrl} does not exist!`);
49
+ const tracesDirMarker = "traces.dir";
50
+ function validateTraceUrlOrPath(traceFileOrUrl) {
51
+ if (!traceFileOrUrl)
52
+ return traceFileOrUrl;
53
+ if (traceFileOrUrl.startsWith("http://") || traceFileOrUrl.startsWith("https://"))
54
+ return traceFileOrUrl;
55
+ let traceFile = traceFileOrUrl;
56
+ if (traceFile.endsWith(".json"))
57
+ return toFilePathUrl(traceFile);
58
+ try {
59
+ const stat = import_fs.default.statSync(traceFile);
60
+ if (stat.isDirectory())
61
+ traceFile = import_path.default.join(traceFile, tracesDirMarker);
62
+ return toFilePathUrl(traceFile);
63
+ } catch {
64
+ throw new Error(`Trace file ${traceFileOrUrl} does not exist!`);
56
65
  }
57
66
  }
58
67
  async function startTraceViewerServer(options) {
@@ -60,24 +69,18 @@ async function startTraceViewerServer(options) {
60
69
  server.routePrefix("/trace", (request, response) => {
61
70
  const url = new URL("http://localhost" + request.url);
62
71
  const relativePath = url.pathname.slice("/trace".length);
63
- if (process.env.PW_HMR) {
64
- response.appendHeader("Access-Control-Allow-Origin", "http://localhost:44223");
65
- }
66
- if (relativePath.endsWith("/stall.js"))
67
- return true;
68
72
  if (relativePath.startsWith("/file")) {
69
73
  try {
70
74
  const filePath = url.searchParams.get("path");
71
75
  if (import_fs.default.existsSync(filePath))
72
76
  return server.serveFile(request, response, url.searchParams.get("path"));
73
77
  if (filePath.endsWith(".json")) {
74
- const traceName = filePath.substring(0, filePath.length - ".json".length);
75
- response.statusCode = 200;
76
- response.setHeader("Content-Type", "application/json");
77
- response.end(JSON.stringify(traceDescriptor(traceName)));
78
- return true;
78
+ const fullPrefix = filePath.substring(0, filePath.length - ".json".length);
79
+ return sendTraceDescriptor(response, import_path.default.dirname(fullPrefix), import_path.default.basename(fullPrefix));
79
80
  }
80
- } catch (e) {
81
+ if (filePath.endsWith(tracesDirMarker))
82
+ return sendTraceDescriptor(response, import_path.default.dirname(filePath));
83
+ } catch {
81
84
  }
82
85
  response.statusCode = 404;
83
86
  response.end();
@@ -93,11 +96,11 @@ async function startTraceViewerServer(options) {
93
96
  await server.start({ preferredPort: port, host });
94
97
  return server;
95
98
  }
96
- async function installRootRedirect(server, traceUrls, options) {
99
+ async function installRootRedirect(server, traceUrl, options) {
97
100
  const params = new URLSearchParams();
98
101
  if (import_path.default.sep !== import_path.default.posix.sep)
99
102
  params.set("pathSeparator", import_path.default.sep);
100
- for (const traceUrl of traceUrls)
103
+ if (traceUrl)
101
104
  params.append("trace", traceUrl);
102
105
  if (server.wsGuid())
103
106
  params.append("ws", server.wsGuid());
@@ -115,12 +118,7 @@ async function installRootRedirect(server, traceUrls, options) {
115
118
  params.append("project", project);
116
119
  for (const reporter of options.reporter || [])
117
120
  params.append("reporter", reporter);
118
- let baseUrl = ".";
119
- if (process.env.PW_HMR) {
120
- baseUrl = "http://localhost:44223";
121
- params.set("server", server.urlPrefix("precise"));
122
- }
123
- const urlPath = `${baseUrl}/trace/${options.webApp || "index.html"}?${params.toString()}`;
121
+ const urlPath = `./trace/${options.webApp || "index.html"}?${params.toString()}`;
124
122
  server.routePath("/", (_, response) => {
125
123
  response.statusCode = 302;
126
124
  response.setHeader("Location", urlPath);
@@ -128,19 +126,19 @@ async function installRootRedirect(server, traceUrls, options) {
128
126
  return true;
129
127
  });
130
128
  }
131
- async function runTraceViewerApp(traceUrls, browserName, options, exitOnClose) {
132
- validateTraceUrls(traceUrls);
129
+ async function runTraceViewerApp(traceUrl, browserName, options, exitOnClose) {
130
+ traceUrl = validateTraceUrlOrPath(traceUrl);
133
131
  const server = await startTraceViewerServer(options);
134
- await installRootRedirect(server, traceUrls, options);
132
+ await installRootRedirect(server, traceUrl, options);
135
133
  const page = await openTraceViewerApp(server.urlPrefix("precise"), browserName, options);
136
134
  if (exitOnClose)
137
135
  page.on("close", () => (0, import_utils.gracefullyProcessExitDoNotHang)(0));
138
136
  return page;
139
137
  }
140
- async function runTraceInBrowser(traceUrls, options) {
141
- validateTraceUrls(traceUrls);
138
+ async function runTraceInBrowser(traceUrl, options) {
139
+ traceUrl = validateTraceUrlOrPath(traceUrl);
142
140
  const server = await startTraceViewerServer(options);
143
- await installRootRedirect(server, traceUrls, options);
141
+ await installRootRedirect(server, traceUrl, options);
144
142
  await openTraceInBrowser(server.urlPrefix("human-readable"));
145
143
  }
146
144
  async function openTraceViewerApp(url, browserName, options) {
@@ -180,8 +178,8 @@ async function openTraceInBrowser(url) {
180
178
  class StdinServer {
181
179
  constructor() {
182
180
  process.stdin.on("data", (data) => {
183
- const url = data.toString().trim();
184
- if (url === this._traceUrl)
181
+ const url = validateTraceUrlOrPath(data.toString().trim());
182
+ if (!url || url === this._traceUrl)
185
183
  return;
186
184
  if (url.endsWith(".json"))
187
185
  this._pollLoadTrace(url);
@@ -212,23 +210,30 @@ class StdinServer {
212
210
  }, 500);
213
211
  }
214
212
  }
215
- function traceDescriptor(traceName) {
213
+ function sendTraceDescriptor(response, traceDir, tracePrefix) {
214
+ response.statusCode = 200;
215
+ response.setHeader("Content-Type", "application/json");
216
+ response.end(JSON.stringify(traceDescriptor(traceDir, tracePrefix)));
217
+ return true;
218
+ }
219
+ function traceDescriptor(traceDir, tracePrefix) {
216
220
  const result = {
217
221
  entries: []
218
222
  };
219
- const traceDir = import_path.default.dirname(traceName);
220
- const traceFile = import_path.default.basename(traceName);
221
223
  for (const name of import_fs.default.readdirSync(traceDir)) {
222
- if (name.startsWith(traceFile))
223
- result.entries.push({ name, path: import_path.default.join(traceDir, name) });
224
+ if (!tracePrefix || name.startsWith(tracePrefix))
225
+ result.entries.push({ name, path: toFilePathUrl(import_path.default.join(traceDir, name)) });
224
226
  }
225
227
  const resourcesDir = import_path.default.join(traceDir, "resources");
226
228
  if (import_fs.default.existsSync(resourcesDir)) {
227
229
  for (const name of import_fs.default.readdirSync(resourcesDir))
228
- result.entries.push({ name: "resources/" + name, path: import_path.default.join(resourcesDir, name) });
230
+ result.entries.push({ name: "resources/" + name, path: toFilePathUrl(import_path.default.join(resourcesDir, name)) });
229
231
  }
230
232
  return result;
231
233
  }
234
+ function toFilePathUrl(filePath) {
235
+ return `file?path=${encodeURIComponent(filePath)}`;
236
+ }
232
237
  // Annotate the CommonJS export names for ESM import in node:
233
238
  0 && (module.exports = {
234
239
  installRootRedirect,
@@ -37,6 +37,7 @@ var import_pixelmatch = __toESM(require("../../third_party/pixelmatch"));
37
37
  var import_utilsBundle = require("../../utilsBundle");
38
38
  var import_utilsBundle2 = require("../../utilsBundle");
39
39
  var import_utilsBundle3 = require("../../utilsBundle");
40
+ var import_imageUtils = require("./imageUtils");
40
41
  function getComparator(mimeType) {
41
42
  if (mimeType === "image/png")
42
43
  return compareImages.bind(null, "image/png");
@@ -66,8 +67,8 @@ function compareImages(mimeType, actualBuffer, expectedBuffer, options = {}) {
66
67
  let sizesMismatchError = "";
67
68
  if (expected.width !== actual.width || expected.height !== actual.height) {
68
69
  sizesMismatchError = `Expected an image ${expected.width}px by ${expected.height}px, received ${actual.width}px by ${actual.height}px. `;
69
- actual = resizeImage(actual, size);
70
- expected = resizeImage(expected, size);
70
+ actual = (0, import_imageUtils.padImageToSize)(actual, size);
71
+ expected = (0, import_imageUtils.padImageToSize)(expected, size);
71
72
  }
72
73
  const diff2 = new import_utilsBundle3.PNG({ width: size.width, height: size.height });
73
74
  let count;
@@ -131,29 +132,6 @@ function compareText(actual, expectedBuffer) {
131
132
  const errorMessage = coloredLines.join("\n");
132
133
  return { errorMessage };
133
134
  }
134
- function resizeImage(image, size) {
135
- if (image.width === size.width && image.height === size.height)
136
- return image;
137
- const buffer = new Uint8Array(size.width * size.height * 4);
138
- for (let y = 0; y < size.height; y++) {
139
- for (let x = 0; x < size.width; x++) {
140
- const to = (y * size.width + x) * 4;
141
- if (y < image.height && x < image.width) {
142
- const from = (y * image.width + x) * 4;
143
- buffer[to] = image.data[from];
144
- buffer[to + 1] = image.data[from + 1];
145
- buffer[to + 2] = image.data[from + 2];
146
- buffer[to + 3] = image.data[from + 3];
147
- } else {
148
- buffer[to] = 0;
149
- buffer[to + 1] = 0;
150
- buffer[to + 2] = 0;
151
- buffer[to + 3] = 0;
152
- }
153
- }
154
- }
155
- return { data: Buffer.from(buffer), width: size.width, height: size.height };
156
- }
157
135
  // Annotate the CommonJS export names for ESM import in node:
158
136
  0 && (module.exports = {
159
137
  compareBuffersOrStrings,
@@ -18,10 +18,16 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var expectUtils_exports = {};
20
20
  __export(expectUtils_exports, {
21
- serializeExpectedTextValues: () => serializeExpectedTextValues
21
+ callLogText: () => callLogText,
22
+ formatMatcherMessage: () => formatMatcherMessage,
23
+ printReceivedStringContainExpectedResult: () => printReceivedStringContainExpectedResult,
24
+ printReceivedStringContainExpectedSubstring: () => printReceivedStringContainExpectedSubstring,
25
+ serializeExpectedTextValues: () => serializeExpectedTextValues,
26
+ simpleMatcherUtils: () => simpleMatcherUtils
22
27
  });
23
28
  module.exports = __toCommonJS(expectUtils_exports);
24
29
  var import_rtti = require("../../utils/isomorphic/rtti");
30
+ var import_utilsBundle = require("../../utilsBundle");
25
31
  function serializeExpectedTextValues(items, options = {}) {
26
32
  return items.map((i) => ({
27
33
  string: (0, import_rtti.isString)(i) ? i : void 0,
@@ -32,7 +38,86 @@ function serializeExpectedTextValues(items, options = {}) {
32
38
  normalizeWhiteSpace: options.normalizeWhiteSpace
33
39
  }));
34
40
  }
41
+ const printSubstring = (val) => val.replace(/"|\\/g, "\\$&");
42
+ const printReceivedStringContainExpectedSubstring = (utils, received, start, length) => utils.RECEIVED_COLOR(
43
+ '"' + printSubstring(received.slice(0, start)) + utils.INVERTED_COLOR(printSubstring(received.slice(start, start + length))) + printSubstring(received.slice(start + length)) + '"'
44
+ );
45
+ const printReceivedStringContainExpectedResult = (utils, received, result) => result === null ? utils.printReceived(received) : printReceivedStringContainExpectedSubstring(
46
+ utils,
47
+ received,
48
+ result.index,
49
+ result[0].length
50
+ );
51
+ function formatMatcherMessage(utils, details) {
52
+ const receiver = details.receiver ?? (details.locator ? "locator" : "page");
53
+ let message = utils.DIM_COLOR("expect(") + utils.RECEIVED_COLOR(receiver) + utils.DIM_COLOR(")" + (details.promise ? "." + details.promise : "") + (details.isNot ? ".not" : "") + ".") + details.matcherName + utils.DIM_COLOR("(") + utils.EXPECTED_COLOR(details.expectation) + utils.DIM_COLOR(")") + " failed\n\n";
54
+ const diffLines = details.printedDiff?.split("\n");
55
+ if (diffLines?.length === 2) {
56
+ details.printedExpected = diffLines[0];
57
+ details.printedReceived = diffLines[1];
58
+ details.printedDiff = void 0;
59
+ }
60
+ const align = !details.errorMessage && details.printedExpected?.startsWith("Expected:") && (!details.printedReceived || details.printedReceived.startsWith("Received:"));
61
+ if (details.locator)
62
+ message += `Locator: ${align ? " " : ""}${details.locator}
63
+ `;
64
+ if (details.printedExpected)
65
+ message += details.printedExpected + "\n";
66
+ if (details.printedReceived)
67
+ message += details.printedReceived + "\n";
68
+ if (details.timedOut && details.timeout)
69
+ message += `Timeout: ${align ? " " : ""}${details.timeout}ms
70
+ `;
71
+ if (details.printedDiff)
72
+ message += details.printedDiff + "\n";
73
+ if (details.errorMessage) {
74
+ message += details.errorMessage;
75
+ if (!details.errorMessage.endsWith("\n"))
76
+ message += "\n";
77
+ }
78
+ message += callLogText(utils, details.log);
79
+ return message;
80
+ }
81
+ const callLogText = (utils, log) => {
82
+ if (!log || !log.some((l) => !!l))
83
+ return "";
84
+ return `
85
+ Call log:
86
+ ${utils.DIM_COLOR(log.join("\n"))}
87
+ `;
88
+ };
89
+ function printValue(value) {
90
+ try {
91
+ return JSON.stringify(value);
92
+ } catch {
93
+ return String(value);
94
+ }
95
+ }
96
+ function printReceived(value) {
97
+ return import_utilsBundle.colors.red(printValue(value));
98
+ }
99
+ function printExpected(value) {
100
+ return import_utilsBundle.colors.green(printValue(value));
101
+ }
102
+ const simpleMatcherUtils = {
103
+ DIM_COLOR: import_utilsBundle.colors.dim,
104
+ RECEIVED_COLOR: import_utilsBundle.colors.red,
105
+ EXPECTED_COLOR: import_utilsBundle.colors.green,
106
+ INVERTED_COLOR: import_utilsBundle.colors.inverse,
107
+ printReceived,
108
+ printExpected,
109
+ printDiffOrStringify: (expected, received, expectedLabel, receivedLabel) => {
110
+ const maxLength = Math.max(expectedLabel.length, receivedLabel.length) + 2;
111
+ return `${expectedLabel}: `.padEnd(maxLength) + printExpected(expected) + `
112
+ ` + `${receivedLabel}: `.padEnd(maxLength) + printReceived(received);
113
+ }
114
+ };
35
115
  // Annotate the CommonJS export names for ESM import in node:
36
116
  0 && (module.exports = {
37
- serializeExpectedTextValues
117
+ callLogText,
118
+ formatMatcherMessage,
119
+ printReceivedStringContainExpectedResult,
120
+ printReceivedStringContainExpectedSubstring,
121
+ serializeExpectedTextValues,
122
+ simpleMatcherUtils
38
123
  });
@@ -28,10 +28,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var hostPlatform_exports = {};
30
30
  __export(hostPlatform_exports, {
31
+ hasGpuMac: () => hasGpuMac,
31
32
  hostPlatform: () => hostPlatform,
32
- isOfficiallySupportedPlatform: () => isOfficiallySupportedPlatform
33
+ isOfficiallySupportedPlatform: () => isOfficiallySupportedPlatform,
34
+ shortPlatform: () => shortPlatform
33
35
  });
34
36
  module.exports = __toCommonJS(hostPlatform_exports);
37
+ var import_child_process = require("child_process");
35
38
  var import_os = __toESM(require("os"));
36
39
  var import_linuxUtils = require("./linuxUtils");
37
40
  function calculatePlatform() {
@@ -97,15 +100,39 @@ function calculatePlatform() {
97
100
  if (distroInfo?.version === "")
98
101
  return { hostPlatform: "debian13" + archSuffix, isOfficiallySupportedPlatform: isOfficiallySupportedPlatform2 };
99
102
  }
100
- return { hostPlatform: "ubuntu20.04" + archSuffix, isOfficiallySupportedPlatform: false };
103
+ return { hostPlatform: "ubuntu24.04" + archSuffix, isOfficiallySupportedPlatform: false };
101
104
  }
102
105
  if (platform === "win32")
103
106
  return { hostPlatform: "win64", isOfficiallySupportedPlatform: true };
104
107
  return { hostPlatform: "<unknown>", isOfficiallySupportedPlatform: false };
105
108
  }
106
109
  const { hostPlatform, isOfficiallySupportedPlatform } = calculatePlatform();
110
+ function toShortPlatform(hostPlatform2) {
111
+ if (hostPlatform2 === "<unknown>")
112
+ return "<unknown>";
113
+ if (hostPlatform2 === "win64")
114
+ return "win-x64";
115
+ if (hostPlatform2.startsWith("mac"))
116
+ return hostPlatform2.endsWith("arm64") ? "mac-arm64" : "mac-x64";
117
+ return hostPlatform2.endsWith("arm64") ? "linux-arm64" : "linux-x64";
118
+ }
119
+ const shortPlatform = toShortPlatform(hostPlatform);
120
+ let hasGpuMacValue;
121
+ function hasGpuMac() {
122
+ try {
123
+ if (hasGpuMacValue === void 0) {
124
+ const output = (0, import_child_process.execSync)("system_profiler SPDisplaysDataType", { stdio: ["ignore", "pipe", "ignore"] }).toString();
125
+ hasGpuMacValue = output.includes("Metal: Supported") || output.includes("Metal Support: Metal");
126
+ }
127
+ return hasGpuMacValue;
128
+ } catch (e) {
129
+ return false;
130
+ }
131
+ }
107
132
  // Annotate the CommonJS export names for ESM import in node:
108
133
  0 && (module.exports = {
134
+ hasGpuMac,
109
135
  hostPlatform,
110
- isOfficiallySupportedPlatform
136
+ isOfficiallySupportedPlatform,
137
+ shortPlatform
111
138
  });
@@ -36,7 +36,6 @@ var import_path = __toESM(require("path"));
36
36
  var import_utilsBundle = require("../../utilsBundle");
37
37
  var import_crypto = require("./crypto");
38
38
  var import_assert = require("../../utils/isomorphic/assert");
39
- var import_manualPromise = require("../../utils/isomorphic/manualPromise");
40
39
  var import_network = require("./network");
41
40
  class HttpServer {
42
41
  constructor() {
@@ -59,20 +58,6 @@ class HttpServer {
59
58
  port() {
60
59
  return this._port;
61
60
  }
62
- async _tryStart(port, host) {
63
- const errorPromise = new import_manualPromise.ManualPromise();
64
- const errorListener = (error) => errorPromise.reject(error);
65
- this._server.on("error", errorListener);
66
- try {
67
- this._server.listen(port, host);
68
- await Promise.race([
69
- new Promise((cb) => this._server.once("listening", cb)),
70
- errorPromise
71
- ]);
72
- } finally {
73
- this._server.removeListener("error", errorListener);
74
- }
75
- }
76
61
  createWebSocket(transport, guid) {
77
62
  (0, import_assert.assert)(!this._wsGuid, "can only create one main websocket transport per server");
78
63
  this._wsGuid = guid || (0, import_crypto.createGuid)();
@@ -100,17 +85,17 @@ class HttpServer {
100
85
  async start(options = {}) {
101
86
  (0, import_assert.assert)(!this._started, "server already started");
102
87
  this._started = true;
103
- const host = options.host || "localhost";
88
+ const host = options.host;
104
89
  if (options.preferredPort) {
105
90
  try {
106
- await this._tryStart(options.preferredPort, host);
91
+ await (0, import_network.startHttpServer)(this._server, { port: options.preferredPort, host });
107
92
  } catch (e) {
108
93
  if (!e || !e.message || !e.message.includes("EADDRINUSE"))
109
94
  throw e;
110
- await this._tryStart(void 0, host);
95
+ await (0, import_network.startHttpServer)(this._server, { host });
111
96
  }
112
97
  } else {
113
- await this._tryStart(options.port, host);
98
+ await (0, import_network.startHttpServer)(this._server, { port: options.port, host });
114
99
  }
115
100
  const address = this._server.address();
116
101
  (0, import_assert.assert)(address, "Could not bind server socket");
@@ -121,7 +106,7 @@ class HttpServer {
121
106
  this._port = address.port;
122
107
  const resolvedHost = address.family === "IPv4" ? address.address : `[${address.address}]`;
123
108
  this._urlPrefixPrecise = `http://${resolvedHost}:${address.port}`;
124
- this._urlPrefixHumanReadable = `http://${host}:${address.port}`;
109
+ this._urlPrefixHumanReadable = `http://${host ?? "localhost"}:${address.port}`;
125
110
  }
126
111
  }
127
112
  async stop() {
@@ -0,0 +1,141 @@
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 imageUtils_exports = {};
20
+ __export(imageUtils_exports, {
21
+ padImageToSize: () => padImageToSize,
22
+ scaleImageToSize: () => scaleImageToSize
23
+ });
24
+ module.exports = __toCommonJS(imageUtils_exports);
25
+ function padImageToSize(image, size) {
26
+ if (image.width === size.width && image.height === size.height)
27
+ return image;
28
+ const buffer = new Uint8Array(size.width * size.height * 4);
29
+ for (let y = 0; y < size.height; y++) {
30
+ for (let x = 0; x < size.width; x++) {
31
+ const to = (y * size.width + x) * 4;
32
+ if (y < image.height && x < image.width) {
33
+ const from = (y * image.width + x) * 4;
34
+ buffer[to] = image.data[from];
35
+ buffer[to + 1] = image.data[from + 1];
36
+ buffer[to + 2] = image.data[from + 2];
37
+ buffer[to + 3] = image.data[from + 3];
38
+ } else {
39
+ buffer[to] = 0;
40
+ buffer[to + 1] = 0;
41
+ buffer[to + 2] = 0;
42
+ buffer[to + 3] = 0;
43
+ }
44
+ }
45
+ }
46
+ return { data: Buffer.from(buffer), width: size.width, height: size.height };
47
+ }
48
+ function scaleImageToSize(image, size) {
49
+ const { data: src, width: w1, height: h1 } = image;
50
+ const w2 = Math.max(1, Math.floor(size.width));
51
+ const h2 = Math.max(1, Math.floor(size.height));
52
+ if (w1 === w2 && h1 === h2)
53
+ return image;
54
+ if (w1 <= 0 || h1 <= 0)
55
+ throw new Error("Invalid input image");
56
+ if (size.width <= 0 || size.height <= 0 || !isFinite(size.width) || !isFinite(size.height))
57
+ throw new Error("Invalid output dimensions");
58
+ const clamp = (v, lo, hi) => v < lo ? lo : v > hi ? hi : v;
59
+ const weights = (t, o) => {
60
+ const t2 = t * t, t3 = t2 * t;
61
+ o[0] = -0.5 * t + 1 * t2 - 0.5 * t3;
62
+ o[1] = 1 - 2.5 * t2 + 1.5 * t3;
63
+ o[2] = 0.5 * t + 2 * t2 - 1.5 * t3;
64
+ o[3] = -0.5 * t2 + 0.5 * t3;
65
+ };
66
+ const srcRowStride = w1 * 4;
67
+ const dstRowStride = w2 * 4;
68
+ const xOff = new Int32Array(w2 * 4);
69
+ const xW = new Float32Array(w2 * 4);
70
+ const wx = new Float32Array(4);
71
+ const xScale = w1 / w2;
72
+ for (let x = 0; x < w2; x++) {
73
+ const sx = (x + 0.5) * xScale - 0.5;
74
+ const sxi = Math.floor(sx);
75
+ const t = sx - sxi;
76
+ weights(t, wx);
77
+ const b = x * 4;
78
+ const i0 = clamp(sxi - 1, 0, w1 - 1);
79
+ const i1 = clamp(sxi + 0, 0, w1 - 1);
80
+ const i2 = clamp(sxi + 1, 0, w1 - 1);
81
+ const i3 = clamp(sxi + 2, 0, w1 - 1);
82
+ xOff[b + 0] = i0 << 2;
83
+ xOff[b + 1] = i1 << 2;
84
+ xOff[b + 2] = i2 << 2;
85
+ xOff[b + 3] = i3 << 2;
86
+ xW[b + 0] = wx[0];
87
+ xW[b + 1] = wx[1];
88
+ xW[b + 2] = wx[2];
89
+ xW[b + 3] = wx[3];
90
+ }
91
+ const yRow = new Int32Array(h2 * 4);
92
+ const yW = new Float32Array(h2 * 4);
93
+ const wy = new Float32Array(4);
94
+ const yScale = h1 / h2;
95
+ for (let y = 0; y < h2; y++) {
96
+ const sy = (y + 0.5) * yScale - 0.5;
97
+ const syi = Math.floor(sy);
98
+ const t = sy - syi;
99
+ weights(t, wy);
100
+ const b = y * 4;
101
+ const j0 = clamp(syi - 1, 0, h1 - 1);
102
+ const j1 = clamp(syi + 0, 0, h1 - 1);
103
+ const j2 = clamp(syi + 1, 0, h1 - 1);
104
+ const j3 = clamp(syi + 2, 0, h1 - 1);
105
+ yRow[b + 0] = j0 * srcRowStride;
106
+ yRow[b + 1] = j1 * srcRowStride;
107
+ yRow[b + 2] = j2 * srcRowStride;
108
+ yRow[b + 3] = j3 * srcRowStride;
109
+ yW[b + 0] = wy[0];
110
+ yW[b + 1] = wy[1];
111
+ yW[b + 2] = wy[2];
112
+ yW[b + 3] = wy[3];
113
+ }
114
+ const dst = new Uint8Array(w2 * h2 * 4);
115
+ for (let y = 0; y < h2; y++) {
116
+ const yb = y * 4;
117
+ const rb0 = yRow[yb + 0], rb1 = yRow[yb + 1], rb2 = yRow[yb + 2], rb3 = yRow[yb + 3];
118
+ const wy0 = yW[yb + 0], wy1 = yW[yb + 1], wy2 = yW[yb + 2], wy3 = yW[yb + 3];
119
+ const dstBase = y * dstRowStride;
120
+ for (let x = 0; x < w2; x++) {
121
+ const xb = x * 4;
122
+ const xo0 = xOff[xb + 0], xo1 = xOff[xb + 1], xo2 = xOff[xb + 2], xo3 = xOff[xb + 3];
123
+ const wx0 = xW[xb + 0], wx1 = xW[xb + 1], wx2 = xW[xb + 2], wx3 = xW[xb + 3];
124
+ const di = dstBase + (x << 2);
125
+ for (let c = 0; c < 4; c++) {
126
+ const r0 = src[rb0 + xo0 + c] * wx0 + src[rb0 + xo1 + c] * wx1 + src[rb0 + xo2 + c] * wx2 + src[rb0 + xo3 + c] * wx3;
127
+ const r1 = src[rb1 + xo0 + c] * wx0 + src[rb1 + xo1 + c] * wx1 + src[rb1 + xo2 + c] * wx2 + src[rb1 + xo3 + c] * wx3;
128
+ const r2 = src[rb2 + xo0 + c] * wx0 + src[rb2 + xo1 + c] * wx1 + src[rb2 + xo2 + c] * wx2 + src[rb2 + xo3 + c] * wx3;
129
+ const r3 = src[rb3 + xo0 + c] * wx0 + src[rb3 + xo1 + c] * wx1 + src[rb3 + xo2 + c] * wx2 + src[rb3 + xo3 + c] * wx3;
130
+ const v = r0 * wy0 + r1 * wy1 + r2 * wy2 + r3 * wy3;
131
+ dst[di + c] = v < 0 ? 0 : v > 255 ? 255 : v | 0;
132
+ }
133
+ }
134
+ }
135
+ return { data: Buffer.from(dst.buffer), width: w2, height: h2 };
136
+ }
137
+ // Annotate the CommonJS export names for ESM import in node:
138
+ 0 && (module.exports = {
139
+ padImageToSize,
140
+ scaleImageToSize
141
+ });