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
@@ -28,157 +28,360 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var recorderApp_exports = {};
30
30
  __export(recorderApp_exports, {
31
- EmptyRecorderApp: () => EmptyRecorderApp,
31
+ ProgrammaticRecorderApp: () => ProgrammaticRecorderApp,
32
32
  RecorderApp: () => RecorderApp
33
33
  });
34
34
  module.exports = __toCommonJS(recorderApp_exports);
35
- var import_events = require("events");
36
35
  var import_fs = __toESM(require("fs"));
37
36
  var import_path = __toESM(require("path"));
38
37
  var import_debug = require("../utils/debug");
39
38
  var import_utilsBundle = require("../../utilsBundle");
40
- var import_instrumentation = require("../instrumentation");
41
39
  var import_launchApp = require("../launchApp");
42
40
  var import_launchApp2 = require("../launchApp");
43
41
  var import_progress = require("../progress");
44
- class EmptyRecorderApp extends import_events.EventEmitter {
45
- async close() {
46
- }
47
- async setPaused(paused) {
48
- }
49
- async setMode(mode) {
50
- }
51
- async setRunningFile(file) {
52
- }
53
- async elementPicked(elementInfo, userGesture) {
54
- }
55
- async updateCallLogs(callLogs) {
56
- }
57
- async setSources(sources, primaryPageURL) {
58
- }
59
- async setActions(actions, sources) {
60
- }
61
- }
62
- class RecorderApp extends import_events.EventEmitter {
63
- constructor(recorder, page, wsEndpoint) {
64
- super();
65
- this.setMaxListeners(0);
66
- this._recorder = recorder;
42
+ var import_throttledFile = require("./throttledFile");
43
+ var import_languages = require("../codegen/languages");
44
+ var import_recorderUtils = require("./recorderUtils");
45
+ var import_language = require("../codegen/language");
46
+ var import_recorder = require("../recorder");
47
+ var import_browserContext = require("../browserContext");
48
+ class RecorderApp {
49
+ constructor(recorder, params, page, wsEndpointForTest) {
50
+ this._throttledOutputFile = null;
51
+ this._actions = [];
52
+ this._userSources = [];
53
+ this._recorderSources = [];
67
54
  this._page = page;
68
- this.wsEndpointForTest = wsEndpoint;
69
- }
70
- async close() {
71
- await this._page.context().close({ reason: "Recorder window closed" });
55
+ this._recorder = recorder;
56
+ this.wsEndpointForTest = wsEndpointForTest;
57
+ this._languageGeneratorOptions = {
58
+ browserName: params.browserName,
59
+ launchOptions: { headless: false, ...params.launchOptions, tracesDir: void 0 },
60
+ contextOptions: { ...params.contextOptions },
61
+ deviceName: params.device,
62
+ saveStorage: params.saveStorage
63
+ };
64
+ this._throttledOutputFile = params.outputFile ? new import_throttledFile.ThrottledFile(params.outputFile) : null;
65
+ this._primaryGeneratorId = process.env.TEST_INSPECTOR_LANGUAGE || params.language || determinePrimaryGeneratorId(params.sdkLanguage);
66
+ this._selectedGeneratorId = this._primaryGeneratorId;
72
67
  }
73
- async _init() {
68
+ async _init(inspectedContext) {
74
69
  await (0, import_launchApp.syncLocalStorageWithSettings)(this._page, "recorder");
75
- await this._page._setServerRequestInterceptor((route) => {
76
- if (!route.request().url().startsWith("https://playwright/"))
77
- return false;
78
- const uri = route.request().url().substring("https://playwright/".length);
79
- const file = require.resolve("../../vite/recorder/" + uri);
80
- import_fs.default.promises.readFile(file).then((buffer) => {
81
- route.fulfill({
82
- status: 200,
83
- headers: [
84
- { name: "Content-Type", value: import_utilsBundle.mime.getType(import_path.default.extname(file)) || "application/octet-stream" }
85
- ],
86
- body: buffer.toString("base64"),
87
- isBase64: true
88
- }).catch(() => {
70
+ const controller = new import_progress.ProgressController();
71
+ await controller.run(async (progress) => {
72
+ await this._page.addRequestInterceptor(progress, (route) => {
73
+ if (!route.request().url().startsWith("https://playwright/")) {
74
+ route.continue({ isFallback: true }).catch(() => {
75
+ });
76
+ return;
77
+ }
78
+ const uri = route.request().url().substring("https://playwright/".length);
79
+ const file = require.resolve("../../vite/recorder/" + uri);
80
+ import_fs.default.promises.readFile(file).then((buffer) => {
81
+ route.fulfill({
82
+ status: 200,
83
+ headers: [
84
+ { name: "Content-Type", value: import_utilsBundle.mime.getType(import_path.default.extname(file)) || "application/octet-stream" }
85
+ ],
86
+ body: buffer.toString("base64"),
87
+ isBase64: true
88
+ }).catch(() => {
89
+ });
89
90
  });
90
91
  });
91
- return true;
92
- });
93
- await this._page.exposeBinding("dispatch", false, (_, data) => this.emit("event", data));
94
- this._page.once("close", () => {
95
- this.emit("close");
96
- this._page.context().close({ reason: "Recorder window closed" }).catch(() => {
92
+ await this._page.exposeBinding(progress, "dispatch", false, (_, data) => this._handleUIEvent(data));
93
+ this._page.once("close", () => {
94
+ this._recorder.close();
95
+ this._page.browserContext.close({ reason: "Recorder window closed" }).catch(() => {
96
+ });
97
+ delete inspectedContext[recorderAppSymbol];
97
98
  });
99
+ await this._page.mainFrame().goto(progress, process.env.PW_HMR ? "http://localhost:44225" : "https://playwright/index.html");
98
100
  });
99
- const mainFrame = this._page.mainFrame();
100
- await mainFrame.goto((0, import_instrumentation.serverSideCallMetadata)(), process.env.PW_HMR ? "http://localhost:44225" : "https://playwright/index.html");
101
+ const url = this._recorder.url();
102
+ if (url)
103
+ this._onPageNavigated(url);
104
+ this._onModeChanged(this._recorder.mode());
105
+ this._onPausedStateChanged(this._recorder.paused());
106
+ this._updateActions("reveal");
107
+ this._onUserSourcesChanged(this._recorder.userSources(), this._recorder.pausedSourceId());
108
+ this._onCallLogsUpdated(this._recorder.callLog());
109
+ this._wireListeners(this._recorder);
101
110
  }
102
- static factory(context) {
103
- return async (recorder) => {
104
- if (process.env.PW_CODEGEN_NO_INSPECTOR)
105
- return new EmptyRecorderApp();
106
- return await RecorderApp._open(recorder, context);
107
- };
111
+ _handleUIEvent(data) {
112
+ if (data.event === "clear") {
113
+ this._actions = [];
114
+ this._updateActions("reveal");
115
+ this._recorder.clear();
116
+ return;
117
+ }
118
+ if (data.event === "fileChanged") {
119
+ const source = [...this._recorderSources, ...this._userSources].find((s) => s.id === data.params.fileId);
120
+ if (source) {
121
+ if (source.isRecorded)
122
+ this._selectedGeneratorId = source.id;
123
+ this._recorder.setLanguage(source.language);
124
+ }
125
+ return;
126
+ }
127
+ if (data.event === "setAutoExpect") {
128
+ this._languageGeneratorOptions.generateAutoExpect = data.params.autoExpect;
129
+ this._updateActions();
130
+ return;
131
+ }
132
+ if (data.event === "setMode") {
133
+ this._recorder.setMode(data.params.mode);
134
+ return;
135
+ }
136
+ if (data.event === "resume") {
137
+ this._recorder.resume();
138
+ return;
139
+ }
140
+ if (data.event === "pause") {
141
+ this._recorder.pause();
142
+ return;
143
+ }
144
+ if (data.event === "step") {
145
+ this._recorder.step();
146
+ return;
147
+ }
148
+ if (data.event === "highlightRequested") {
149
+ if (data.params.selector)
150
+ this._recorder.setHighlightedSelector(data.params.selector);
151
+ if (data.params.ariaTemplate)
152
+ this._recorder.setHighlightedAriaTemplate(data.params.ariaTemplate);
153
+ return;
154
+ }
155
+ throw new Error(`Unknown event: ${data.event}`);
156
+ }
157
+ static async show(context, params) {
158
+ if (process.env.PW_CODEGEN_NO_INSPECTOR)
159
+ return;
160
+ const recorder = await import_recorder.Recorder.forContext(context, params);
161
+ if (params.recorderMode === "api") {
162
+ const browserName = context._browser.options.name;
163
+ await ProgrammaticRecorderApp.run(context, recorder, browserName, params);
164
+ return;
165
+ }
166
+ await RecorderApp._show(recorder, context, params);
167
+ }
168
+ async close() {
169
+ await this._page.close();
170
+ }
171
+ static showInspectorNoReply(context) {
172
+ if (process.env.PW_CODEGEN_NO_INSPECTOR)
173
+ return;
174
+ void import_recorder.Recorder.forContext(context, {}).then((recorder) => RecorderApp._show(recorder, context, {})).catch(() => {
175
+ });
108
176
  }
109
- static async _open(recorder, inspectedContext) {
110
- const sdkLanguage = inspectedContext.attribution.playwright.options.sdkLanguage;
177
+ static async _show(recorder, inspectedContext, params) {
178
+ if (inspectedContext[recorderAppSymbol])
179
+ return;
180
+ inspectedContext[recorderAppSymbol] = true;
181
+ const sdkLanguage = inspectedContext._browser.sdkLanguage();
111
182
  const headed = !!inspectedContext._browser.options.headful;
112
183
  const recorderPlaywright = require("../playwright").createPlaywright({ sdkLanguage: "javascript", isInternalPlaywright: true });
113
- const { context, page } = await (0, import_launchApp2.launchApp)(recorderPlaywright.chromium, {
184
+ const { context: appContext, page } = await (0, import_launchApp2.launchApp)(recorderPlaywright.chromium, {
114
185
  sdkLanguage,
115
186
  windowSize: { width: 600, height: 600 },
116
187
  windowPosition: { x: 1020, y: 10 },
117
188
  persistentContextOptions: {
118
189
  noDefaultViewport: true,
119
190
  headless: !!process.env.PWTEST_CLI_HEADLESS || (0, import_debug.isUnderTest)() && !headed,
120
- useWebSocket: (0, import_debug.isUnderTest)(),
121
- handleSIGINT: recorder.handleSIGINT,
191
+ cdpPort: (0, import_debug.isUnderTest)() ? 0 : void 0,
192
+ handleSIGINT: params.handleSIGINT,
122
193
  executablePath: inspectedContext._browser.options.isChromium ? inspectedContext._browser.options.customExecutablePath : void 0,
123
194
  // Use the same channel as the inspected context to guarantee that the browser is installed.
124
195
  channel: inspectedContext._browser.options.isChromium ? inspectedContext._browser.options.channel : void 0
125
196
  }
126
197
  });
127
- const controller = new import_progress.ProgressController((0, import_instrumentation.serverSideCallMetadata)(), context._browser);
198
+ const controller = new import_progress.ProgressController();
128
199
  await controller.run(async (progress) => {
129
- await context._browser._defaultContext._loadDefaultContextAsIs(progress);
200
+ await appContext._browser._defaultContext._loadDefaultContextAsIs(progress);
201
+ });
202
+ const appParams = {
203
+ browserName: inspectedContext._browser.options.name,
204
+ sdkLanguage: inspectedContext._browser.sdkLanguage(),
205
+ wsEndpointForTest: inspectedContext._browser.options.wsEndpoint,
206
+ headed: !!inspectedContext._browser.options.headful,
207
+ executablePath: inspectedContext._browser.options.isChromium ? inspectedContext._browser.options.customExecutablePath : void 0,
208
+ channel: inspectedContext._browser.options.isChromium ? inspectedContext._browser.options.channel : void 0,
209
+ ...params
210
+ };
211
+ const recorderApp = new RecorderApp(recorder, appParams, page, appContext._browser.options.wsEndpoint);
212
+ await recorderApp._init(inspectedContext);
213
+ inspectedContext.recorderAppForTest = recorderApp;
214
+ }
215
+ _wireListeners(recorder) {
216
+ recorder.on(import_recorder.RecorderEvent.ActionAdded, (action) => {
217
+ this._onActionAdded(action);
218
+ });
219
+ recorder.on(import_recorder.RecorderEvent.SignalAdded, (signal) => {
220
+ this._onSignalAdded(signal);
221
+ });
222
+ recorder.on(import_recorder.RecorderEvent.PageNavigated, (url) => {
223
+ this._onPageNavigated(url);
224
+ });
225
+ recorder.on(import_recorder.RecorderEvent.ContextClosed, () => {
226
+ this._onContextClosed();
227
+ });
228
+ recorder.on(import_recorder.RecorderEvent.ModeChanged, (mode) => {
229
+ this._onModeChanged(mode);
230
+ });
231
+ recorder.on(import_recorder.RecorderEvent.PausedStateChanged, (paused) => {
232
+ this._onPausedStateChanged(paused);
233
+ });
234
+ recorder.on(import_recorder.RecorderEvent.UserSourcesChanged, (sources, pausedSourceId) => {
235
+ this._onUserSourcesChanged(sources, pausedSourceId);
236
+ });
237
+ recorder.on(import_recorder.RecorderEvent.ElementPicked, (elementInfo, userGesture) => {
238
+ this._onElementPicked(elementInfo, userGesture);
239
+ });
240
+ recorder.on(import_recorder.RecorderEvent.CallLogsUpdated, (callLogs) => {
241
+ this._onCallLogsUpdated(callLogs);
130
242
  });
131
- const result = new RecorderApp(recorder, page, context._browser.options.wsEndpoint);
132
- await result._init();
133
- return result;
134
243
  }
135
- async setMode(mode) {
136
- await this._page.mainFrame().evaluateExpression(((mode2) => {
137
- window.playwrightSetMode(mode2);
138
- }).toString(), { isFunction: true }, mode).catch(() => {
244
+ _onActionAdded(action) {
245
+ this._actions.push(action);
246
+ this._updateActions("reveal");
247
+ }
248
+ _onSignalAdded(signal) {
249
+ const lastAction = this._actions.findLast((a) => a.frame.pageGuid === signal.frame.pageGuid);
250
+ if (lastAction)
251
+ lastAction.action.signals.push(signal.signal);
252
+ this._updateActions();
253
+ }
254
+ _onPageNavigated(url) {
255
+ this._page.mainFrame().evaluateExpression((({ url: url2 }) => {
256
+ window.playwrightSetPageURL(url2);
257
+ }).toString(), { isFunction: true }, { url }).catch(() => {
139
258
  });
140
259
  }
141
- async setRunningFile(file) {
142
- await this._page.mainFrame().evaluateExpression(((file2) => {
143
- window.playwrightSetRunningFile(file2);
144
- }).toString(), { isFunction: true }, file).catch(() => {
260
+ _onContextClosed() {
261
+ this._throttledOutputFile?.flush();
262
+ this._page.browserContext.close({ reason: "Recorder window closed" }).catch(() => {
145
263
  });
146
264
  }
147
- async setPaused(paused) {
148
- await this._page.mainFrame().evaluateExpression(((paused2) => {
149
- window.playwrightSetPaused(paused2);
150
- }).toString(), { isFunction: true }, paused).catch(() => {
265
+ _onModeChanged(mode) {
266
+ this._page.mainFrame().evaluateExpression(((mode2) => {
267
+ window.playwrightSetMode(mode2);
268
+ }).toString(), { isFunction: true }, mode).catch(() => {
151
269
  });
152
270
  }
153
- async setSources(sources, primaryPageURL) {
154
- await this._page.mainFrame().evaluateExpression((({ sources: sources2, primaryPageURL: primaryPageURL2 }) => {
155
- window.playwrightSetSources(sources2, primaryPageURL2);
156
- }).toString(), { isFunction: true }, { sources, primaryPageURL }).catch(() => {
271
+ _onPausedStateChanged(paused) {
272
+ this._page.mainFrame().evaluateExpression(((paused2) => {
273
+ window.playwrightSetPaused(paused2);
274
+ }).toString(), { isFunction: true }, paused).catch(() => {
157
275
  });
158
- if (process.env.PWTEST_CLI_IS_UNDER_TEST && sources.length) {
159
- if (process._didSetSourcesForTest(sources[0].text))
160
- this.close();
161
- }
162
276
  }
163
- async setActions(actions, sources) {
277
+ _onUserSourcesChanged(sources, pausedSourceId) {
278
+ if (!sources.length && !this._userSources.length)
279
+ return;
280
+ this._userSources = sources;
281
+ this._pushAllSources();
282
+ this._revealSource(pausedSourceId);
164
283
  }
165
- async elementPicked(elementInfo, userGesture) {
284
+ _onElementPicked(elementInfo, userGesture) {
166
285
  if (userGesture)
167
286
  this._page.bringToFront();
168
- await this._page.mainFrame().evaluateExpression(((param) => {
287
+ this._page.mainFrame().evaluateExpression(((param) => {
169
288
  window.playwrightElementPicked(param.elementInfo, param.userGesture);
170
289
  }).toString(), { isFunction: true }, { elementInfo, userGesture }).catch(() => {
171
290
  });
172
291
  }
173
- async updateCallLogs(callLogs) {
174
- await this._page.mainFrame().evaluateExpression(((callLogs2) => {
292
+ _onCallLogsUpdated(callLogs) {
293
+ this._page.mainFrame().evaluateExpression(((callLogs2) => {
175
294
  window.playwrightUpdateLogs(callLogs2);
176
295
  }).toString(), { isFunction: true }, callLogs).catch(() => {
177
296
  });
178
297
  }
298
+ _pushAllSources() {
299
+ const sources = [...this._userSources, ...this._recorderSources];
300
+ this._page.mainFrame().evaluateExpression((({ sources: sources2 }) => {
301
+ window.playwrightSetSources(sources2);
302
+ }).toString(), { isFunction: true }, { sources }).catch(() => {
303
+ });
304
+ }
305
+ _revealSource(sourceId) {
306
+ if (!sourceId)
307
+ return;
308
+ this._page.mainFrame().evaluateExpression((({ sourceId: sourceId2 }) => {
309
+ window.playwrightSelectSource(sourceId2);
310
+ }).toString(), { isFunction: true }, { sourceId }).catch(() => {
311
+ });
312
+ }
313
+ _updateActions(reveal) {
314
+ const recorderSources = [];
315
+ const actions = (0, import_recorderUtils.collapseActions)(this._actions);
316
+ let revealSourceId;
317
+ for (const languageGenerator of (0, import_languages.languageSet)()) {
318
+ const { header, footer, actionTexts, text } = (0, import_language.generateCode)(actions, languageGenerator, this._languageGeneratorOptions);
319
+ const source = {
320
+ isRecorded: true,
321
+ label: languageGenerator.name,
322
+ group: languageGenerator.groupName,
323
+ id: languageGenerator.id,
324
+ text,
325
+ header,
326
+ footer,
327
+ actions: actionTexts,
328
+ language: languageGenerator.highlighter,
329
+ highlight: []
330
+ };
331
+ source.revealLine = text.split("\n").length - 1;
332
+ recorderSources.push(source);
333
+ if (languageGenerator.id === this._primaryGeneratorId)
334
+ this._throttledOutputFile?.setContent(source.text);
335
+ if (reveal === "reveal" && source.id === this._selectedGeneratorId)
336
+ revealSourceId = source.id;
337
+ }
338
+ this._recorderSources = recorderSources;
339
+ this._pushAllSources();
340
+ this._revealSource(revealSourceId);
341
+ }
342
+ }
343
+ function determinePrimaryGeneratorId(sdkLanguage) {
344
+ for (const language of (0, import_languages.languageSet)()) {
345
+ if (language.highlighter === sdkLanguage)
346
+ return language.id;
347
+ }
348
+ return sdkLanguage;
349
+ }
350
+ class ProgrammaticRecorderApp {
351
+ static async run(inspectedContext, recorder, browserName, params) {
352
+ let lastAction = null;
353
+ const languages = [...(0, import_languages.languageSet)()];
354
+ const languageGeneratorOptions = {
355
+ browserName,
356
+ launchOptions: { headless: false, ...params.launchOptions, tracesDir: void 0 },
357
+ contextOptions: { ...params.contextOptions },
358
+ deviceName: params.device,
359
+ saveStorage: params.saveStorage
360
+ };
361
+ const languageGenerator = languages.find((l) => l.id === params.language) ?? languages.find((l) => l.id === "playwright-test");
362
+ recorder.on(import_recorder.RecorderEvent.ActionAdded, (action) => {
363
+ const page = findPageByGuid(inspectedContext, action.frame.pageGuid);
364
+ if (!page)
365
+ return;
366
+ const { actionTexts } = (0, import_language.generateCode)([action], languageGenerator, languageGeneratorOptions);
367
+ if (!lastAction || !(0, import_recorderUtils.shouldMergeAction)(action, lastAction))
368
+ inspectedContext.emit(import_browserContext.BrowserContext.Events.RecorderEvent, { event: "actionAdded", data: action, page, code: actionTexts.join("\n") });
369
+ else
370
+ inspectedContext.emit(import_browserContext.BrowserContext.Events.RecorderEvent, { event: "actionUpdated", data: action, page, code: actionTexts.join("\n") });
371
+ lastAction = action;
372
+ });
373
+ recorder.on(import_recorder.RecorderEvent.SignalAdded, (signal) => {
374
+ const page = findPageByGuid(inspectedContext, signal.frame.pageGuid);
375
+ inspectedContext.emit(import_browserContext.BrowserContext.Events.RecorderEvent, { event: "signalAdded", data: signal, page, code: "" });
376
+ });
377
+ }
378
+ }
379
+ function findPageByGuid(context, guid) {
380
+ return context.pages().find((p) => p.guid === guid);
179
381
  }
382
+ const recorderAppSymbol = Symbol("recorderApp");
180
383
  // Annotate the CommonJS export names for ESM import in node:
181
384
  0 && (module.exports = {
182
- EmptyRecorderApp,
385
+ ProgrammaticRecorderApp,
183
386
  RecorderApp
184
387
  });
@@ -24,92 +24,91 @@ __export(recorderRunner_exports, {
24
24
  module.exports = __toCommonJS(recorderRunner_exports);
25
25
  var import_utils = require("../../utils");
26
26
  var import_language = require("../codegen/language");
27
- var import_instrumentation = require("../instrumentation");
28
27
  var import_recorderUtils = require("./recorderUtils");
28
+ var import_progress = require("../progress");
29
29
  async function performAction(pageAliases, actionInContext) {
30
- const callMetadata = (0, import_instrumentation.serverSideCallMetadata)();
31
30
  const mainFrame = (0, import_recorderUtils.mainFrameForAction)(pageAliases, actionInContext);
32
- const { action } = actionInContext;
31
+ const controller = new import_progress.ProgressController();
33
32
  const kActionTimeout = 5e3;
33
+ return await controller.run((progress) => performActionImpl(progress, mainFrame, actionInContext), kActionTimeout);
34
+ }
35
+ async function performActionImpl(progress, mainFrame, actionInContext) {
36
+ const { action } = actionInContext;
34
37
  if (action.name === "navigate") {
35
- await mainFrame.goto(callMetadata, action.url, { timeout: kActionTimeout });
38
+ await mainFrame.goto(progress, action.url);
36
39
  return;
37
40
  }
38
41
  if (action.name === "openPage")
39
42
  throw Error("Not reached");
40
43
  if (action.name === "closePage") {
41
- await mainFrame._page.close(callMetadata);
44
+ await mainFrame._page.close();
42
45
  return;
43
46
  }
44
47
  const selector = (0, import_recorderUtils.buildFullSelector)(actionInContext.frame.framePath, action.selector);
45
48
  if (action.name === "click") {
46
49
  const options = toClickOptions(action);
47
- await mainFrame.click(callMetadata, selector, { ...options, timeout: kActionTimeout, strict: true });
50
+ await mainFrame.click(progress, selector, { ...options, strict: true });
48
51
  return;
49
52
  }
50
53
  if (action.name === "press") {
51
54
  const modifiers = (0, import_language.toKeyboardModifiers)(action.modifiers);
52
55
  const shortcut = [...modifiers, action.key].join("+");
53
- await mainFrame.press(callMetadata, selector, shortcut, { timeout: kActionTimeout, strict: true });
56
+ await mainFrame.press(progress, selector, shortcut, { strict: true });
54
57
  return;
55
58
  }
56
59
  if (action.name === "fill") {
57
- await mainFrame.fill(callMetadata, selector, action.text, { timeout: kActionTimeout, strict: true });
60
+ await mainFrame.fill(progress, selector, action.text, { strict: true });
58
61
  return;
59
62
  }
60
63
  if (action.name === "setInputFiles") {
61
- await mainFrame.setInputFiles(callMetadata, selector, { selector, payloads: [], timeout: kActionTimeout, strict: true });
64
+ await mainFrame.setInputFiles(progress, selector, { selector, payloads: [], strict: true });
62
65
  return;
63
66
  }
64
67
  if (action.name === "check") {
65
- await mainFrame.check(callMetadata, selector, { timeout: kActionTimeout, strict: true });
68
+ await mainFrame.check(progress, selector, { strict: true });
66
69
  return;
67
70
  }
68
71
  if (action.name === "uncheck") {
69
- await mainFrame.uncheck(callMetadata, selector, { timeout: kActionTimeout, strict: true });
72
+ await mainFrame.uncheck(progress, selector, { strict: true });
70
73
  return;
71
74
  }
72
75
  if (action.name === "select") {
73
76
  const values = action.options.map((value) => ({ value }));
74
- await mainFrame.selectOption(callMetadata, selector, [], values, { timeout: kActionTimeout, strict: true });
77
+ await mainFrame.selectOption(progress, selector, [], values, { strict: true });
75
78
  return;
76
79
  }
77
80
  if (action.name === "assertChecked") {
78
- await mainFrame.expect(callMetadata, selector, {
81
+ await mainFrame.expect(progress, selector, {
79
82
  selector,
80
83
  expression: "to.be.checked",
81
84
  expectedValue: { checked: action.checked },
82
- isNot: !action.checked,
83
- timeout: kActionTimeout
85
+ isNot: !action.checked
84
86
  });
85
87
  return;
86
88
  }
87
89
  if (action.name === "assertText") {
88
- await mainFrame.expect(callMetadata, selector, {
90
+ await mainFrame.expect(progress, selector, {
89
91
  selector,
90
92
  expression: "to.have.text",
91
93
  expectedText: (0, import_utils.serializeExpectedTextValues)([action.text], { matchSubstring: true, normalizeWhiteSpace: true }),
92
- isNot: false,
93
- timeout: kActionTimeout
94
+ isNot: false
94
95
  });
95
96
  return;
96
97
  }
97
98
  if (action.name === "assertValue") {
98
- await mainFrame.expect(callMetadata, selector, {
99
+ await mainFrame.expect(progress, selector, {
99
100
  selector,
100
101
  expression: "to.have.value",
101
102
  expectedValue: action.value,
102
- isNot: false,
103
- timeout: kActionTimeout
103
+ isNot: false
104
104
  });
105
105
  return;
106
106
  }
107
107
  if (action.name === "assertVisible") {
108
- await mainFrame.expect(callMetadata, selector, {
108
+ await mainFrame.expect(progress, selector, {
109
109
  selector,
110
110
  expression: "to.be.visible",
111
- isNot: false,
112
- timeout: kActionTimeout
111
+ isNot: false
113
112
  });
114
113
  return;
115
114
  }
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var recorderSignalProcessor_exports = {};
20
+ __export(recorderSignalProcessor_exports, {
21
+ RecorderSignalProcessor: () => RecorderSignalProcessor
22
+ });
23
+ module.exports = __toCommonJS(recorderSignalProcessor_exports);
24
+ var import_debug = require("../utils/debug");
25
+ var import_time = require("../../utils/isomorphic/time");
26
+ var import_recorderUtils = require("./recorderUtils");
27
+ class RecorderSignalProcessor {
28
+ constructor(actionSink) {
29
+ this._lastAction = null;
30
+ this._delegate = actionSink;
31
+ }
32
+ addAction(actionInContext) {
33
+ this._lastAction = actionInContext;
34
+ this._delegate.addAction(actionInContext);
35
+ }
36
+ signal(pageAlias, frame, signal) {
37
+ const timestamp = (0, import_time.monotonicTime)();
38
+ if (signal.name === "navigation" && frame._page.mainFrame() === frame) {
39
+ const lastAction = this._lastAction;
40
+ const signalThreshold = (0, import_debug.isUnderTest)() ? 500 : 5e3;
41
+ let generateGoto = false;
42
+ if (!lastAction)
43
+ generateGoto = true;
44
+ else if (lastAction.action.name !== "click" && lastAction.action.name !== "press" && lastAction.action.name !== "fill")
45
+ generateGoto = true;
46
+ else if (timestamp - lastAction.startTime > signalThreshold)
47
+ generateGoto = true;
48
+ if (generateGoto) {
49
+ this.addAction({
50
+ frame: {
51
+ pageGuid: frame._page.guid,
52
+ pageAlias,
53
+ framePath: []
54
+ },
55
+ action: {
56
+ name: "navigate",
57
+ url: frame.url(),
58
+ signals: []
59
+ },
60
+ startTime: timestamp,
61
+ endTime: timestamp
62
+ });
63
+ }
64
+ return;
65
+ }
66
+ (0, import_recorderUtils.generateFrameSelector)(frame).then((framePath) => {
67
+ const signalInContext = {
68
+ frame: {
69
+ pageGuid: frame._page.guid,
70
+ pageAlias,
71
+ framePath
72
+ },
73
+ signal,
74
+ timestamp
75
+ };
76
+ this._delegate.addSignal(signalInContext);
77
+ });
78
+ }
79
+ }
80
+ // Annotate the CommonJS export names for ESM import in node:
81
+ 0 && (module.exports = {
82
+ RecorderSignalProcessor
83
+ });