patchright-core 1.52.4 → 1.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/ThirdPartyNotices.txt +65 -123
  2. package/bin/reinstall_chrome_beta_mac.sh +1 -1
  3. package/bin/reinstall_chrome_stable_mac.sh +1 -1
  4. package/bin/reinstall_msedge_beta_mac.sh +1 -1
  5. package/bin/reinstall_msedge_dev_mac.sh +1 -1
  6. package/bin/reinstall_msedge_stable_mac.sh +1 -1
  7. package/browsers.json +14 -14
  8. package/index.js +1 -1
  9. package/lib/androidServerImpl.js +4 -2
  10. package/lib/browserServerImpl.js +47 -12
  11. package/lib/cli/program.js +116 -50
  12. package/lib/cli/programWithTestStub.js +1 -1
  13. package/lib/client/android.js +30 -34
  14. package/lib/client/browser.js +54 -17
  15. package/lib/client/browserContext.js +67 -71
  16. package/lib/client/browserType.js +25 -34
  17. package/lib/client/channelOwner.js +20 -24
  18. package/lib/client/connection.js +6 -10
  19. package/lib/client/electron.js +8 -3
  20. package/lib/client/elementHandle.js +18 -21
  21. package/lib/client/fetch.js +5 -3
  22. package/lib/client/frame.js +57 -35
  23. package/lib/client/input.js +3 -1
  24. package/lib/client/jsHandle.js +4 -0
  25. package/lib/client/localUtils.js +0 -1
  26. package/lib/client/locator.js +32 -28
  27. package/lib/client/network.js +5 -12
  28. package/lib/client/page.js +32 -32
  29. package/lib/client/playwright.js +6 -16
  30. package/lib/client/selectors.js +18 -38
  31. package/lib/client/timeoutSettings.js +12 -8
  32. package/lib/client/tracing.js +24 -20
  33. package/lib/client/waiter.js +2 -2
  34. package/lib/client/webSocket.js +4 -22
  35. package/lib/generated/bindingsControllerSource.js +28 -0
  36. package/lib/generated/clockSource.js +1 -1
  37. package/lib/generated/injectedScriptSource.js +1 -1
  38. package/lib/generated/pollingRecorderSource.js +1 -1
  39. package/lib/generated/storageScriptSource.js +28 -0
  40. package/lib/generated/utilityScriptSource.js +1 -1
  41. package/lib/generated/webSocketMockSource.js +12 -50
  42. package/lib/inProcessFactory.js +9 -6
  43. package/lib/outofprocess.js +0 -2
  44. package/lib/protocol/validator.js +423 -346
  45. package/lib/protocol/validatorPrimitives.js +18 -4
  46. package/lib/remote/playwrightConnection.js +29 -166
  47. package/lib/remote/playwrightServer.js +233 -35
  48. package/lib/server/android/android.js +97 -83
  49. package/lib/server/android/backendAdb.js +0 -2
  50. package/lib/server/bidi/bidiBrowser.js +139 -73
  51. package/lib/server/bidi/bidiChromium.js +23 -22
  52. package/lib/server/bidi/bidiExecutionContext.js +2 -1
  53. package/lib/server/bidi/bidiFirefox.js +17 -14
  54. package/lib/server/bidi/bidiInput.js +22 -22
  55. package/lib/server/bidi/bidiNetworkManager.js +8 -11
  56. package/lib/server/bidi/bidiPage.js +42 -86
  57. package/lib/server/bidi/third_party/bidiProtocol.js +5 -133
  58. package/lib/server/bidi/third_party/bidiProtocolCore.js +179 -0
  59. package/lib/server/{dispatchers/selectorsDispatcher.js → bidi/third_party/bidiProtocolPermissions.js} +20 -18
  60. package/lib/server/browser.js +30 -21
  61. package/lib/server/browserContext.js +203 -165
  62. package/lib/server/browserType.js +109 -107
  63. package/lib/server/chromium/chromium.js +84 -69
  64. package/lib/server/chromium/chromiumSwitches.js +13 -20
  65. package/lib/server/chromium/crBrowser.js +74 -40
  66. package/lib/server/chromium/crConnection.js +8 -9
  67. package/lib/server/chromium/crCoverage.js +11 -8
  68. package/lib/server/chromium/crDragDrop.js +25 -20
  69. package/lib/server/chromium/crExecutionContext.js +2 -1
  70. package/lib/server/chromium/crInput.js +32 -29
  71. package/lib/server/chromium/crNetworkManager.js +45 -33
  72. package/lib/server/chromium/crPage.js +98 -73
  73. package/lib/server/chromium/crServiceWorker.js +13 -18
  74. package/lib/server/chromium/videoRecorder.js +10 -18
  75. package/lib/server/clock.js +51 -39
  76. package/lib/server/codegen/csharp.js +10 -5
  77. package/lib/server/codegen/java.js +1 -1
  78. package/lib/server/codegen/javascript.js +1 -1
  79. package/lib/server/codegen/jsonl.js +2 -1
  80. package/lib/server/codegen/language.js +22 -1
  81. package/lib/server/codegen/languages.js +4 -4
  82. package/lib/server/codegen/python.js +1 -1
  83. package/lib/server/cookieStore.js +3 -1
  84. package/lib/server/debugController.js +105 -71
  85. package/lib/server/debugger.js +6 -23
  86. package/lib/server/deviceDescriptorsSource.json +237 -127
  87. package/lib/server/dialog.js +50 -6
  88. package/lib/server/dispatchers/androidDispatcher.js +77 -62
  89. package/lib/server/dispatchers/artifactDispatcher.js +18 -18
  90. package/lib/server/dispatchers/browserContextDispatcher.js +141 -91
  91. package/lib/server/dispatchers/browserDispatcher.js +55 -88
  92. package/lib/server/dispatchers/browserTypeDispatcher.js +18 -9
  93. package/lib/server/dispatchers/cdpSessionDispatcher.js +4 -4
  94. package/lib/server/dispatchers/debugControllerDispatcher.js +12 -21
  95. package/lib/server/dispatchers/dialogDispatcher.js +4 -4
  96. package/lib/server/dispatchers/dispatcher.js +78 -53
  97. package/lib/server/dispatchers/electronDispatcher.js +19 -20
  98. package/lib/server/dispatchers/elementHandlerDispatcher.js +83 -93
  99. package/lib/server/dispatchers/frameDispatcher.js +99 -102
  100. package/lib/server/dispatchers/jsHandleDispatcher.js +21 -16
  101. package/lib/server/dispatchers/jsonPipeDispatcher.js +4 -4
  102. package/lib/server/dispatchers/localUtilsDispatcher.js +53 -59
  103. package/lib/server/dispatchers/networkDispatchers.js +41 -35
  104. package/lib/server/dispatchers/pageDispatcher.js +156 -107
  105. package/lib/server/dispatchers/playwrightDispatcher.js +37 -25
  106. package/lib/server/dispatchers/streamDispatcher.js +15 -8
  107. package/lib/server/dispatchers/tracingDispatcher.js +22 -13
  108. package/lib/server/dispatchers/webSocketRouteDispatcher.js +46 -35
  109. package/lib/server/dispatchers/writableStreamDispatcher.js +16 -10
  110. package/lib/server/dom.js +198 -266
  111. package/lib/server/download.js +3 -3
  112. package/lib/server/electron/electron.js +96 -103
  113. package/lib/server/electron/loader.js +1 -1
  114. package/lib/server/fetch.js +22 -41
  115. package/lib/server/fileUploadUtils.js +1 -1
  116. package/lib/server/firefox/ffBrowser.js +79 -55
  117. package/lib/server/firefox/ffExecutionContext.js +2 -1
  118. package/lib/server/firefox/ffInput.js +23 -23
  119. package/lib/server/firefox/ffNetworkManager.js +8 -6
  120. package/lib/server/firefox/ffPage.js +39 -36
  121. package/lib/server/firefox/firefox.js +9 -10
  122. package/lib/server/frameSelectors.js +65 -22
  123. package/lib/server/frames.js +516 -544
  124. package/lib/server/har/harRecorder.js +1 -1
  125. package/lib/server/har/harTracer.js +4 -2
  126. package/lib/server/helper.js +3 -7
  127. package/lib/server/index.js +0 -3
  128. package/lib/server/input.js +47 -54
  129. package/lib/server/instrumentation.js +8 -14
  130. package/lib/server/javascript.js +9 -17
  131. package/lib/server/launchApp.js +48 -30
  132. package/lib/server/localUtils.js +45 -38
  133. package/lib/server/network.js +44 -10
  134. package/lib/server/page.js +233 -178
  135. package/lib/server/pageBinding.js +6 -7
  136. package/lib/server/playwright.js +4 -14
  137. package/lib/server/progress.js +57 -49
  138. package/lib/server/recorder/recorderApp.js +298 -95
  139. package/lib/server/recorder/recorderRunner.js +23 -24
  140. package/lib/server/recorder/recorderSignalProcessor.js +83 -0
  141. package/lib/server/recorder/recorderUtils.js +67 -10
  142. package/lib/server/recorder.js +284 -146
  143. package/lib/server/registry/index.js +83 -48
  144. package/lib/server/registry/nativeDeps.js +175 -0
  145. package/lib/server/registry/oopDownloadBrowserMain.js +1 -1
  146. package/lib/server/screenshotter.js +84 -83
  147. package/lib/server/selectors.js +12 -12
  148. package/lib/server/socksClientCertificatesInterceptor.js +198 -136
  149. package/lib/server/trace/recorder/snapshotter.js +12 -19
  150. package/lib/server/trace/recorder/tracing.js +36 -27
  151. package/lib/server/trace/viewer/traceViewer.js +11 -20
  152. package/lib/server/transport.js +20 -22
  153. package/lib/server/utils/comparators.js +2 -2
  154. package/lib/server/utils/debug.js +3 -8
  155. package/lib/server/utils/debugLogger.js +8 -0
  156. package/lib/server/utils/hostPlatform.js +3 -1
  157. package/lib/server/utils/network.js +35 -25
  158. package/lib/server/utils/nodePlatform.js +1 -1
  159. package/lib/server/utils/processLauncher.js +4 -1
  160. package/lib/server/utils/wsServer.js +11 -17
  161. package/lib/server/webkit/webkit.js +5 -2
  162. package/lib/server/webkit/wkBrowser.js +51 -28
  163. package/lib/server/webkit/wkExecutionContext.js +2 -1
  164. package/lib/server/webkit/wkInput.js +25 -25
  165. package/lib/server/webkit/wkInterceptableRequest.js +1 -1
  166. package/lib/server/webkit/wkPage.js +80 -59
  167. package/lib/server/webkit/wkProvisionalPage.js +1 -1
  168. package/lib/server/webkit/wkWorkers.js +7 -7
  169. package/lib/utils/isomorphic/ariaSnapshot.js +13 -7
  170. package/lib/utils/isomorphic/cssParser.js +1 -2
  171. package/lib/utils/isomorphic/locatorGenerators.js +18 -0
  172. package/lib/utils/isomorphic/manualPromise.js +1 -2
  173. package/lib/utils/isomorphic/mimeType.js +1 -2
  174. package/lib/utils/isomorphic/multimap.js +1 -2
  175. package/lib/utils/isomorphic/oldUtilityScriptSerializers.js +248 -0
  176. package/lib/utils/isomorphic/protocolFormatter.js +78 -0
  177. package/lib/utils/isomorphic/protocolMetainfo.js +318 -0
  178. package/lib/utils/isomorphic/selectorParser.js +3 -4
  179. package/lib/utils/isomorphic/stringUtils.js +3 -24
  180. package/lib/utils/isomorphic/time.js +9 -4
  181. package/lib/utils/isomorphic/timeoutRunner.js +3 -4
  182. package/lib/utils/isomorphic/traceUtils.js +2 -3
  183. package/lib/utils/isomorphic/urlMatch.js +21 -7
  184. package/lib/utils/isomorphic/utilityScriptSerializers.js +208 -205
  185. package/lib/utils.js +8 -2
  186. package/lib/utilsBundleImpl/index.js +160 -150
  187. package/lib/vite/htmlReport/index.html +17 -17
  188. package/lib/vite/recorder/assets/{codeMirrorModule-CXVeovup.js → codeMirrorModule-DzQ0k89p.js} +1 -1
  189. package/lib/vite/recorder/assets/{index-eHBmevrY.css → index-CI4HQ-Zb.css} +1 -1
  190. package/lib/vite/recorder/assets/index-D7C7daHH.js +184 -0
  191. package/lib/vite/recorder/index.html +3 -3
  192. package/lib/vite/traceViewer/assets/{codeMirrorModule-_GLjJL-7.js → codeMirrorModule-Di48jgWx.js} +1 -1
  193. package/lib/vite/traceViewer/assets/defaultSettingsView-szBn8781.js +256 -0
  194. package/lib/vite/traceViewer/defaultSettingsView.DVJHpiGt.css +1 -0
  195. package/lib/vite/traceViewer/index.BFsek2M6.css +1 -0
  196. package/lib/vite/traceViewer/index.DQvXoPLL.js +2 -0
  197. package/lib/vite/traceViewer/index.html +6 -6
  198. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  199. package/lib/vite/traceViewer/uiMode.dBV3oN9h.js +5 -0
  200. package/lib/vite/traceViewer/uiMode.html +4 -4
  201. package/lib/zipBundleImpl.js +4 -4
  202. package/package.json +1 -1
  203. package/types/protocol.d.ts +712 -107
  204. package/types/types.d.ts +148 -37
  205. package/lib/generated/consoleApiSource.js +0 -28
  206. package/lib/protocol/debug.js +0 -211
  207. package/lib/server/recorder/contextRecorder.js +0 -286
  208. package/lib/server/recorder/recorderCollection.js +0 -116
  209. package/lib/server/recorder/recorderFrontend.js +0 -16
  210. package/lib/server/storageScript.js +0 -154
  211. package/lib/server/timeoutSettings.js +0 -89
  212. package/lib/utils/isomorphic/builtins.js +0 -86
  213. package/lib/vite/recorder/assets/index-BsWQsSGl.js +0 -184
  214. package/lib/vite/traceViewer/assets/defaultSettingsView-DtCQiGHe.js +0 -265
  215. package/lib/vite/traceViewer/defaultSettingsView.QdHITyLI.css +0 -1
  216. package/lib/vite/traceViewer/index.CFOW-Ezb.css +0 -1
  217. package/lib/vite/traceViewer/index.cFZzK9RN.js +0 -2
  218. package/lib/vite/traceViewer/uiMode.XVPIqBeS.js +0 -5
@@ -31,67 +31,79 @@ __export(clock_exports, {
31
31
  Clock: () => Clock
32
32
  });
33
33
  module.exports = __toCommonJS(clock_exports);
34
- var clockSource = __toESM(require("../generated/clockSource"));
34
+ var rawClockSource = __toESM(require("../generated/clockSource"));
35
35
  class Clock {
36
36
  constructor(browserContext) {
37
- this._scriptInstalled = false;
37
+ this._initScripts = [];
38
38
  this._browserContext = browserContext;
39
39
  }
40
- markAsUninstalled() {
41
- this._scriptInstalled = false;
40
+ async uninstall(progress) {
41
+ await progress.race(this._browserContext.removeInitScripts(this._initScripts));
42
+ this._initScripts = [];
42
43
  }
43
- async fastForward(ticks) {
44
- await this._installIfNeeded();
44
+ async fastForward(progress, ticks) {
45
+ await this._installIfNeeded(progress);
45
46
  const ticksMillis = parseTicks(ticks);
46
- await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('fastForward', ${Date.now()}, ${ticksMillis})`);
47
- await this._evaluateInFrames(`globalThis.__pwClock.controller.fastForward(${ticksMillis})`);
47
+ this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('fastForward', ${Date.now()}, ${ticksMillis})`));
48
+ await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.fastForward(${ticksMillis})`));
48
49
  }
49
- async install(time) {
50
- await this._installIfNeeded();
50
+ async install(progress, time) {
51
+ await this._installIfNeeded(progress);
51
52
  const timeMillis = time !== void 0 ? parseTime(time) : Date.now();
52
- await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('install', ${Date.now()}, ${timeMillis})`);
53
- await this._evaluateInFrames(`globalThis.__pwClock.controller.install(${timeMillis})`);
53
+ this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('install', ${Date.now()}, ${timeMillis})`));
54
+ await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.install(${timeMillis})`));
54
55
  }
55
- async pauseAt(ticks) {
56
- await this._installIfNeeded();
56
+ async pauseAt(progress, ticks) {
57
+ await this._installIfNeeded(progress);
57
58
  const timeMillis = parseTime(ticks);
58
- await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('pauseAt', ${Date.now()}, ${timeMillis})`);
59
- await this._evaluateInFrames(`globalThis.__pwClock.controller.pauseAt(${timeMillis})`);
59
+ this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('pauseAt', ${Date.now()}, ${timeMillis})`));
60
+ await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.pauseAt(${timeMillis})`));
60
61
  }
61
- async resume() {
62
- await this._installIfNeeded();
63
- await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('resume', ${Date.now()})`);
64
- await this._evaluateInFrames(`globalThis.__pwClock.controller.resume()`);
62
+ resumeNoReply() {
63
+ if (!this._initScripts.length)
64
+ return;
65
+ const doResume = async () => {
66
+ this._initScripts.push(await this._browserContext.addInitScript(void 0, `globalThis.__pwClock.controller.log('resume', ${Date.now()})`));
67
+ await this._evaluateInFrames(`globalThis.__pwClock.controller.resume()`);
68
+ };
69
+ doResume().catch(() => {
70
+ });
71
+ }
72
+ async resume(progress) {
73
+ await this._installIfNeeded(progress);
74
+ this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('resume', ${Date.now()})`));
75
+ await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.resume()`));
65
76
  }
66
- async setFixedTime(time) {
67
- await this._installIfNeeded();
77
+ async setFixedTime(progress, time) {
78
+ await this._installIfNeeded(progress);
68
79
  const timeMillis = parseTime(time);
69
- await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('setFixedTime', ${Date.now()}, ${timeMillis})`);
70
- await this._evaluateInFrames(`globalThis.__pwClock.controller.setFixedTime(${timeMillis})`);
80
+ this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('setFixedTime', ${Date.now()}, ${timeMillis})`));
81
+ await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.setFixedTime(${timeMillis})`));
71
82
  }
72
- async setSystemTime(time) {
73
- await this._installIfNeeded();
83
+ async setSystemTime(progress, time) {
84
+ await this._installIfNeeded(progress);
74
85
  const timeMillis = parseTime(time);
75
- await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('setSystemTime', ${Date.now()}, ${timeMillis})`);
76
- await this._evaluateInFrames(`globalThis.__pwClock.controller.setSystemTime(${timeMillis})`);
86
+ this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('setSystemTime', ${Date.now()}, ${timeMillis})`));
87
+ await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.setSystemTime(${timeMillis})`));
77
88
  }
78
- async runFor(ticks) {
79
- await this._installIfNeeded();
89
+ async runFor(progress, ticks) {
90
+ await this._installIfNeeded(progress);
80
91
  const ticksMillis = parseTicks(ticks);
81
- await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('runFor', ${Date.now()}, ${ticksMillis})`);
82
- await this._evaluateInFrames(`globalThis.__pwClock.controller.runFor(${ticksMillis})`);
92
+ this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('runFor', ${Date.now()}, ${ticksMillis})`));
93
+ await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.runFor(${ticksMillis})`));
83
94
  }
84
- async _installIfNeeded() {
85
- if (this._scriptInstalled)
95
+ async _installIfNeeded(progress) {
96
+ if (this._initScripts.length)
86
97
  return;
87
- this._scriptInstalled = true;
88
98
  const script = `(() => {
89
99
  const module = {};
90
- ${clockSource.source}
91
- globalThis.__pwClock = (module.exports.inject())(globalThis);
100
+ ${rawClockSource.source}
101
+ if (!globalThis.__pwClock)
102
+ globalThis.__pwClock = (module.exports.inject())(globalThis);
92
103
  })();`;
93
- await this._browserContext.addInitScript(script);
94
- await this._evaluateInFrames(script);
104
+ const initScript = await this._browserContext.addInitScript(progress, script);
105
+ await progress.race(this._evaluateInFrames(script));
106
+ this._initScripts.push(initScript);
95
107
  }
96
108
  async _evaluateInFrames(script) {
97
109
  await Promise.all(this._browserContext.pages().map(async (page) => {
@@ -52,9 +52,7 @@ class CSharpLanguageGenerator {
52
52
  const action = actionInContext.action;
53
53
  if (this._mode !== "library" && (action.name === "openPage" || action.name === "closePage"))
54
54
  return "";
55
- let pageAlias = actionInContext.frame.pageAlias;
56
- if (this._mode !== "library")
57
- pageAlias = pageAlias.replace("page", "Page");
55
+ const pageAlias = this._formatPageAlias(actionInContext.frame.pageAlias);
58
56
  const formatter = new CSharpFormatter(this._mode === "library" ? 0 : 8);
59
57
  if (action.name === "openPage") {
60
58
  formatter.add(`var ${pageAlias} = await context.NewPageAsync();`);
@@ -82,7 +80,7 @@ class CSharpLanguageGenerator {
82
80
  lines.push(`});`);
83
81
  }
84
82
  if (signals.popup) {
85
- lines.unshift(`var ${signals.popup.popupAlias} = await ${pageAlias}.RunAndWaitForPopupAsync(async () =>
83
+ lines.unshift(`var ${this._formatPageAlias(signals.popup.popupAlias)} = await ${pageAlias}.RunAndWaitForPopupAsync(async () =>
86
84
  {`);
87
85
  lines.push(`});`);
88
86
  }
@@ -90,6 +88,13 @@ class CSharpLanguageGenerator {
90
88
  formatter.add(line);
91
89
  return formatter.format();
92
90
  }
91
+ _formatPageAlias(pageAlias) {
92
+ if (this._mode === "library")
93
+ return pageAlias;
94
+ if (pageAlias === "page")
95
+ return "Page";
96
+ return pageAlias;
97
+ }
93
98
  _generateActionCall(subject, actionInContext) {
94
99
  const action = actionInContext.action;
95
100
  switch (action.name) {
@@ -135,7 +140,7 @@ class CSharpLanguageGenerator {
135
140
  return `await Expect(${subject}.${this._asLocator(action.selector)}).${assertion};`;
136
141
  }
137
142
  case "assertSnapshot":
138
- return `await Expect(${subject}.${this._asLocator(action.selector)}).ToMatchAriaSnapshotAsync(${quote(action.snapshot)});`;
143
+ return `await Expect(${subject}.${this._asLocator(action.selector)}).ToMatchAriaSnapshotAsync(${quote(action.ariaSnapshot)});`;
139
144
  }
140
145
  }
141
146
  _asLocator(selector) {
@@ -119,7 +119,7 @@ class JavaLanguageGenerator {
119
119
  return `assertThat(${subject}.${this._asLocator(action.selector, inFrameLocator)}).${assertion};`;
120
120
  }
121
121
  case "assertSnapshot":
122
- return `assertThat(${subject}.${this._asLocator(action.selector, inFrameLocator)}).matchesAriaSnapshot(${quote(action.snapshot)});`;
122
+ return `assertThat(${subject}.${this._asLocator(action.selector, inFrameLocator)}).matchesAriaSnapshot(${quote(action.ariaSnapshot)});`;
123
123
  }
124
124
  }
125
125
  _asLocator(selector, inFrameLocator) {
@@ -110,7 +110,7 @@ class JavaScriptLanguageGenerator {
110
110
  }
111
111
  case "assertSnapshot": {
112
112
  const commentIfNeeded = this._isTest ? "" : "// ";
113
- return `${commentIfNeeded}await expect(${subject}.${this._asLocator(action.selector)}).toMatchAriaSnapshot(${quoteMultiline(action.snapshot, `${commentIfNeeded} `)});`;
113
+ return `${commentIfNeeded}await expect(${subject}.${this._asLocator(action.selector)}).toMatchAriaSnapshot(${quoteMultiline(action.ariaSnapshot, `${commentIfNeeded} `)});`;
114
114
  }
115
115
  }
116
116
  }
@@ -34,7 +34,8 @@ class JsonlLanguageGenerator {
34
34
  const entry = {
35
35
  ...actionInContext.action,
36
36
  ...actionInContext.frame,
37
- locator
37
+ locator,
38
+ ariaSnapshot: void 0
38
39
  };
39
40
  return JSON.stringify(entry);
40
41
  }
@@ -29,10 +29,31 @@ module.exports = __toCommonJS(language_exports);
29
29
  function generateCode(actions, languageGenerator, options) {
30
30
  const header = languageGenerator.generateHeader(options);
31
31
  const footer = languageGenerator.generateFooter(options.saveStorage);
32
- const actionTexts = actions.map((a) => languageGenerator.generateAction(a)).filter(Boolean);
32
+ const actionTexts = actions.map((a) => generateActionText(languageGenerator, a, !!options.generateAutoExpect)).filter(Boolean);
33
33
  const text = [header, ...actionTexts, footer].join("\n");
34
34
  return { header, footer, actionTexts, text };
35
35
  }
36
+ function generateActionText(generator, action, generateAutoExpect) {
37
+ let text = generator.generateAction(action);
38
+ if (!text)
39
+ return;
40
+ if (generateAutoExpect && action.action.preconditionSelector) {
41
+ const expectAction = {
42
+ frame: action.frame,
43
+ startTime: action.startTime,
44
+ endTime: action.startTime,
45
+ action: {
46
+ name: "assertVisible",
47
+ selector: action.action.preconditionSelector,
48
+ signals: []
49
+ }
50
+ };
51
+ const expectText = generator.generateAction(expectAction);
52
+ if (expectText)
53
+ text = expectText + "\n\n" + text;
54
+ }
55
+ return text;
56
+ }
36
57
  function sanitizeDeviceOptions(device, options) {
37
58
  const cleanedOptions = {};
38
59
  for (const property in options) {
@@ -28,15 +28,13 @@ var import_jsonl = require("./jsonl");
28
28
  var import_python = require("./python");
29
29
  function languageSet() {
30
30
  return /* @__PURE__ */ new Set([
31
- new import_java.JavaLanguageGenerator("junit"),
32
- new import_java.JavaLanguageGenerator("library"),
33
31
  new import_javascript.JavaScriptLanguageGenerator(
34
32
  /* isPlaywrightTest */
35
- false
33
+ true
36
34
  ),
37
35
  new import_javascript.JavaScriptLanguageGenerator(
38
36
  /* isPlaywrightTest */
39
- true
37
+ false
40
38
  ),
41
39
  new import_python.PythonLanguageGenerator(
42
40
  /* isAsync */
@@ -59,6 +57,8 @@ function languageSet() {
59
57
  new import_csharp.CSharpLanguageGenerator("mstest"),
60
58
  new import_csharp.CSharpLanguageGenerator("nunit"),
61
59
  new import_csharp.CSharpLanguageGenerator("library"),
60
+ new import_java.JavaLanguageGenerator("junit"),
61
+ new import_java.JavaLanguageGenerator("library"),
62
62
  new import_jsonl.JsonlLanguageGenerator()
63
63
  ]);
64
64
  }
@@ -111,7 +111,7 @@ class PythonLanguageGenerator {
111
111
  return `expect(${subject}.${this._asLocator(action.selector)}).${assertion};`;
112
112
  }
113
113
  case "assertSnapshot":
114
- return `expect(${subject}.${this._asLocator(action.selector)}).to_match_aria_snapshot(${quote(action.snapshot)})`;
114
+ return `expect(${subject}.${this._asLocator(action.selector)}).to_match_aria_snapshot(${quote(action.ariaSnapshot)})`;
115
115
  }
116
116
  }
117
117
  _asLocator(selector) {
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var cookieStore_exports = {};
20
20
  __export(cookieStore_exports, {
21
+ Cookie: () => Cookie,
21
22
  CookieStore: () => CookieStore,
22
23
  domainMatches: () => domainMatches,
23
24
  parseRawCookie: () => parseRawCookie
@@ -33,7 +34,7 @@ class Cookie {
33
34
  }
34
35
  // https://datatracker.ietf.org/doc/html/rfc6265#section-5.4
35
36
  matches(url) {
36
- if (this._raw.secure && (url.protocol !== "https:" && url.hostname !== "localhost"))
37
+ if (this._raw.secure && (url.protocol !== "https:" && !(0, import_network.isLocalHostname)(url.hostname)))
37
38
  return false;
38
39
  if (!domainMatches(url.hostname, this._raw.domain))
39
40
  return false;
@@ -198,6 +199,7 @@ function pathMatches(value, path) {
198
199
  }
199
200
  // Annotate the CommonJS export names for ESM import in node:
200
201
  0 && (module.exports = {
202
+ Cookie,
201
203
  CookieStore,
202
204
  domainMatches,
203
205
  parseRawCookie
@@ -27,14 +27,19 @@ var import_recorder = require("./recorder");
27
27
  var import_utils = require("../utils");
28
28
  var import_ariaSnapshot = require("../utils/isomorphic/ariaSnapshot");
29
29
  var import_utilsBundle = require("../utilsBundle");
30
- var import_recorderApp = require("./recorder/recorderApp");
31
30
  var import_locatorParser = require("../utils/isomorphic/locatorParser");
32
- const internalMetadata = (0, import_instrumentation.serverSideCallMetadata)();
31
+ var import_language = require("./codegen/language");
32
+ var import_recorderUtils = require("./recorder/recorderUtils");
33
+ var import_javascript = require("./codegen/javascript");
34
+ var import_frames = require("./frames");
35
+ var import_page = require("./page");
33
36
  class DebugController extends import_instrumentation.SdkObject {
34
37
  constructor(playwright) {
35
38
  super({ attribution: { isInternalPlaywright: true }, instrumentation: (0, import_instrumentation.createInstrumentation)() }, void 0, "DebugController");
39
+ this._reportState = false;
40
+ this._disposeListeners = /* @__PURE__ */ new Set();
36
41
  this._sdkLanguage = "javascript";
37
- this._codegenId = "playwright-test";
42
+ this._generateAutoExpect = false;
38
43
  this._playwright = playwright;
39
44
  }
40
45
  static {
@@ -47,105 +52,114 @@ class DebugController extends import_instrumentation.SdkObject {
47
52
  };
48
53
  }
49
54
  initialize(codegenId, sdkLanguage) {
50
- this._codegenId = codegenId;
51
55
  this._sdkLanguage = sdkLanguage;
52
56
  }
53
57
  dispose() {
54
58
  this.setReportStateChanged(false);
55
59
  }
56
60
  setReportStateChanged(enabled) {
57
- if (enabled && !this._trackHierarchyListener) {
58
- this._trackHierarchyListener = {
59
- onPageOpen: () => this._emitSnapshot(false),
61
+ if (this._reportState === enabled)
62
+ return;
63
+ this._reportState = enabled;
64
+ if (enabled) {
65
+ const listener = {
66
+ onPageOpen: (page) => {
67
+ this._emitSnapshot(false);
68
+ const handleNavigation = () => this._emitSnapshot(false);
69
+ page.mainFrame().on(import_frames.Frame.Events.InternalNavigation, handleNavigation);
70
+ const dispose = () => page.mainFrame().off(import_frames.Frame.Events.InternalNavigation, handleNavigation);
71
+ this._disposeListeners.add(dispose);
72
+ page.on(import_page.Page.Events.Close, () => this._disposeListeners.delete(dispose));
73
+ },
60
74
  onPageClose: () => this._emitSnapshot(false)
61
75
  };
62
- this._playwright.instrumentation.addListener(this._trackHierarchyListener, null);
76
+ this._playwright.instrumentation.addListener(listener, null);
77
+ this._disposeListeners.add(() => this._playwright.instrumentation.removeListener(listener));
63
78
  this._emitSnapshot(true);
64
- } else if (!enabled && this._trackHierarchyListener) {
65
- this._playwright.instrumentation.removeListener(this._trackHierarchyListener);
66
- this._trackHierarchyListener = void 0;
79
+ } else {
80
+ for (const dispose of this._disposeListeners)
81
+ dispose();
82
+ this._disposeListeners.clear();
67
83
  }
68
84
  }
69
- async resetForReuse() {
70
- const contexts = /* @__PURE__ */ new Set();
71
- for (const page of this._playwright.allPages())
72
- contexts.add(page.context());
73
- for (const context of contexts)
74
- await context.resetForReuse(internalMetadata, null);
75
- }
76
- async navigate(url) {
77
- for (const p of this._playwright.allPages())
78
- await p.mainFrame().goto(internalMetadata, url);
79
- }
80
- async setRecorderMode(params) {
81
- await this._closeBrowsersWithoutPages();
85
+ async setRecorderMode(progress, params) {
86
+ await progress.race(this._closeBrowsersWithoutPages());
87
+ this._generateAutoExpect = !!params.generateAutoExpect;
82
88
  if (params.mode === "none") {
83
- for (const recorder of await this._allRecorders()) {
89
+ for (const recorder of await progress.race(this._allRecorders())) {
84
90
  recorder.hideHighlightedSelector();
85
91
  recorder.setMode("none");
86
92
  }
87
93
  return;
88
94
  }
89
95
  if (!this._playwright.allBrowsers().length)
90
- await this._playwright.chromium.launch(internalMetadata, { headless: !!process.env.PW_DEBUG_CONTROLLER_HEADLESS });
96
+ await this._playwright.chromium.launch(progress, { headless: !!process.env.PW_DEBUG_CONTROLLER_HEADLESS });
91
97
  const pages = this._playwright.allPages();
92
98
  if (!pages.length) {
93
99
  const [browser] = this._playwright.allBrowsers();
94
- const { context } = await browser.newContextForReuse({}, internalMetadata);
95
- await context.newPage(internalMetadata);
100
+ const context = await browser.newContextForReuse(progress, {});
101
+ await context.newPage(progress);
96
102
  }
97
103
  if (params.testIdAttributeName) {
98
104
  for (const page of this._playwright.allPages())
99
- page.context().selectors().setTestIdAttributeName(params.testIdAttributeName);
105
+ page.browserContext.selectors().setTestIdAttributeName(params.testIdAttributeName);
100
106
  }
101
- for (const recorder of await this._allRecorders()) {
107
+ for (const recorder of await progress.race(this._allRecorders())) {
102
108
  recorder.hideHighlightedSelector();
103
- if (params.mode !== "inspecting")
104
- recorder.setOutput(this._codegenId, params.file);
105
109
  recorder.setMode(params.mode);
106
110
  }
107
111
  }
108
- async highlight(params) {
112
+ async highlight(progress, params) {
109
113
  if (params.selector)
110
114
  (0, import_locatorParser.unsafeLocatorOrSelectorAsSelector)(this._sdkLanguage, params.selector, "data-testid");
111
115
  const ariaTemplate = params.ariaTemplate ? (0, import_ariaSnapshot.parseAriaSnapshotUnsafe)(import_utilsBundle.yaml, params.ariaTemplate) : void 0;
112
- for (const recorder of await this._allRecorders()) {
116
+ for (const recorder of await progress.race(this._allRecorders())) {
113
117
  if (ariaTemplate)
114
118
  recorder.setHighlightedAriaTemplate(ariaTemplate);
115
119
  else if (params.selector)
116
- recorder.setHighlightedSelector(this._sdkLanguage, params.selector);
120
+ recorder.setHighlightedSelector(params.selector);
117
121
  }
118
122
  }
119
- async hideHighlight() {
120
- for (const recorder of await this._allRecorders())
123
+ async hideHighlight(progress) {
124
+ for (const recorder of await progress.race(this._allRecorders()))
121
125
  recorder.hideHighlightedSelector();
122
- await this._playwright.hideHighlight();
123
- }
124
- allBrowsers() {
125
- return [...this._playwright.allBrowsers()];
126
+ await Promise.all(this._playwright.allPages().map((p) => p.hideHighlight().catch(() => {
127
+ })));
126
128
  }
127
- async resume() {
128
- for (const recorder of await this._allRecorders())
129
+ async resume(progress) {
130
+ for (const recorder of await progress.race(this._allRecorders()))
129
131
  recorder.resume();
130
132
  }
131
- async kill() {
133
+ kill() {
132
134
  (0, import_processLauncher.gracefullyProcessExitDoNotHang)(0);
133
135
  }
134
- async closeAllBrowsers() {
135
- await Promise.all(this.allBrowsers().map((browser) => browser.close({ reason: "Close all browsers requested" })));
136
- }
137
136
  _emitSnapshot(initial) {
138
137
  const pageCount = this._playwright.allPages().length;
139
138
  if (initial && !pageCount)
140
139
  return;
141
- this.emit(DebugController.Events.StateChanged, { pageCount });
140
+ this.emit(DebugController.Events.StateChanged, {
141
+ pageCount,
142
+ browsers: this._playwright.allBrowsers().map((browser) => ({
143
+ id: browser.guid,
144
+ name: browser.options.name,
145
+ channel: browser.options.channel,
146
+ contexts: browser.contexts().map((context) => ({
147
+ pages: context.pages().map((page) => ({
148
+ url: page.mainFrame().url()
149
+ }))
150
+ }))
151
+ }))
152
+ });
142
153
  }
143
154
  async _allRecorders() {
144
155
  const contexts = /* @__PURE__ */ new Set();
145
156
  for (const page of this._playwright.allPages())
146
- contexts.add(page.context());
147
- const result = await Promise.all([...contexts].map((c) => import_recorder.Recorder.showInspector(c, { omitCallTracking: true }, () => Promise.resolve(new InspectingRecorderApp(this)))));
148
- return result.filter(Boolean);
157
+ contexts.add(page.browserContext);
158
+ const recorders = await Promise.all([...contexts].map((c) => import_recorder.Recorder.forContext(c, { omitCallTracking: true })));
159
+ const nonNullRecorders = recorders.filter(Boolean);
160
+ for (const recorder of recorders)
161
+ wireListeners(recorder, this);
162
+ return nonNullRecorders;
149
163
  }
150
164
  async _closeBrowsersWithoutPages() {
151
165
  for (const browser of this._playwright.allBrowsers()) {
@@ -158,26 +172,46 @@ class DebugController extends import_instrumentation.SdkObject {
158
172
  }
159
173
  }
160
174
  }
161
- class InspectingRecorderApp extends import_recorderApp.EmptyRecorderApp {
162
- constructor(debugController) {
163
- super();
164
- this._debugController = debugController;
165
- }
166
- async elementPicked(elementInfo) {
167
- const locator = (0, import_utils.asLocator)(this._debugController._sdkLanguage, elementInfo.selector);
168
- this._debugController.emit(DebugController.Events.InspectRequested, { selector: elementInfo.selector, locator, ariaSnapshot: elementInfo.ariaSnapshot });
169
- }
170
- async setSources(sources) {
171
- const source = sources.find((s) => s.id === this._debugController._codegenId);
172
- const { text, header, footer, actions } = source || { text: "" };
173
- this._debugController.emit(DebugController.Events.SourceChanged, { text, header, footer, actions });
174
- }
175
- async setPaused(paused) {
176
- this._debugController.emit(DebugController.Events.Paused, { paused });
177
- }
178
- async setMode(mode) {
179
- this._debugController.emit(DebugController.Events.SetModeRequested, { mode });
180
- }
175
+ const wiredSymbol = Symbol("wired");
176
+ function wireListeners(recorder, debugController) {
177
+ if (recorder[wiredSymbol])
178
+ return;
179
+ recorder[wiredSymbol] = true;
180
+ const actions = [];
181
+ const languageGenerator = new import_javascript.JavaScriptLanguageGenerator(
182
+ /* isPlaywrightTest */
183
+ true
184
+ );
185
+ const actionsChanged = () => {
186
+ const aa = (0, import_recorderUtils.collapseActions)(actions);
187
+ const { header, footer, text, actionTexts } = (0, import_language.generateCode)(aa, languageGenerator, {
188
+ browserName: "chromium",
189
+ launchOptions: {},
190
+ contextOptions: {},
191
+ generateAutoExpect: debugController._generateAutoExpect
192
+ });
193
+ debugController.emit(DebugController.Events.SourceChanged, { text, header, footer, actions: actionTexts });
194
+ };
195
+ recorder.on(import_recorder.RecorderEvent.ElementPicked, (elementInfo) => {
196
+ const locator = (0, import_utils.asLocator)(debugController._sdkLanguage, elementInfo.selector);
197
+ debugController.emit(DebugController.Events.InspectRequested, { selector: elementInfo.selector, locator, ariaSnapshot: elementInfo.ariaSnapshot });
198
+ });
199
+ recorder.on(import_recorder.RecorderEvent.PausedStateChanged, (paused) => {
200
+ debugController.emit(DebugController.Events.Paused, { paused });
201
+ });
202
+ recorder.on(import_recorder.RecorderEvent.ModeChanged, (mode) => {
203
+ debugController.emit(DebugController.Events.SetModeRequested, { mode });
204
+ });
205
+ recorder.on(import_recorder.RecorderEvent.ActionAdded, (action) => {
206
+ actions.push(action);
207
+ actionsChanged();
208
+ });
209
+ recorder.on(import_recorder.RecorderEvent.SignalAdded, (signal) => {
210
+ const lastAction = actions.findLast((a) => a.frame.pageGuid === signal.frame.pageGuid);
211
+ if (lastAction)
212
+ lastAction.action.signals.push(signal.signal);
213
+ actionsChanged();
214
+ });
181
215
  }
182
216
  // Annotate the CommonJS export names for ESM import in node:
183
217
  0 && (module.exports = {
@@ -18,14 +18,13 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var debugger_exports = {};
20
20
  __export(debugger_exports, {
21
- Debugger: () => Debugger,
22
- shouldSlowMo: () => shouldSlowMo
21
+ Debugger: () => Debugger
23
22
  });
24
23
  module.exports = __toCommonJS(debugger_exports);
25
24
  var import_events = require("events");
26
25
  var import_utils = require("../utils");
27
26
  var import_browserContext = require("./browserContext");
28
- var import_debug = require("../protocol/debug");
27
+ var import_protocolMetainfo = require("../utils/isomorphic/protocolMetainfo");
29
28
  const symbol = Symbol("Debugger");
30
29
  class Debugger extends import_events.EventEmitter {
31
30
  constructor(context) {
@@ -42,7 +41,6 @@ class Debugger extends import_events.EventEmitter {
42
41
  this._context.once(import_browserContext.BrowserContext.Events.Close, () => {
43
42
  this._context.instrumentation.removeListener(this);
44
43
  });
45
- this._slowMo = this._context._browser.options.slowMo;
46
44
  }
47
45
  static {
48
46
  this.Events = {
@@ -58,13 +56,6 @@ class Debugger extends import_events.EventEmitter {
58
56
  if (shouldPauseOnCall(sdkObject, metadata) || this._pauseOnNextStatement && shouldPauseBeforeStep(metadata))
59
57
  await this.pause(sdkObject, metadata);
60
58
  }
61
- async _doSlowMo() {
62
- await new Promise((f) => setTimeout(f, this._slowMo));
63
- }
64
- async onAfterCall(sdkObject, metadata) {
65
- if (this._slowMo && shouldSlowMo(metadata))
66
- await this._doSlowMo();
67
- }
68
59
  async onBeforeInputAction(sdkObject, metadata) {
69
60
  if (this._muted)
70
61
  return;
@@ -117,20 +108,12 @@ function shouldPauseOnCall(sdkObject, metadata) {
117
108
  return metadata.method === "pause";
118
109
  }
119
110
  function shouldPauseBeforeStep(metadata) {
120
- if (!metadata.apiName)
111
+ if (metadata.internal)
121
112
  return false;
122
- if (metadata.method === "close")
123
- return true;
124
- if (metadata.method === "waitForSelector" || metadata.method === "waitForEventInfo" || metadata.method === "querySelector" || metadata.method === "querySelectorAll")
125
- return false;
126
- const step = metadata.type + "." + metadata.method;
127
- return import_debug.commandsWithTracingSnapshots.has(step) && !import_debug.pausesBeforeInputActions.has(metadata.type + "." + metadata.method);
128
- }
129
- function shouldSlowMo(metadata) {
130
- return import_debug.slowMoActions.has(metadata.type + "." + metadata.method);
113
+ const metainfo = import_protocolMetainfo.methodMetainfo.get(metadata.type + "." + metadata.method);
114
+ return !!metainfo?.pausesBeforeAction;
131
115
  }
132
116
  // Annotate the CommonJS export names for ESM import in node:
133
117
  0 && (module.exports = {
134
- Debugger,
135
- shouldSlowMo
118
+ Debugger
136
119
  });