@smoothdeploy/playwright 1.57.1 → 1.58.1-beta-1770383926000

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.

Potentially problematic release.


This version of @smoothdeploy/playwright might be problematic. Click here for more details.

Files changed (264) hide show
  1. package/ThirdPartyNotices.txt +1188 -65
  2. package/lib/agents/agentParser.js +89 -0
  3. package/lib/agents/generateAgents.js +27 -74
  4. package/lib/agents/generateAgents.js.map +7 -0
  5. package/lib/agents/playwright-test-planner.agent.md +1 -0
  6. package/lib/common/config.js +6 -4
  7. package/lib/common/config.js.map +7 -0
  8. package/lib/common/configLoader.js.map +7 -0
  9. package/lib/common/esmLoaderHost.js +2 -0
  10. package/lib/common/esmLoaderHost.js.map +7 -0
  11. package/lib/common/expectBundle.js +2 -17
  12. package/lib/common/expectBundle.js.map +7 -0
  13. package/lib/common/expectBundleImpl.js +132 -132
  14. package/lib/common/expectBundleImpl.js.map +7 -0
  15. package/lib/common/fixtures.js.map +7 -0
  16. package/lib/common/globals.js.map +7 -0
  17. package/lib/common/ipc.js.map +7 -0
  18. package/lib/common/poolBuilder.js.map +7 -0
  19. package/lib/common/process.js +28 -0
  20. package/lib/common/process.js.map +7 -0
  21. package/lib/common/suiteUtils.js.map +7 -0
  22. package/lib/common/test.js.map +7 -0
  23. package/lib/common/testLoader.js.map +7 -0
  24. package/lib/common/testType.js.map +7 -0
  25. package/lib/common/validators.js +10 -10
  26. package/lib/common/validators.js.map +7 -0
  27. package/lib/fsWatcher.js.map +7 -0
  28. package/lib/index.js +205 -12
  29. package/lib/index.js.map +7 -0
  30. package/lib/internalsForTest.js.map +7 -0
  31. package/lib/isomorphic/events.js.map +7 -0
  32. package/lib/isomorphic/folders.js.map +7 -0
  33. package/lib/isomorphic/stringInternPool.js.map +7 -0
  34. package/lib/isomorphic/teleReceiver.js +15 -2
  35. package/lib/isomorphic/teleReceiver.js.map +7 -0
  36. package/lib/isomorphic/teleSuiteUpdater.js +24 -4
  37. package/lib/isomorphic/teleSuiteUpdater.js.map +7 -0
  38. package/lib/isomorphic/testServerConnection.js.map +7 -0
  39. package/lib/isomorphic/testServerInterface.js.map +7 -0
  40. package/lib/isomorphic/testTree.js +13 -18
  41. package/lib/isomorphic/testTree.js.map +7 -0
  42. package/lib/isomorphic/types.d.js.map +7 -0
  43. package/lib/loader/loaderMain.js.map +7 -0
  44. package/lib/matchers/expect.js +2 -15
  45. package/lib/matchers/expect.js.map +7 -0
  46. package/lib/matchers/matcherHint.js +1 -44
  47. package/lib/matchers/matcherHint.js.map +7 -0
  48. package/lib/matchers/matchers.js +3 -2
  49. package/lib/matchers/matchers.js.map +7 -0
  50. package/lib/matchers/toBeTruthy.js +5 -3
  51. package/lib/matchers/toBeTruthy.js.map +7 -0
  52. package/lib/matchers/toEqual.js +4 -3
  53. package/lib/matchers/toEqual.js.map +7 -0
  54. package/lib/matchers/toHaveURL.js +5 -6
  55. package/lib/matchers/toHaveURL.js.map +7 -0
  56. package/lib/matchers/toMatchAriaSnapshot.js +5 -5
  57. package/lib/matchers/toMatchAriaSnapshot.js.map +7 -0
  58. package/lib/matchers/toMatchSnapshot.js +9 -8
  59. package/lib/matchers/toMatchSnapshot.js.map +7 -0
  60. package/lib/matchers/toMatchText.js +9 -9
  61. package/lib/matchers/toMatchText.js.map +7 -0
  62. package/lib/mcp/browser/actions.d.js.map +7 -0
  63. package/lib/mcp/browser/browserContextFactory.js +62 -29
  64. package/lib/mcp/browser/browserContextFactory.js.map +7 -0
  65. package/lib/mcp/browser/browserServerBackend.js +17 -9
  66. package/lib/mcp/browser/browserServerBackend.js.map +7 -0
  67. package/lib/mcp/browser/codegen.js.map +7 -0
  68. package/lib/mcp/browser/config.js +65 -12
  69. package/lib/mcp/browser/config.js.map +7 -0
  70. package/lib/mcp/browser/context.js +71 -94
  71. package/lib/mcp/browser/context.js.map +7 -0
  72. package/lib/mcp/browser/response.js +172 -131
  73. package/lib/mcp/browser/response.js.map +7 -0
  74. package/lib/mcp/browser/sessionLog.js +19 -104
  75. package/lib/mcp/browser/sessionLog.js.map +7 -0
  76. package/lib/mcp/browser/tab.js +92 -41
  77. package/lib/mcp/browser/tab.js.map +7 -0
  78. package/lib/mcp/browser/tools/common.js +8 -6
  79. package/lib/mcp/browser/tools/common.js.map +7 -0
  80. package/lib/mcp/browser/tools/console.js +7 -5
  81. package/lib/mcp/browser/tools/console.js.map +7 -0
  82. package/lib/mcp/browser/tools/dialogs.js +4 -4
  83. package/lib/mcp/browser/tools/dialogs.js.map +7 -0
  84. package/lib/mcp/browser/tools/evaluate.js +11 -19
  85. package/lib/mcp/browser/tools/evaluate.js.map +7 -0
  86. package/lib/mcp/browser/tools/files.js +3 -3
  87. package/lib/mcp/browser/tools/files.js.map +7 -0
  88. package/lib/mcp/browser/tools/form.js +9 -19
  89. package/lib/mcp/browser/tools/form.js.map +7 -0
  90. package/lib/mcp/browser/tools/install.js +6 -3
  91. package/lib/mcp/browser/tools/install.js.map +7 -0
  92. package/lib/mcp/browser/tools/keyboard.js +34 -11
  93. package/lib/mcp/browser/tools/keyboard.js.map +7 -0
  94. package/lib/mcp/browser/tools/mouse.js +11 -11
  95. package/lib/mcp/browser/tools/mouse.js.map +7 -0
  96. package/lib/mcp/browser/tools/navigate.js +14 -5
  97. package/lib/mcp/browser/tools/navigate.js.map +7 -0
  98. package/lib/mcp/browser/tools/network.js +20 -11
  99. package/lib/mcp/browser/tools/network.js.map +7 -0
  100. package/lib/mcp/browser/tools/open.js +57 -0
  101. package/lib/mcp/browser/tools/pdf.js +9 -19
  102. package/lib/mcp/browser/tools/pdf.js.map +7 -0
  103. package/lib/mcp/browser/tools/runCode.js +11 -8
  104. package/lib/mcp/browser/tools/runCode.js.map +7 -0
  105. package/lib/mcp/browser/tools/screenshot.js +16 -29
  106. package/lib/mcp/browser/tools/screenshot.js.map +7 -0
  107. package/lib/mcp/browser/tools/snapshot.js +21 -29
  108. package/lib/mcp/browser/tools/snapshot.js.map +7 -0
  109. package/lib/mcp/browser/tools/tabs.js +12 -12
  110. package/lib/mcp/browser/tools/tabs.js.map +7 -0
  111. package/lib/mcp/browser/tools/tool.js +2 -4
  112. package/lib/mcp/browser/tools/tool.js.map +7 -0
  113. package/lib/mcp/browser/tools/tracing.js +6 -6
  114. package/lib/mcp/browser/tools/tracing.js.map +7 -0
  115. package/lib/mcp/browser/tools/utils.js +49 -44
  116. package/lib/mcp/browser/tools/utils.js.map +7 -0
  117. package/lib/mcp/browser/tools/verify.js +24 -34
  118. package/lib/mcp/browser/tools/verify.js.map +7 -0
  119. package/lib/mcp/browser/tools/wait.js +6 -6
  120. package/lib/mcp/browser/tools/wait.js.map +7 -0
  121. package/lib/mcp/browser/tools.js +3 -1
  122. package/lib/mcp/browser/tools.js.map +7 -0
  123. package/lib/mcp/browser/watchdog.js.map +7 -0
  124. package/lib/mcp/config.d.js.map +7 -0
  125. package/lib/mcp/extension/cdpRelay.js +1 -1
  126. package/lib/mcp/extension/cdpRelay.js.map +7 -0
  127. package/lib/mcp/extension/extensionContextFactory.js +6 -5
  128. package/lib/mcp/extension/extensionContextFactory.js.map +7 -0
  129. package/lib/mcp/extension/protocol.js.map +7 -0
  130. package/lib/mcp/index.js.map +7 -0
  131. package/lib/mcp/log.js.map +7 -0
  132. package/lib/mcp/program.js +15 -20
  133. package/lib/mcp/program.js.map +7 -0
  134. package/lib/mcp/sdk/bundle.js.map +7 -0
  135. package/lib/mcp/sdk/exports.js +0 -2
  136. package/lib/mcp/sdk/exports.js.map +7 -0
  137. package/lib/mcp/sdk/http.js +20 -55
  138. package/lib/mcp/sdk/http.js.map +7 -0
  139. package/lib/mcp/sdk/inProcessTransport.js.map +7 -0
  140. package/lib/mcp/sdk/proxyBackend.js.map +7 -0
  141. package/lib/mcp/sdk/server.js +29 -4
  142. package/lib/mcp/sdk/server.js.map +7 -0
  143. package/lib/mcp/sdk/tool.js +2 -2
  144. package/lib/mcp/sdk/tool.js.map +7 -0
  145. package/lib/mcp/terminal/cli.js +296 -0
  146. package/lib/mcp/terminal/command.js +56 -0
  147. package/lib/mcp/terminal/commands.js +333 -0
  148. package/lib/mcp/terminal/daemon.js +129 -0
  149. package/lib/mcp/terminal/help.json +32 -0
  150. package/lib/mcp/terminal/helpGenerator.js +88 -0
  151. package/lib/mcp/terminal/socketConnection.js +80 -0
  152. package/lib/mcp/test/browserBackend.js +3 -13
  153. package/lib/mcp/test/browserBackend.js.map +7 -0
  154. package/lib/mcp/test/generatorTools.js +9 -9
  155. package/lib/mcp/test/generatorTools.js.map +7 -0
  156. package/lib/mcp/test/plannerTools.js +23 -22
  157. package/lib/mcp/test/plannerTools.js.map +7 -0
  158. package/lib/mcp/test/seed.js.map +7 -0
  159. package/lib/mcp/test/streams.js.map +7 -0
  160. package/lib/mcp/test/testBackend.js +6 -6
  161. package/lib/mcp/test/testBackend.js.map +7 -0
  162. package/lib/mcp/test/testContext.js +9 -3
  163. package/lib/mcp/test/testContext.js.map +7 -0
  164. package/lib/mcp/test/testTool.js.map +7 -0
  165. package/lib/mcp/test/testTools.js +12 -10
  166. package/lib/mcp/test/testTools.js.map +7 -0
  167. package/lib/mcpBundleImpl.js.map +7 -0
  168. package/lib/plugins/gitCommitInfoPlugin.js.map +7 -0
  169. package/lib/plugins/index.js.map +7 -0
  170. package/lib/plugins/webServerPlugin.js.map +7 -0
  171. package/lib/program.js +18 -4
  172. package/lib/program.js.map +7 -0
  173. package/lib/reporters/base.js +29 -4
  174. package/lib/reporters/base.js.map +7 -0
  175. package/lib/reporters/blob.js +3 -0
  176. package/lib/reporters/blob.js.map +7 -0
  177. package/lib/reporters/dot.js +17 -0
  178. package/lib/reporters/dot.js.map +7 -0
  179. package/lib/reporters/empty.js.map +7 -0
  180. package/lib/reporters/github.js.map +7 -0
  181. package/lib/reporters/html.js +13 -3
  182. package/lib/reporters/html.js.map +7 -0
  183. package/lib/reporters/internalReporter.js +6 -0
  184. package/lib/reporters/internalReporter.js.map +7 -0
  185. package/lib/reporters/json.js.map +7 -0
  186. package/lib/reporters/junit.js.map +7 -0
  187. package/lib/reporters/line.js +18 -0
  188. package/lib/reporters/line.js.map +7 -0
  189. package/lib/reporters/list.js +22 -0
  190. package/lib/reporters/list.js.map +7 -0
  191. package/lib/reporters/listModeReporter.js.map +7 -0
  192. package/lib/reporters/markdown.js.map +7 -0
  193. package/lib/reporters/merge.js +25 -8
  194. package/lib/reporters/merge.js.map +7 -0
  195. package/lib/reporters/multiplexer.js +8 -0
  196. package/lib/reporters/multiplexer.js.map +7 -0
  197. package/lib/reporters/reporterV2.js.map +7 -0
  198. package/lib/reporters/smoothdeploy.js +191 -0
  199. package/lib/reporters/teleEmitter.js +22 -4
  200. package/lib/reporters/teleEmitter.js.map +7 -0
  201. package/lib/reporters/versions/blobV1.js.map +7 -0
  202. package/lib/runner/dispatcher.js +20 -4
  203. package/lib/runner/dispatcher.js.map +7 -0
  204. package/lib/runner/failureTracker.js.map +7 -0
  205. package/lib/runner/lastRun.js.map +7 -0
  206. package/lib/runner/loadUtils.js +2 -2
  207. package/lib/runner/loadUtils.js.map +7 -0
  208. package/lib/runner/loaderHost.js.map +7 -0
  209. package/lib/runner/processHost.js +19 -0
  210. package/lib/runner/processHost.js.map +7 -0
  211. package/lib/runner/projectUtils.js +1 -1
  212. package/lib/runner/projectUtils.js.map +7 -0
  213. package/lib/runner/rebase.js.map +7 -0
  214. package/lib/runner/reporters.js +3 -1
  215. package/lib/runner/reporters.js.map +7 -0
  216. package/lib/runner/sigIntWatcher.js.map +7 -0
  217. package/lib/runner/storage.js +91 -0
  218. package/lib/runner/taskRunner.js.map +7 -0
  219. package/lib/runner/tasks.js.map +7 -0
  220. package/lib/runner/testGroups.js +14 -6
  221. package/lib/runner/testGroups.js.map +7 -0
  222. package/lib/runner/testRunner.js +13 -4
  223. package/lib/runner/testRunner.js.map +7 -0
  224. package/lib/runner/testServer.js +2 -2
  225. package/lib/runner/testServer.js.map +7 -0
  226. package/lib/runner/uiModeReporter.js.map +7 -0
  227. package/lib/runner/vcs.js.map +7 -0
  228. package/lib/runner/watchMode.js +2 -1
  229. package/lib/runner/watchMode.js.map +7 -0
  230. package/lib/runner/workerHost.js +6 -0
  231. package/lib/runner/workerHost.js.map +7 -0
  232. package/lib/third_party/pirates.js.map +7 -0
  233. package/lib/third_party/tsconfig-loader.js.map +7 -0
  234. package/lib/transform/babelBundle.js +3 -0
  235. package/lib/transform/babelBundle.js.map +7 -0
  236. package/lib/transform/babelBundleImpl.js +134 -134
  237. package/lib/transform/babelBundleImpl.js.map +7 -0
  238. package/lib/transform/compilationCache.js +2 -0
  239. package/lib/transform/compilationCache.js.map +7 -0
  240. package/lib/transform/esmLoader.js +10 -11
  241. package/lib/transform/esmLoader.js.map +7 -0
  242. package/lib/transform/md.js +221 -0
  243. package/lib/transform/portTransport.js.map +7 -0
  244. package/lib/transform/transform.js +18 -8
  245. package/lib/transform/transform.js.map +7 -0
  246. package/lib/util.js +3 -6
  247. package/lib/util.js.map +7 -0
  248. package/lib/utilsBundle.js +7 -0
  249. package/lib/utilsBundle.js.map +7 -0
  250. package/lib/utilsBundleImpl.js +51 -48
  251. package/lib/utilsBundleImpl.js.map +7 -0
  252. package/lib/worker/fixtureRunner.js +6 -2
  253. package/lib/worker/fixtureRunner.js.map +7 -0
  254. package/lib/worker/testInfo.js +39 -19
  255. package/lib/worker/testInfo.js.map +7 -0
  256. package/lib/worker/testTracing.js.map +7 -0
  257. package/lib/worker/timeoutManager.js.map +7 -0
  258. package/lib/worker/util.js.map +7 -0
  259. package/lib/worker/workerMain.js +17 -16
  260. package/lib/worker/workerMain.js.map +7 -0
  261. package/package.json +2 -2
  262. package/test.mjs +1 -0
  263. package/types/test.d.ts +26 -6
  264. package/types/testReporter.d.ts +1 -0
@@ -20,7 +20,8 @@ var tab_exports = {};
20
20
  __export(tab_exports, {
21
21
  Tab: () => Tab,
22
22
  TabEvents: () => TabEvents,
23
- renderModalStates: () => renderModalStates
23
+ renderModalStates: () => renderModalStates,
24
+ shouldIncludeMessage: () => shouldIncludeMessage
24
25
  });
25
26
  module.exports = __toCommonJS(tab_exports);
26
27
  var import_events = require("events");
@@ -36,19 +37,20 @@ const TabEvents = {
36
37
  class Tab extends import_events.EventEmitter {
37
38
  constructor(context, page, onPageClose) {
38
39
  super();
39
- this._lastTitle = "about:blank";
40
+ this._lastHeader = { title: "about:blank", url: "about:blank", current: false };
40
41
  this._consoleMessages = [];
41
- this._recentConsoleMessages = [];
42
+ this._downloads = [];
42
43
  this._requests = /* @__PURE__ */ new Set();
43
44
  this._modalStates = [];
44
- this._downloads = [];
45
45
  this._needsFullSnapshot = false;
46
+ this._eventEntries = [];
47
+ this._recentEventEntries = [];
46
48
  this.context = context;
47
49
  this.page = page;
48
50
  this._onPageClose = onPageClose;
49
51
  page.on("console", (event) => this._handleConsoleMessage(messageToConsoleMessage(event)));
50
52
  page.on("pageerror", (error) => this._handleConsoleMessage(pageErrorToConsoleMessage(error)));
51
- page.on("request", (request) => this._requests.add(request));
53
+ page.on("request", (request) => this._handleRequest(request));
52
54
  page.on("close", () => this._onClose());
53
55
  page.on("filechooser", (chooser) => {
54
56
  this.setModalState({
@@ -65,7 +67,7 @@ class Tab extends import_events.EventEmitter {
65
67
  page.setDefaultNavigationTimeout(this.context.config.timeouts.navigation);
66
68
  page.setDefaultTimeout(this.context.config.timeouts.action);
67
69
  page[tabSymbol] = this;
68
- this.initializedPromise = this._initialize();
70
+ this._initializedPromise = this._initialize();
69
71
  }
70
72
  static forPage(page) {
71
73
  return page[tabSymbol];
@@ -105,9 +107,6 @@ class Tab extends import_events.EventEmitter {
105
107
  clearModalState(modalState) {
106
108
  this._modalStates = this._modalStates.filter((state) => state !== modalState);
107
109
  }
108
- modalStatesMarkdown() {
109
- return renderModalStates(this.context, this.modalStates());
110
- }
111
110
  _dialogShown(dialog) {
112
111
  this.setModalState({
113
112
  type: "dialog",
@@ -120,53 +119,68 @@ class Tab extends import_events.EventEmitter {
120
119
  const entry = {
121
120
  download,
122
121
  finished: false,
123
- outputFile: await this.context.outputFile(download.suggestedFilename(), { origin: "web", reason: "Saving download" })
122
+ outputFile: await this.context.outputFile(download.suggestedFilename(), { origin: "web", title: "Saving download" })
124
123
  };
125
124
  this._downloads.push(entry);
125
+ this._addLogEntry({ type: "download-start", wallTime: Date.now(), download: entry });
126
126
  await download.saveAs(entry.outputFile);
127
127
  entry.finished = true;
128
+ this._addLogEntry({ type: "download-finish", wallTime: Date.now(), download: entry });
128
129
  }
129
130
  _clearCollectedArtifacts() {
130
131
  this._consoleMessages.length = 0;
131
- this._recentConsoleMessages.length = 0;
132
+ this._downloads.length = 0;
132
133
  this._requests.clear();
134
+ this._eventEntries.length = 0;
135
+ this._recentEventEntries.length = 0;
136
+ }
137
+ _handleRequest(request) {
138
+ this._requests.add(request);
139
+ this._addLogEntry({ type: "request", wallTime: Date.now(), request });
133
140
  }
134
141
  _handleConsoleMessage(message) {
135
142
  this._consoleMessages.push(message);
136
- this._recentConsoleMessages.push(message);
143
+ this._addLogEntry({ type: "console", wallTime: Date.now(), message });
144
+ }
145
+ _addLogEntry(entry) {
146
+ this._eventEntries.push(entry);
147
+ this._recentEventEntries.push(entry);
137
148
  }
138
149
  _onClose() {
139
150
  this._clearCollectedArtifacts();
140
151
  this._onPageClose(this);
141
152
  }
142
- async updateTitle() {
153
+ async headerSnapshot() {
154
+ let title;
143
155
  await this._raceAgainstModalStates(async () => {
144
- this._lastTitle = await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => page.title());
156
+ title = await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => page.title());
145
157
  });
146
- }
147
- lastTitle() {
148
- return this._lastTitle;
158
+ if (this._lastHeader.title !== title || this._lastHeader.url !== this.page.url() || this._lastHeader.current !== this.isCurrentTab()) {
159
+ this._lastHeader = { title: title ?? "", url: this.page.url(), current: this.isCurrentTab() };
160
+ return { ...this._lastHeader, changed: true };
161
+ }
162
+ return { ...this._lastHeader, changed: false };
149
163
  }
150
164
  isCurrentTab() {
151
165
  return this === this.context.currentTab();
152
166
  }
153
167
  async waitForLoadState(state, options) {
168
+ await this._initializedPromise;
154
169
  await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => page.waitForLoadState(state, options).catch(import_log.logUnhandledError));
155
170
  }
156
171
  async navigate(url) {
172
+ await this._initializedPromise;
157
173
  this._clearCollectedArtifacts();
158
- const downloadEvent = (0, import_utils2.callOnPageNoTrace)(this.page, (page) => page.waitForEvent("download").catch(import_log.logUnhandledError));
174
+ const { promise: downloadEvent, abort: abortDownloadEvent } = (0, import_utils2.eventWaiter)(this.page, "download", 3e3);
159
175
  try {
160
176
  await this.page.goto(url, { waitUntil: "domcontentloaded" });
177
+ abortDownloadEvent();
161
178
  } catch (_e) {
162
179
  const e = _e;
163
180
  const mightBeDownload = e.message.includes("net::ERR_ABORTED") || e.message.includes("Download is starting");
164
181
  if (!mightBeDownload)
165
182
  throw e;
166
- const download = await Promise.race([
167
- downloadEvent,
168
- new Promise((resolve) => setTimeout(resolve, 3e3))
169
- ]);
183
+ const download = await downloadEvent;
170
184
  if (!download)
171
185
  throw e;
172
186
  await new Promise((resolve) => setTimeout(resolve, 500));
@@ -174,40 +188,36 @@ class Tab extends import_events.EventEmitter {
174
188
  }
175
189
  await this.waitForLoadState("load", { timeout: 5e3 });
176
190
  }
177
- async consoleMessages(type) {
178
- await this.initializedPromise;
179
- return this._consoleMessages.filter((message) => type ? message.type === type : true);
191
+ async consoleMessages(level) {
192
+ await this._initializedPromise;
193
+ return this._consoleMessages.filter((message) => shouldIncludeMessage(level, message.type));
180
194
  }
181
195
  async requests() {
182
- await this.initializedPromise;
196
+ await this._initializedPromise;
183
197
  return this._requests;
184
198
  }
185
199
  async captureSnapshot() {
200
+ await this._initializedPromise;
186
201
  let tabSnapshot;
187
202
  const modalStates = await this._raceAgainstModalStates(async () => {
188
203
  const snapshot = await this.page._snapshotForAI({ track: "response" });
189
204
  tabSnapshot = {
190
- url: this.page.url(),
191
- title: await this.page.title(),
192
205
  ariaSnapshot: snapshot.full,
193
206
  ariaSnapshotDiff: this._needsFullSnapshot ? void 0 : snapshot.incremental,
194
207
  modalStates: [],
195
- consoleMessages: [],
196
- downloads: this._downloads
208
+ events: []
197
209
  };
198
210
  });
199
211
  if (tabSnapshot) {
200
- tabSnapshot.consoleMessages = this._recentConsoleMessages;
201
- this._recentConsoleMessages = [];
212
+ tabSnapshot.events = this._recentEventEntries;
213
+ this._recentEventEntries = [];
202
214
  }
203
215
  this._needsFullSnapshot = !tabSnapshot;
204
216
  return tabSnapshot ?? {
205
- url: this.page.url(),
206
- title: "",
207
217
  ariaSnapshot: "",
218
+ ariaSnapshotDiff: "",
208
219
  modalStates,
209
- consoleMessages: [],
210
- downloads: []
220
+ events: []
211
221
  };
212
222
  }
213
223
  _javaScriptBlocked() {
@@ -228,15 +238,20 @@ class Tab extends import_events.EventEmitter {
228
238
  ]);
229
239
  }
230
240
  async waitForCompletion(callback) {
241
+ await this._initializedPromise;
231
242
  await this._raceAgainstModalStates(() => (0, import_utils2.waitForCompletion)(this, callback));
232
243
  }
233
244
  async refLocator(params) {
245
+ await this._initializedPromise;
234
246
  return (await this.refLocators([params]))[0];
235
247
  }
236
248
  async refLocators(params) {
249
+ await this._initializedPromise;
237
250
  return Promise.all(params.map(async (param) => {
238
251
  try {
239
- const locator = this.page.locator(`aria-ref=${param.ref}`).describe(param.element);
252
+ let locator = this.page.locator(`aria-ref=${param.ref}`);
253
+ if (param.element)
254
+ locator = locator.describe(param.element);
240
255
  const { resolvedSelector } = await locator._resolveSelector();
241
256
  return { locator, resolved: (0, import_utils.asLocator)("javascript", resolvedSelector) };
242
257
  } catch (e) {
@@ -250,7 +265,8 @@ class Tab extends import_events.EventEmitter {
250
265
  return;
251
266
  }
252
267
  await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => {
253
- return page.evaluate(() => new Promise((f) => setTimeout(f, 1e3)));
268
+ return page.evaluate(() => new Promise((f) => setTimeout(f, 1e3))).catch(() => {
269
+ });
254
270
  });
255
271
  }
256
272
  }
@@ -275,18 +291,53 @@ function pageErrorToConsoleMessage(errorOrValue) {
275
291
  toString: () => String(errorOrValue)
276
292
  };
277
293
  }
278
- function renderModalStates(context, modalStates) {
279
- const result = ["### Modal state"];
294
+ function renderModalStates(modalStates) {
295
+ const result = [];
280
296
  if (modalStates.length === 0)
281
297
  result.push("- There is no modal state present");
282
298
  for (const state of modalStates)
283
299
  result.push(`- [${state.description}]: can be handled by the "${state.clearedBy}" tool`);
284
300
  return result;
285
301
  }
302
+ const consoleMessageLevels = ["error", "warning", "info", "debug"];
303
+ function shouldIncludeMessage(thresholdLevel, type) {
304
+ const messageLevel = consoleLevelForMessageType(type);
305
+ return consoleMessageLevels.indexOf(messageLevel) <= consoleMessageLevels.indexOf(thresholdLevel);
306
+ }
307
+ function consoleLevelForMessageType(type) {
308
+ switch (type) {
309
+ case "assert":
310
+ case "error":
311
+ return "error";
312
+ case "warning":
313
+ return "warning";
314
+ case "count":
315
+ case "dir":
316
+ case "dirxml":
317
+ case "info":
318
+ case "log":
319
+ case "table":
320
+ case "time":
321
+ case "timeEnd":
322
+ return "info";
323
+ case "clear":
324
+ case "debug":
325
+ case "endGroup":
326
+ case "profile":
327
+ case "profileEnd":
328
+ case "startGroup":
329
+ case "startGroupCollapsed":
330
+ case "trace":
331
+ return "debug";
332
+ default:
333
+ return "info";
334
+ }
335
+ }
286
336
  const tabSymbol = Symbol("tabSymbol");
287
337
  // Annotate the CommonJS export names for ESM import in node:
288
338
  0 && (module.exports = {
289
339
  Tab,
290
340
  TabEvents,
291
- renderModalStates
341
+ renderModalStates,
342
+ shouldIncludeMessage
292
343
  });
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/mcp/browser/tab.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { EventEmitter } from 'events';\nimport * as playwright from 'playwright-core';\nimport { asLocator, ManualPromise } from 'playwright-core/lib/utils';\n\nimport { callOnPageNoTrace, waitForCompletion } from './tools/utils';\nimport { logUnhandledError } from '../log';\nimport { ModalState } from './tools/tool';\nimport { handleDialog } from './tools/dialogs';\nimport { uploadFile } from './tools/files';\nimport { requireOrImport } from '../../transform/transform';\n\nimport type { Context } from './context';\nimport type { Page } from '../../../../playwright-core/src/client/page';\nimport type { Locator } from '../../../../playwright-core/src/client/locator';\n\nexport const TabEvents = {\n modalState: 'modalState'\n};\n\nexport type TabEventsInterface = {\n [TabEvents.modalState]: [modalState: ModalState];\n};\n\nexport type TabSnapshot = {\n url: string;\n title: string;\n ariaSnapshot: string;\n ariaSnapshotDiff?: string;\n modalStates: ModalState[];\n consoleMessages: ConsoleMessage[];\n downloads: { download: playwright.Download, finished: boolean, outputFile: string }[];\n};\n\nexport class Tab extends EventEmitter<TabEventsInterface> {\n readonly context: Context;\n readonly page: Page;\n private _lastTitle = 'about:blank';\n private _consoleMessages: ConsoleMessage[] = [];\n private _recentConsoleMessages: ConsoleMessage[] = [];\n private _requests: Set<playwright.Request> = new Set();\n private _onPageClose: (tab: Tab) => void;\n private _modalStates: ModalState[] = [];\n private _downloads: { download: playwright.Download, finished: boolean, outputFile: string }[] = [];\n readonly initializedPromise: Promise<void>;\n private _needsFullSnapshot = false;\n\n constructor(context: Context, page: playwright.Page, onPageClose: (tab: Tab) => void) {\n super();\n this.context = context;\n this.page = page as Page;\n this._onPageClose = onPageClose;\n page.on('console', event => this._handleConsoleMessage(messageToConsoleMessage(event)));\n page.on('pageerror', error => this._handleConsoleMessage(pageErrorToConsoleMessage(error)));\n page.on('request', request => this._requests.add(request));\n page.on('close', () => this._onClose());\n page.on('filechooser', chooser => {\n this.setModalState({\n type: 'fileChooser',\n description: 'File chooser',\n fileChooser: chooser,\n clearedBy: uploadFile.schema.name,\n });\n });\n page.on('dialog', dialog => this._dialogShown(dialog));\n page.on('download', download => {\n void this._downloadStarted(download);\n });\n page.setDefaultNavigationTimeout(this.context.config.timeouts.navigation);\n page.setDefaultTimeout(this.context.config.timeouts.action);\n (page as any)[tabSymbol] = this;\n this.initializedPromise = this._initialize();\n }\n\n static forPage(page: playwright.Page): Tab | undefined {\n return (page as any)[tabSymbol];\n }\n\n static async collectConsoleMessages(page: playwright.Page): Promise<ConsoleMessage[]> {\n const result: ConsoleMessage[] = [];\n const messages = await page.consoleMessages().catch(() => []);\n for (const message of messages)\n result.push(messageToConsoleMessage(message));\n const errors = await page.pageErrors().catch(() => []);\n for (const error of errors)\n result.push(pageErrorToConsoleMessage(error));\n return result;\n }\n\n private async _initialize() {\n for (const message of await Tab.collectConsoleMessages(this.page))\n this._handleConsoleMessage(message);\n const requests = await this.page.requests().catch(() => []);\n for (const request of requests)\n this._requests.add(request);\n for (const initPage of this.context.config.browser.initPage || []) {\n try {\n const { default: func } = await requireOrImport(initPage);\n await func({ page: this.page });\n } catch (e) {\n logUnhandledError(e);\n }\n }\n }\n\n modalStates(): ModalState[] {\n return this._modalStates;\n }\n\n setModalState(modalState: ModalState) {\n this._modalStates.push(modalState);\n this.emit(TabEvents.modalState, modalState);\n }\n\n clearModalState(modalState: ModalState) {\n this._modalStates = this._modalStates.filter(state => state !== modalState);\n }\n\n modalStatesMarkdown(): string[] {\n return renderModalStates(this.context, this.modalStates());\n }\n\n private _dialogShown(dialog: playwright.Dialog) {\n this.setModalState({\n type: 'dialog',\n description: `\"${dialog.type()}\" dialog with message \"${dialog.message()}\"`,\n dialog,\n clearedBy: handleDialog.schema.name\n });\n }\n\n private async _downloadStarted(download: playwright.Download) {\n const entry = {\n download,\n finished: false,\n outputFile: await this.context.outputFile(download.suggestedFilename(), { origin: 'web', reason: 'Saving download' })\n };\n this._downloads.push(entry);\n await download.saveAs(entry.outputFile);\n entry.finished = true;\n }\n\n private _clearCollectedArtifacts() {\n this._consoleMessages.length = 0;\n this._recentConsoleMessages.length = 0;\n this._requests.clear();\n }\n\n private _handleConsoleMessage(message: ConsoleMessage) {\n this._consoleMessages.push(message);\n this._recentConsoleMessages.push(message);\n }\n\n private _onClose() {\n this._clearCollectedArtifacts();\n this._onPageClose(this);\n }\n\n async updateTitle() {\n await this._raceAgainstModalStates(async () => {\n this._lastTitle = await callOnPageNoTrace(this.page, page => page.title());\n });\n }\n\n lastTitle(): string {\n return this._lastTitle;\n }\n\n isCurrentTab(): boolean {\n return this === this.context.currentTab();\n }\n\n async waitForLoadState(state: 'load', options?: { timeout?: number }): Promise<void> {\n await callOnPageNoTrace(this.page, page => page.waitForLoadState(state, options).catch(logUnhandledError));\n }\n\n async navigate(url: string) {\n this._clearCollectedArtifacts();\n\n const downloadEvent = callOnPageNoTrace(this.page, page => page.waitForEvent('download').catch(logUnhandledError));\n try {\n await this.page.goto(url, { waitUntil: 'domcontentloaded' });\n } catch (_e: unknown) {\n const e = _e as Error;\n const mightBeDownload =\n e.message.includes('net::ERR_ABORTED') // chromium\n || e.message.includes('Download is starting'); // firefox + webkit\n if (!mightBeDownload)\n throw e;\n // on chromium, the download event is fired *after* page.goto rejects, so we wait a lil bit\n const download = await Promise.race([\n downloadEvent,\n new Promise(resolve => setTimeout(resolve, 3000)),\n ]);\n if (!download)\n throw e;\n // Make sure other \"download\" listeners are notified first.\n await new Promise(resolve => setTimeout(resolve, 500));\n return;\n }\n\n // Cap load event to 5 seconds, the page is operational at this point.\n await this.waitForLoadState('load', { timeout: 5000 });\n }\n\n async consoleMessages(type?: 'error'): Promise<ConsoleMessage[]> {\n await this.initializedPromise;\n return this._consoleMessages.filter(message => type ? message.type === type : true);\n }\n\n async requests(): Promise<Set<playwright.Request>> {\n await this.initializedPromise;\n return this._requests;\n }\n\n async captureSnapshot(): Promise<TabSnapshot> {\n let tabSnapshot: TabSnapshot | undefined;\n const modalStates = await this._raceAgainstModalStates(async () => {\n const snapshot = await this.page._snapshotForAI({ track: 'response' });\n tabSnapshot = {\n url: this.page.url(),\n title: await this.page.title(),\n ariaSnapshot: snapshot.full,\n ariaSnapshotDiff: this._needsFullSnapshot ? undefined : snapshot.incremental,\n modalStates: [],\n consoleMessages: [],\n downloads: this._downloads,\n };\n });\n if (tabSnapshot) {\n // Assign console message late so that we did not lose any to modal state.\n tabSnapshot.consoleMessages = this._recentConsoleMessages;\n this._recentConsoleMessages = [];\n }\n // If we failed to capture a snapshot this time, make sure we do a full one next time,\n // to avoid reporting deltas against un-reported snapshot.\n this._needsFullSnapshot = !tabSnapshot;\n return tabSnapshot ?? {\n url: this.page.url(),\n title: '',\n ariaSnapshot: '',\n modalStates,\n consoleMessages: [],\n downloads: [],\n };\n }\n\n private _javaScriptBlocked(): boolean {\n return this._modalStates.some(state => state.type === 'dialog');\n }\n\n private async _raceAgainstModalStates(action: () => Promise<void>): Promise<ModalState[]> {\n if (this.modalStates().length)\n return this.modalStates();\n\n const promise = new ManualPromise<ModalState[]>();\n const listener = (modalState: ModalState) => promise.resolve([modalState]);\n this.once(TabEvents.modalState, listener);\n\n return await Promise.race([\n action().then(() => {\n this.off(TabEvents.modalState, listener);\n return [];\n }),\n promise,\n ]);\n }\n\n async waitForCompletion(callback: () => Promise<void>) {\n await this._raceAgainstModalStates(() => waitForCompletion(this, callback));\n }\n\n async refLocator(params: { element: string, ref: string }): Promise<{ locator: Locator, resolved: string }> {\n return (await this.refLocators([params]))[0];\n }\n\n async refLocators(params: { element: string, ref: string }[]): Promise<{ locator: Locator, resolved: string }[]> {\n return Promise.all(params.map(async param => {\n try {\n const locator = this.page.locator(`aria-ref=${param.ref}`).describe(param.element) as Locator;\n const { resolvedSelector } = await locator._resolveSelector();\n return { locator, resolved: asLocator('javascript', resolvedSelector) };\n } catch (e) {\n throw new Error(`Ref ${param.ref} not found in the current page snapshot. Try capturing new snapshot.`);\n }\n }));\n }\n\n async waitForTimeout(time: number) {\n if (this._javaScriptBlocked()) {\n await new Promise(f => setTimeout(f, time));\n return;\n }\n\n await callOnPageNoTrace(this.page, page => {\n return page.evaluate(() => new Promise(f => setTimeout(f, 1000)));\n });\n }\n}\n\nexport type ConsoleMessage = {\n type: ReturnType<playwright.ConsoleMessage['type']> | undefined;\n text: string;\n toString(): string;\n};\n\nfunction messageToConsoleMessage(message: playwright.ConsoleMessage): ConsoleMessage {\n return {\n type: message.type(),\n text: message.text(),\n toString: () => `[${message.type().toUpperCase()}] ${message.text()} @ ${message.location().url}:${message.location().lineNumber}`,\n };\n}\n\nfunction pageErrorToConsoleMessage(errorOrValue: Error | any): ConsoleMessage {\n if (errorOrValue instanceof Error) {\n return {\n type: 'error',\n text: errorOrValue.message,\n toString: () => errorOrValue.stack || errorOrValue.message,\n };\n }\n return {\n type: 'error',\n text: String(errorOrValue),\n toString: () => String(errorOrValue),\n };\n}\n\nexport function renderModalStates(context: Context, modalStates: ModalState[]): string[] {\n const result: string[] = ['### Modal state'];\n if (modalStates.length === 0)\n result.push('- There is no modal state present');\n for (const state of modalStates)\n result.push(`- [${state.description}]: can be handled by the \"${state.clearedBy}\" tool`);\n return result;\n}\n\nconst tabSymbol = Symbol('tabSymbol');\n"],
5
+ "mappings": "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",
6
+ "names": ["import_utils"]
7
+ }
@@ -21,20 +21,22 @@ __export(common_exports, {
21
21
  default: () => common_default
22
22
  });
23
23
  module.exports = __toCommonJS(common_exports);
24
- var import_bundle = require("../../sdk/bundle");
24
+ var import_mcpBundle = require("playwright-core/lib/mcpBundle");
25
25
  var import_tool = require("./tool");
26
+ var import_response = require("../response");
26
27
  const close = (0, import_tool.defineTool)({
27
28
  capability: "core",
28
29
  schema: {
29
30
  name: "browser_close",
30
31
  title: "Close browser",
31
32
  description: "Close the page",
32
- inputSchema: import_bundle.z.object({}),
33
+ inputSchema: import_mcpBundle.z.object({}),
33
34
  type: "action"
34
35
  },
35
36
  handle: async (context, params, response) => {
36
37
  await context.closeBrowserContext();
37
- response.setIncludeTabs();
38
+ const result = (0, import_response.renderTabsMarkdown)([]);
39
+ response.addTextResult(result.join("\n"));
38
40
  response.addCode(`await page.close()`);
39
41
  }
40
42
  });
@@ -44,9 +46,9 @@ const resize = (0, import_tool.defineTabTool)({
44
46
  name: "browser_resize",
45
47
  title: "Resize browser window",
46
48
  description: "Resize the browser window",
47
- inputSchema: import_bundle.z.object({
48
- width: import_bundle.z.number().describe("Width of the browser window"),
49
- height: import_bundle.z.number().describe("Height of the browser window")
49
+ inputSchema: import_mcpBundle.z.object({
50
+ width: import_mcpBundle.z.number().describe("Width of the browser window"),
51
+ height: import_mcpBundle.z.number().describe("Height of the browser window")
50
52
  }),
51
53
  type: "action"
52
54
  },
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/mcp/browser/tools/common.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool, defineTool } from './tool';\n\nconst close = defineTool({\n capability: 'core',\n\n schema: {\n name: 'browser_close',\n title: 'Close browser',\n description: 'Close the page',\n inputSchema: z.object({}),\n type: 'action',\n },\n\n handle: async (context, params, response) => {\n await context.closeBrowserContext();\n response.setIncludeTabs();\n response.addCode(`await page.close()`);\n },\n});\n\nconst resize = defineTabTool({\n capability: 'core',\n schema: {\n name: 'browser_resize',\n title: 'Resize browser window',\n description: 'Resize the browser window',\n inputSchema: z.object({\n width: z.number().describe('Width of the browser window'),\n height: z.number().describe('Height of the browser window'),\n }),\n type: 'action',\n },\n\n handle: async (tab, params, response) => {\n response.addCode(`await page.setViewportSize({ width: ${params.width}, height: ${params.height} });`);\n\n await tab.waitForCompletion(async () => {\n await tab.page.setViewportSize({ width: params.width, height: params.height });\n });\n },\n});\n\nexport default [\n close,\n resize\n];\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA0C;AAE1C,MAAM,YAAQ,wBAAW;AAAA,EACvB,YAAY;AAAA,EAEZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO,CAAC,CAAC;AAAA,IACxB,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,SAAS,QAAQ,aAAa;AAC3C,UAAM,QAAQ,oBAAoB;AAClC,aAAS,eAAe;AACxB,aAAS,QAAQ,oBAAoB;AAAA,EACvC;AACF,CAAC;AAED,MAAM,aAAS,2BAAc;AAAA,EAC3B,YAAY;AAAA,EACZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO;AAAA,MACpB,OAAO,gBAAE,OAAO,EAAE,SAAS,6BAA6B;AAAA,MACxD,QAAQ,gBAAE,OAAO,EAAE,SAAS,8BAA8B;AAAA,IAC5D,CAAC;AAAA,IACD,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,KAAK,QAAQ,aAAa;AACvC,aAAS,QAAQ,uCAAuC,OAAO,KAAK,aAAa,OAAO,MAAM,MAAM;AAEpG,UAAM,IAAI,kBAAkB,YAAY;AACtC,YAAM,IAAI,KAAK,gBAAgB,EAAE,OAAO,OAAO,OAAO,QAAQ,OAAO,OAAO,CAAC;AAAA,IAC/E,CAAC;AAAA,EACH;AACF,CAAC;AAED,IAAO,iBAAQ;AAAA,EACb;AAAA,EACA;AACF;",
6
+ "names": []
7
+ }
@@ -21,7 +21,7 @@ __export(console_exports, {
21
21
  default: () => console_default
22
22
  });
23
23
  module.exports = __toCommonJS(console_exports);
24
- var import_bundle = require("../../sdk/bundle");
24
+ var import_mcpBundle = require("playwright-core/lib/mcpBundle");
25
25
  var import_tool = require("./tool");
26
26
  const console = (0, import_tool.defineTabTool)({
27
27
  capability: "core",
@@ -29,14 +29,16 @@ const console = (0, import_tool.defineTabTool)({
29
29
  name: "browser_console_messages",
30
30
  title: "Get console messages",
31
31
  description: "Returns all console messages",
32
- inputSchema: import_bundle.z.object({
33
- onlyErrors: import_bundle.z.boolean().optional().describe("Only return error messages")
32
+ inputSchema: import_mcpBundle.z.object({
33
+ level: import_mcpBundle.z.enum(["error", "warning", "info", "debug"]).default("info").describe('Level of the console messages to return. Each level includes the messages of more severe levels. Defaults to "info".'),
34
+ filename: import_mcpBundle.z.string().optional().describe("Filename to save the console messages to. If not provided, messages are returned as text.")
34
35
  }),
35
36
  type: "readOnly"
36
37
  },
37
38
  handle: async (tab, params, response) => {
38
- const messages = await tab.consoleMessages(params.onlyErrors ? "error" : void 0);
39
- messages.map((message) => response.addResult(message.toString()));
39
+ const messages = await tab.consoleMessages(params.level);
40
+ const text = messages.map((message) => message.toString()).join("\n");
41
+ await response.addResult({ text, suggestedFilename: params.filename });
40
42
  }
41
43
  });
42
44
  var console_default = [
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/mcp/browser/tools/console.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool } from './tool';\n\nconst console = defineTabTool({\n capability: 'core',\n schema: {\n name: 'browser_console_messages',\n title: 'Get console messages',\n description: 'Returns all console messages',\n inputSchema: z.object({\n onlyErrors: z.boolean().optional().describe('Only return error messages'),\n }),\n type: 'readOnly',\n },\n handle: async (tab, params, response) => {\n const messages = await tab.consoleMessages(params.onlyErrors ? 'error' : undefined);\n messages.map(message => response.addResult(message.toString()));\n },\n});\n\nexport default [\n console,\n];\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA8B;AAE9B,MAAM,cAAU,2BAAc;AAAA,EAC5B,YAAY;AAAA,EACZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO;AAAA,MACpB,YAAY,gBAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,IAC1E,CAAC;AAAA,IACD,MAAM;AAAA,EACR;AAAA,EACA,QAAQ,OAAO,KAAK,QAAQ,aAAa;AACvC,UAAM,WAAW,MAAM,IAAI,gBAAgB,OAAO,aAAa,UAAU,MAAS;AAClF,aAAS,IAAI,aAAW,SAAS,UAAU,QAAQ,SAAS,CAAC,CAAC;AAAA,EAChE;AACF,CAAC;AAED,IAAO,kBAAQ;AAAA,EACb;AACF;",
6
+ "names": []
7
+ }
@@ -22,7 +22,7 @@ __export(dialogs_exports, {
22
22
  handleDialog: () => handleDialog
23
23
  });
24
24
  module.exports = __toCommonJS(dialogs_exports);
25
- var import_bundle = require("../../sdk/bundle");
25
+ var import_mcpBundle = require("playwright-core/lib/mcpBundle");
26
26
  var import_tool = require("./tool");
27
27
  const handleDialog = (0, import_tool.defineTabTool)({
28
28
  capability: "core",
@@ -30,9 +30,9 @@ const handleDialog = (0, import_tool.defineTabTool)({
30
30
  name: "browser_handle_dialog",
31
31
  title: "Handle a dialog",
32
32
  description: "Handle a dialog",
33
- inputSchema: import_bundle.z.object({
34
- accept: import_bundle.z.boolean().describe("Whether to accept the dialog."),
35
- promptText: import_bundle.z.string().optional().describe("The text of the prompt in case of a prompt dialog.")
33
+ inputSchema: import_mcpBundle.z.object({
34
+ accept: import_mcpBundle.z.boolean().describe("Whether to accept the dialog."),
35
+ promptText: import_mcpBundle.z.string().optional().describe("The text of the prompt in case of a prompt dialog.")
36
36
  }),
37
37
  type: "action"
38
38
  },
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/mcp/browser/tools/dialogs.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool } from './tool';\n\nexport const handleDialog = defineTabTool({\n capability: 'core',\n\n schema: {\n name: 'browser_handle_dialog',\n title: 'Handle a dialog',\n description: 'Handle a dialog',\n inputSchema: z.object({\n accept: z.boolean().describe('Whether to accept the dialog.'),\n promptText: z.string().optional().describe('The text of the prompt in case of a prompt dialog.'),\n }),\n type: 'action',\n },\n\n handle: async (tab, params, response) => {\n response.setIncludeSnapshot();\n\n const dialogState = tab.modalStates().find(state => state.type === 'dialog');\n if (!dialogState)\n throw new Error('No dialog visible');\n\n tab.clearModalState(dialogState);\n await tab.waitForCompletion(async () => {\n if (params.accept)\n await dialogState.dialog.accept(params.promptText);\n else\n await dialogState.dialog.dismiss();\n });\n },\n\n clearsModalState: 'dialog',\n});\n\nexport default [\n handleDialog,\n];\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA8B;AAEvB,MAAM,mBAAe,2BAAc;AAAA,EACxC,YAAY;AAAA,EAEZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO;AAAA,MACpB,QAAQ,gBAAE,QAAQ,EAAE,SAAS,+BAA+B;AAAA,MAC5D,YAAY,gBAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAAA,IACjG,CAAC;AAAA,IACD,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,KAAK,QAAQ,aAAa;AACvC,aAAS,mBAAmB;AAE5B,UAAM,cAAc,IAAI,YAAY,EAAE,KAAK,WAAS,MAAM,SAAS,QAAQ;AAC3E,QAAI,CAAC;AACH,YAAM,IAAI,MAAM,mBAAmB;AAErC,QAAI,gBAAgB,WAAW;AAC/B,UAAM,IAAI,kBAAkB,YAAY;AACtC,UAAI,OAAO;AACT,cAAM,YAAY,OAAO,OAAO,OAAO,UAAU;AAAA;AAEjD,cAAM,YAAY,OAAO,QAAQ;AAAA,IACrC,CAAC;AAAA,EACH;AAAA,EAEA,kBAAkB;AACpB,CAAC;AAED,IAAO,kBAAQ;AAAA,EACb;AACF;",
6
+ "names": []
7
+ }
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,27 +15,20 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
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
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
  var evaluate_exports = {};
30
20
  __export(evaluate_exports, {
31
21
  default: () => evaluate_default
32
22
  });
33
23
  module.exports = __toCommonJS(evaluate_exports);
34
- var import_bundle = require("../../sdk/bundle");
24
+ var import_mcpBundle = require("playwright-core/lib/mcpBundle");
25
+ var import_utils = require("playwright-core/lib/utils");
35
26
  var import_tool = require("./tool");
36
- var javascript = __toESM(require("../codegen"));
37
- const evaluateSchema = import_bundle.z.object({
38
- function: import_bundle.z.string().describe("() => { /* code */ } or (element) => { /* code */ } when element is provided"),
39
- element: import_bundle.z.string().optional().describe("Human-readable element description used to obtain permission to interact with the element"),
40
- ref: import_bundle.z.string().optional().describe("Exact target element reference from the page snapshot")
27
+ const evaluateSchema = import_mcpBundle.z.object({
28
+ function: import_mcpBundle.z.string().describe("() => { /* code */ } or (element) => { /* code */ } when element is provided"),
29
+ element: import_mcpBundle.z.string().optional().describe("Human-readable element description used to obtain permission to interact with the element"),
30
+ ref: import_mcpBundle.z.string().optional().describe("Exact target element reference from the page snapshot"),
31
+ filename: import_mcpBundle.z.string().optional().describe("Filename to save the result to. If not provided, result is returned as JSON string.")
41
32
  });
42
33
  const evaluate = (0, import_tool.defineTabTool)({
43
34
  capability: "core",
@@ -53,14 +44,15 @@ const evaluate = (0, import_tool.defineTabTool)({
53
44
  let locator;
54
45
  if (params.ref && params.element) {
55
46
  locator = await tab.refLocator({ ref: params.ref, element: params.element });
56
- response.addCode(`await page.${locator.resolved}.evaluate(${javascript.quote(params.function)});`);
47
+ response.addCode(`await page.${locator.resolved}.evaluate(${(0, import_utils.escapeWithQuotes)(params.function)});`);
57
48
  } else {
58
- response.addCode(`await page.evaluate(${javascript.quote(params.function)});`);
49
+ response.addCode(`await page.evaluate(${(0, import_utils.escapeWithQuotes)(params.function)});`);
59
50
  }
60
51
  await tab.waitForCompletion(async () => {
61
52
  const receiver = locator?.locator ?? tab.page;
62
53
  const result = await receiver._evaluateFunction(params.function);
63
- response.addResult(JSON.stringify(result, null, 2) || "undefined");
54
+ const text = JSON.stringify(result, null, 2) || "undefined";
55
+ await response.addResult({ text, suggestedFilename: params.filename });
64
56
  });
65
57
  }
66
58
  });
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/mcp/browser/tools/evaluate.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool } from './tool';\nimport * as javascript from '../codegen';\n\nimport type { Tab } from '../tab';\n\nconst evaluateSchema = z.object({\n function: z.string().describe('() => { /* code */ } or (element) => { /* code */ } when element is provided'),\n element: z.string().optional().describe('Human-readable element description used to obtain permission to interact with the element'),\n ref: z.string().optional().describe('Exact target element reference from the page snapshot'),\n});\n\nconst evaluate = defineTabTool({\n capability: 'core',\n schema: {\n name: 'browser_evaluate',\n title: 'Evaluate JavaScript',\n description: 'Evaluate JavaScript expression on page or element',\n inputSchema: evaluateSchema,\n type: 'action',\n },\n\n handle: async (tab, params, response) => {\n response.setIncludeSnapshot();\n\n let locator: Awaited<ReturnType<Tab['refLocator']>> | undefined;\n if (params.ref && params.element) {\n locator = await tab.refLocator({ ref: params.ref, element: params.element });\n response.addCode(`await page.${locator.resolved}.evaluate(${javascript.quote(params.function)});`);\n } else {\n response.addCode(`await page.evaluate(${javascript.quote(params.function)});`);\n }\n\n await tab.waitForCompletion(async () => {\n const receiver = locator?.locator ?? tab.page;\n const result = await receiver._evaluateFunction(params.function);\n response.addResult(JSON.stringify(result, null, 2) || 'undefined');\n });\n },\n});\n\nexport default [\n evaluate,\n];\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA8B;AAC9B,iBAA4B;AAI5B,MAAM,iBAAiB,gBAAE,OAAO;AAAA,EAC9B,UAAU,gBAAE,OAAO,EAAE,SAAS,8EAA8E;AAAA,EAC5G,SAAS,gBAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2FAA2F;AAAA,EACnI,KAAK,gBAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uDAAuD;AAC7F,CAAC;AAED,MAAM,eAAW,2BAAc;AAAA,EAC7B,YAAY;AAAA,EACZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,KAAK,QAAQ,aAAa;AACvC,aAAS,mBAAmB;AAE5B,QAAI;AACJ,QAAI,OAAO,OAAO,OAAO,SAAS;AAChC,gBAAU,MAAM,IAAI,WAAW,EAAE,KAAK,OAAO,KAAK,SAAS,OAAO,QAAQ,CAAC;AAC3E,eAAS,QAAQ,cAAc,QAAQ,QAAQ,aAAa,WAAW,MAAM,OAAO,QAAQ,CAAC,IAAI;AAAA,IACnG,OAAO;AACL,eAAS,QAAQ,uBAAuB,WAAW,MAAM,OAAO,QAAQ,CAAC,IAAI;AAAA,IAC/E;AAEA,UAAM,IAAI,kBAAkB,YAAY;AACtC,YAAM,WAAW,SAAS,WAAW,IAAI;AACzC,YAAM,SAAS,MAAM,SAAS,kBAAkB,OAAO,QAAQ;AAC/D,eAAS,UAAU,KAAK,UAAU,QAAQ,MAAM,CAAC,KAAK,WAAW;AAAA,IACnE,CAAC;AAAA,EACH;AACF,CAAC;AAED,IAAO,mBAAQ;AAAA,EACb;AACF;",
6
+ "names": []
7
+ }
@@ -22,7 +22,7 @@ __export(files_exports, {
22
22
  uploadFile: () => uploadFile
23
23
  });
24
24
  module.exports = __toCommonJS(files_exports);
25
- var import_bundle = require("../../sdk/bundle");
25
+ var import_mcpBundle = require("playwright-core/lib/mcpBundle");
26
26
  var import_tool = require("./tool");
27
27
  const uploadFile = (0, import_tool.defineTabTool)({
28
28
  capability: "core",
@@ -30,8 +30,8 @@ const uploadFile = (0, import_tool.defineTabTool)({
30
30
  name: "browser_file_upload",
31
31
  title: "Upload files",
32
32
  description: "Upload one or multiple files",
33
- inputSchema: import_bundle.z.object({
34
- paths: import_bundle.z.array(import_bundle.z.string()).optional().describe("The absolute paths to the files to upload. Can be single file or multiple files. If omitted, file chooser is cancelled.")
33
+ inputSchema: import_mcpBundle.z.object({
34
+ paths: import_mcpBundle.z.array(import_mcpBundle.z.string()).optional().describe("The absolute paths to the files to upload. Can be single file or multiple files. If omitted, file chooser is cancelled.")
35
35
  }),
36
36
  type: "action"
37
37
  },
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/mcp/browser/tools/files.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from '../../sdk/bundle';\nimport { defineTabTool } from './tool';\n\nexport const uploadFile = defineTabTool({\n capability: 'core',\n\n schema: {\n name: 'browser_file_upload',\n title: 'Upload files',\n description: 'Upload one or multiple files',\n inputSchema: z.object({\n paths: z.array(z.string()).optional().describe('The absolute paths to the files to upload. Can be single file or multiple files. If omitted, file chooser is cancelled.'),\n }),\n type: 'action',\n },\n\n handle: async (tab, params, response) => {\n response.setIncludeSnapshot();\n\n const modalState = tab.modalStates().find(state => state.type === 'fileChooser');\n if (!modalState)\n throw new Error('No file chooser visible');\n\n response.addCode(`await fileChooser.setFiles(${JSON.stringify(params.paths)})`);\n\n tab.clearModalState(modalState);\n await tab.waitForCompletion(async () => {\n if (params.paths)\n await modalState.fileChooser.setFiles(params.paths);\n });\n },\n\n clearsModalState: 'fileChooser',\n});\n\nexport default [\n uploadFile,\n];\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,oBAAkB;AAClB,kBAA8B;AAEvB,MAAM,iBAAa,2BAAc;AAAA,EACtC,YAAY;AAAA,EAEZ,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,gBAAE,OAAO;AAAA,MACpB,OAAO,gBAAE,MAAM,gBAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,yHAAyH;AAAA,IAC1K,CAAC;AAAA,IACD,MAAM;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,KAAK,QAAQ,aAAa;AACvC,aAAS,mBAAmB;AAE5B,UAAM,aAAa,IAAI,YAAY,EAAE,KAAK,WAAS,MAAM,SAAS,aAAa;AAC/E,QAAI,CAAC;AACH,YAAM,IAAI,MAAM,yBAAyB;AAE3C,aAAS,QAAQ,8BAA8B,KAAK,UAAU,OAAO,KAAK,CAAC,GAAG;AAE9E,QAAI,gBAAgB,UAAU;AAC9B,UAAM,IAAI,kBAAkB,YAAY;AACtC,UAAI,OAAO;AACT,cAAM,WAAW,YAAY,SAAS,OAAO,KAAK;AAAA,IACtD,CAAC;AAAA,EACH;AAAA,EAEA,kBAAkB;AACpB,CAAC;AAED,IAAO,gBAAQ;AAAA,EACb;AACF;",
6
+ "names": []
7
+ }
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,35 +15,27 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
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
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
  var form_exports = {};
30
20
  __export(form_exports, {
31
21
  default: () => form_default
32
22
  });
33
23
  module.exports = __toCommonJS(form_exports);
34
- var import_bundle = require("../../sdk/bundle");
24
+ var import_mcpBundle = require("playwright-core/lib/mcpBundle");
25
+ var import_utils = require("playwright-core/lib/utils");
35
26
  var import_tool = require("./tool");
36
- var codegen = __toESM(require("../codegen"));
37
27
  const fillForm = (0, import_tool.defineTabTool)({
38
28
  capability: "core",
39
29
  schema: {
40
30
  name: "browser_fill_form",
41
31
  title: "Fill form",
42
32
  description: "Fill multiple form fields",
43
- inputSchema: import_bundle.z.object({
44
- fields: import_bundle.z.array(import_bundle.z.object({
45
- name: import_bundle.z.string().describe("Human-readable field name"),
46
- type: import_bundle.z.enum(["textbox", "checkbox", "radio", "combobox", "slider"]).describe("Type of the field"),
47
- ref: import_bundle.z.string().describe("Exact target field reference from the page snapshot"),
48
- value: import_bundle.z.string().describe("Value to fill in the field. If the field is a checkbox, the value should be `true` or `false`. If the field is a combobox, the value should be the text of the option.")
33
+ inputSchema: import_mcpBundle.z.object({
34
+ fields: import_mcpBundle.z.array(import_mcpBundle.z.object({
35
+ name: import_mcpBundle.z.string().describe("Human-readable field name"),
36
+ type: import_mcpBundle.z.enum(["textbox", "checkbox", "radio", "combobox", "slider"]).describe("Type of the field"),
37
+ ref: import_mcpBundle.z.string().describe("Exact target field reference from the page snapshot"),
38
+ value: import_mcpBundle.z.string().describe("Value to fill in the field. If the field is a checkbox, the value should be `true` or `false`. If the field is a combobox, the value should be the text of the option.")
49
39
  })).describe("Fields to fill in")
50
40
  }),
51
41
  type: "input"
@@ -63,7 +53,7 @@ const fillForm = (0, import_tool.defineTabTool)({
63
53
  response.addCode(`${locatorSource}.setChecked(${field.value});`);
64
54
  } else if (field.type === "combobox") {
65
55
  await locator.selectOption({ label: field.value });
66
- response.addCode(`${locatorSource}.selectOption(${codegen.quote(field.value)});`);
56
+ response.addCode(`${locatorSource}.selectOption(${(0, import_utils.escapeWithQuotes)(field.value)});`);
67
57
  }
68
58
  }
69
59
  }