@checkly/playwright-core 1.47.20-alpha → 1.48.10-alpha

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 (167) hide show
  1. package/browsers.json +14 -10
  2. package/lib/checkly/escapeRegExp.js +33 -0
  3. package/lib/checkly/secretsFilter.js +23 -0
  4. package/lib/cli/program.js +22 -12
  5. package/lib/client/api.js +6 -0
  6. package/lib/client/browserContext.js +20 -2
  7. package/lib/client/channelOwner.js +5 -2
  8. package/lib/client/connection.js +3 -0
  9. package/lib/client/fetch.js +16 -3
  10. package/lib/client/jsHandle.js +0 -8
  11. package/lib/client/localUtils.js +1 -0
  12. package/lib/client/network.js +175 -17
  13. package/lib/client/page.js +21 -0
  14. package/lib/client/playwright.js +6 -3
  15. package/lib/client/tracing.js +16 -20
  16. package/lib/generated/consoleApiSource.js +1 -1
  17. package/lib/generated/injectedScriptSource.js +1 -1
  18. package/lib/generated/pollingRecorderSource.js +7 -0
  19. package/lib/generated/webSocketMockSource.js +7 -0
  20. package/lib/protocol/validator.js +79 -14
  21. package/lib/server/bidi/bidiBrowser.js +23 -8
  22. package/lib/server/bidi/bidiChromium.js +124 -0
  23. package/lib/server/bidi/bidiConnection.js +1 -1
  24. package/lib/server/bidi/bidiExecutionContext.js +0 -3
  25. package/lib/server/bidi/bidiFirefox.js +15 -21
  26. package/lib/server/bidi/bidiInput.js +16 -32
  27. package/lib/server/bidi/bidiNetworkManager.js +39 -5
  28. package/lib/server/bidi/bidiOverCdp.js +103 -0
  29. package/lib/server/bidi/bidiPage.js +98 -25
  30. package/lib/server/bidi/bidiPdf.js +140 -0
  31. package/lib/server/bidi/third_party/firefoxPrefs.js +221 -0
  32. package/lib/server/browser.js +13 -2
  33. package/lib/server/browserContext.js +6 -23
  34. package/lib/server/browserType.js +39 -11
  35. package/lib/server/chromium/chromium.js +3 -15
  36. package/lib/server/chromium/chromiumSwitches.js +3 -1
  37. package/lib/server/chromium/crBrowser.js +4 -3
  38. package/lib/server/chromium/crExecutionContext.js +0 -7
  39. package/lib/server/chromium/crPage.js +5 -2
  40. package/lib/server/chromium/videoRecorder.js +1 -1
  41. package/lib/server/codegen/csharp.js +2 -2
  42. package/lib/server/codegen/java.js +1 -1
  43. package/lib/server/codegen/javascript.js +1 -1
  44. package/lib/server/codegen/language.js +14 -2
  45. package/lib/server/codegen/python.js +2 -2
  46. package/lib/server/cookieStore.js +73 -0
  47. package/lib/server/debugController.js +2 -2
  48. package/lib/server/deviceDescriptorsSource.json +51 -51
  49. package/lib/server/dialog.js +1 -0
  50. package/lib/server/dispatchers/browserContextDispatcher.js +19 -2
  51. package/lib/server/dispatchers/jsHandleDispatcher.js +0 -5
  52. package/lib/server/dispatchers/pageDispatcher.js +9 -0
  53. package/lib/server/dispatchers/playwrightDispatcher.js +2 -1
  54. package/lib/server/dispatchers/webSocketRouteDispatcher.js +189 -0
  55. package/lib/server/download.js +9 -2
  56. package/lib/server/fetch.js +96 -99
  57. package/lib/server/firefox/ffBrowser.js +6 -4
  58. package/lib/server/firefox/ffExecutionContext.js +0 -3
  59. package/lib/server/firefox/ffPage.js +3 -0
  60. package/lib/server/firefox/firefox.js +2 -13
  61. package/lib/server/frameSelectors.js +1 -1
  62. package/lib/server/frames.js +3 -2
  63. package/lib/server/har/harTracer.js +11 -0
  64. package/lib/server/input.js +0 -1
  65. package/lib/server/javascript.js +0 -7
  66. package/lib/server/page.js +5 -1
  67. package/lib/server/playwright.js +5 -2
  68. package/lib/server/recorder/contextRecorder.js +33 -50
  69. package/lib/server/recorder/recorderActions.js +2 -1
  70. package/lib/server/recorder/recorderApp.js +15 -9
  71. package/lib/server/recorder/recorderCollection.js +68 -79
  72. package/lib/server/recorder/recorderFrontend.js +5 -0
  73. package/lib/server/recorder/recorderInTraceViewer.js +144 -0
  74. package/lib/server/recorder/recorderRunner.js +75 -97
  75. package/lib/server/recorder/recorderUtils.js +47 -6
  76. package/lib/server/recorder.js +28 -25
  77. package/lib/server/registry/index.js +85 -4
  78. package/lib/server/socksClientCertificatesInterceptor.js +15 -3
  79. package/lib/server/trace/recorder/snapshotter.js +1 -0
  80. package/lib/server/trace/recorder/snapshotterInjected.js +2 -2
  81. package/lib/server/trace/recorder/tracing.js +70 -5
  82. package/lib/server/trace/test/inMemorySnapshotter.js +1 -1
  83. package/lib/server/trace/viewer/traceViewer.js +2 -5
  84. package/lib/server/webkit/webkit.js +1 -1
  85. package/lib/server/webkit/wkBrowser.js +6 -5
  86. package/lib/server/webkit/wkExecutionContext.js +0 -3
  87. package/lib/server/webkit/wkPage.js +4 -1
  88. package/lib/utils/happy-eyeballs.js +13 -0
  89. package/lib/utils/hostPlatform.js +2 -2
  90. package/lib/utils/httpServer.js +1 -0
  91. package/lib/utils/isomorphic/locatorGenerators.js +9 -18
  92. package/lib/utils/isomorphic/locatorParser.js +2 -2
  93. package/lib/utils/isomorphic/recorderUtils.js +195 -0
  94. package/lib/vite/htmlReport/index.html +12 -12
  95. package/lib/vite/recorder/assets/codeMirrorModule-CND2fZ5Q.js +24 -0
  96. package/lib/vite/recorder/assets/{index-B-MT5gKo.css → index-BW-aOBcL.css} +1 -1
  97. package/lib/vite/recorder/assets/{index-D-5S5PPN.js → index-CEc83sSS.js} +10 -15
  98. package/lib/vite/recorder/index.html +2 -2
  99. package/lib/vite/traceViewer/assets/codeMirrorModule-BdBhzV6t.js +16443 -0
  100. package/lib/vite/traceViewer/assets/codeMirrorModule-BqcXH1AO.js +16838 -0
  101. package/lib/vite/traceViewer/assets/codeMirrorModule-Ca-1BNel.js +24 -0
  102. package/lib/vite/traceViewer/assets/codeMirrorModule-CcviAl53.js +16831 -0
  103. package/lib/vite/traceViewer/assets/codeMirrorModule-DS3v0XrQ.js +24 -0
  104. package/lib/vite/traceViewer/assets/codeMirrorModule-EhKN7Okm.js +16449 -0
  105. package/lib/vite/{recorder/assets/codeMirrorModule-C-fQ5QZD.js → traceViewer/assets/codeMirrorModule-MzSmL4X2.js} +1 -1
  106. package/lib/vite/traceViewer/assets/codeMirrorModule-U6XMqGkV.js +16437 -0
  107. package/lib/vite/traceViewer/assets/inspectorTab-BABZNwlH.js +17351 -0
  108. package/lib/vite/traceViewer/assets/inspectorTab-BPzVEZSf.js +17351 -0
  109. package/lib/vite/traceViewer/assets/inspectorTab-Bbgq0hgt.js +64 -0
  110. package/lib/vite/traceViewer/assets/inspectorTab-DhBbZz8I.js +64 -0
  111. package/lib/vite/traceViewer/assets/inspectorTab-DpvLVMq5.js +17351 -0
  112. package/lib/vite/traceViewer/assets/workbench-B13nfocr.js +9 -0
  113. package/lib/vite/traceViewer/assets/workbench-BcgGQnKb.js +1473 -0
  114. package/lib/vite/traceViewer/assets/workbench-BwodYCgl.js +19119 -0
  115. package/lib/vite/traceViewer/assets/workbench-ByyWxoT8.js +1473 -0
  116. package/lib/vite/traceViewer/assets/workbench-Crj6jzdv.js +19119 -0
  117. package/lib/vite/traceViewer/assets/workbench-DhqI6jeL.js +1473 -0
  118. package/lib/vite/traceViewer/assets/workbench-Pa1v1Ojh.js +72 -0
  119. package/lib/vite/traceViewer/assets/workbench-gtYcQBNA.js +9 -0
  120. package/lib/vite/traceViewer/assets/xtermModule-DZP0glxx.js +5982 -0
  121. package/lib/vite/traceViewer/embedded.27BGR_eD.js +105 -0
  122. package/lib/vite/traceViewer/embedded.BBZ9gQEw.js +104 -0
  123. package/lib/vite/traceViewer/embedded.CorI3dFX.js +104 -0
  124. package/lib/vite/traceViewer/embedded.D4lqGydT.js +2 -0
  125. package/lib/vite/traceViewer/embedded.DTjd2aiy.js +105 -0
  126. package/lib/vite/traceViewer/embedded.DbzY7Q8w.js +2 -0
  127. package/lib/vite/traceViewer/embedded.SsjKHrxC.js +105 -0
  128. package/lib/vite/traceViewer/embedded.f-PLGsBT.js +2 -0
  129. package/lib/vite/traceViewer/embedded.html +5 -3
  130. package/lib/vite/traceViewer/index.B7aiTMfZ.js +2 -0
  131. package/lib/vite/traceViewer/index.BSak5QT9.js +2 -0
  132. package/lib/vite/traceViewer/index.BrT2kfuc.js +2 -0
  133. package/lib/vite/traceViewer/index.DkRbtWVo.js +195 -0
  134. package/lib/vite/traceViewer/index.DsjmhbB6.js +195 -0
  135. package/lib/vite/traceViewer/index.Dz3icWJV.js +196 -0
  136. package/lib/vite/traceViewer/index.PqcsvBxQ.js +196 -0
  137. package/lib/vite/traceViewer/index.html +5 -3
  138. package/lib/vite/traceViewer/index.yxAwzeWG.js +196 -0
  139. package/lib/vite/traceViewer/inspectorTab.DGJWXOSd.css +3145 -0
  140. package/lib/vite/traceViewer/inspectorTab.DLjBDrQR.css +1 -0
  141. package/lib/vite/traceViewer/recorder.7Wl6HrQl.js +550 -0
  142. package/lib/vite/traceViewer/recorder.B_SY1GJM.css +0 -0
  143. package/lib/vite/traceViewer/recorder.BufKu9Hp.js +550 -0
  144. package/lib/vite/traceViewer/recorder.Ch-WHviK.js +2 -0
  145. package/lib/vite/traceViewer/recorder.DBDpiNOK.css +15 -0
  146. package/lib/vite/traceViewer/recorder.POd-toIn.js +2 -0
  147. package/lib/vite/traceViewer/recorder.am-MV-DQ.js +550 -0
  148. package/lib/vite/traceViewer/recorder.html +17 -0
  149. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  150. package/lib/vite/traceViewer/uiMode.BEZVCe5O.js +5 -0
  151. package/lib/vite/traceViewer/uiMode.BZoFj6zV.js +1723 -0
  152. package/lib/vite/traceViewer/uiMode.C4nbcio6.js +1730 -0
  153. package/lib/vite/traceViewer/uiMode.CAYqod-m.css +1 -0
  154. package/lib/vite/traceViewer/uiMode.DRmgrHSk.css +1462 -0
  155. package/lib/vite/traceViewer/uiMode.DdtUZZVS.js +5 -0
  156. package/lib/vite/traceViewer/uiMode.Dlo9s_YX.js +1723 -0
  157. package/lib/vite/traceViewer/uiMode.O07awP3T.js +10 -0
  158. package/lib/vite/traceViewer/uiMode.gGHHTsyL.js +1730 -0
  159. package/lib/vite/traceViewer/uiMode.html +6 -4
  160. package/lib/vite/traceViewer/uiMode.wsGnVMQK.js +1723 -0
  161. package/lib/vite/traceViewer/workbench.BQNDbcQ0.css +550 -0
  162. package/lib/vite/traceViewer/workbench.DjbIuxix.css +1 -0
  163. package/lib/vite/traceViewer/workbench.DlsCx8k5.css +1 -0
  164. package/lib/vite/traceViewer/workbench.wuxQoE2z.css +3703 -0
  165. package/package.json +1 -1
  166. package/types/protocol.d.ts +610 -173
  167. package/types/types.d.ts +2037 -949
@@ -0,0 +1,550 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ import { j as jsxRuntimeExports, r as reactExports, M as MultiTraceModel, F as sha1, n as asLocator, L as ListView, g as Toolbar, T as ToolbarButton, H as ToolbarSeparator, J as copy, t as toggleTheme, S as SplitView, D as TabbedPane, y as useConsoleTabModel, z as useNetworkTabModel, h as useSetting, A as ConsoleTab, N as NetworkTab, K as collectSnapshots, O as extendSnapshot, Q as SnapshotView, I as InspectorTab, E as SourceTab, a as applyTheme, c as createRoot } from "./assets/inspectorTab-BPzVEZSf.js";
5
+ const SourceChooser = ({ sources, fileId, setFileId }) => {
6
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("select", { className: "source-chooser", hidden: !sources.length, title: "Source chooser", value: fileId, onChange: (event) => {
7
+ setFileId(event.target.selectedOptions[0].value);
8
+ }, children: renderSourceOptions(sources) });
9
+ };
10
+ function renderSourceOptions(sources) {
11
+ const transformTitle = (title) => title.replace(/.*[/\\]([^/\\]+)/, "$1");
12
+ const renderOption = (source) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: source.id, children: transformTitle(source.label) }, source.id);
13
+ const sourcesByGroups = /* @__PURE__ */ new Map();
14
+ for (const source of sources) {
15
+ let list = sourcesByGroups.get(source.group || "Debugger");
16
+ if (!list) {
17
+ list = [];
18
+ sourcesByGroups.set(source.group || "Debugger", list);
19
+ }
20
+ list.push(source);
21
+ }
22
+ return [...sourcesByGroups.entries()].map(([group, sources2]) => /* @__PURE__ */ jsxRuntimeExports.jsx("optgroup", { label: group, children: sources2.filter((s) => (s.group || "Debugger") === group).map((source) => renderOption(source)) }, group));
23
+ }
24
+ const ModelContext = reactExports.createContext(void 0);
25
+ const ModelProvider = ({ trace, children }) => {
26
+ const [model, setModel] = reactExports.useState();
27
+ const [counter, setCounter] = reactExports.useState(0);
28
+ const pollTimer = reactExports.useRef(null);
29
+ reactExports.useEffect(() => {
30
+ if (pollTimer.current)
31
+ clearTimeout(pollTimer.current);
32
+ pollTimer.current = setTimeout(async () => {
33
+ try {
34
+ const result = await loadSingleTraceFile(trace);
35
+ if (result.sha1 !== (model == null ? void 0 : model.sha1))
36
+ setModel(result);
37
+ } catch {
38
+ setModel(void 0);
39
+ } finally {
40
+ setCounter(counter + 1);
41
+ }
42
+ }, 500);
43
+ return () => {
44
+ if (pollTimer.current)
45
+ clearTimeout(pollTimer.current);
46
+ };
47
+ }, [counter, model, trace]);
48
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(ModelContext.Provider, { value: model == null ? void 0 : model.model, children });
49
+ };
50
+ async function loadSingleTraceFile(url) {
51
+ const params = new URLSearchParams();
52
+ params.set("trace", url);
53
+ const response = await fetch(`contexts?${params.toString()}`);
54
+ const contextEntries = await response.json();
55
+ const tokens = [];
56
+ for (const entry of contextEntries) {
57
+ entry.actions.forEach((a) => tokens.push(a.type + "@" + a.startTime + "-" + a.endTime));
58
+ entry.events.forEach((e) => tokens.push(e.type + "@" + e.time));
59
+ }
60
+ return { model: new MultiTraceModel(contextEntries), sha1: await sha1(tokens.join("|")) };
61
+ }
62
+ function buildFullSelector(framePath, selector) {
63
+ return [...framePath, selector].join(" >> internal:control=enter-frame >> ");
64
+ }
65
+ function traceParamsForAction(actionInContext) {
66
+ const { action } = actionInContext;
67
+ switch (action.name) {
68
+ case "navigate": {
69
+ const params = {
70
+ url: action.url
71
+ };
72
+ return { method: "goto", params };
73
+ }
74
+ case "openPage":
75
+ case "closePage":
76
+ throw new Error("Not reached");
77
+ }
78
+ const selector = buildFullSelector(actionInContext.frame.framePath, action.selector);
79
+ switch (action.name) {
80
+ case "click": {
81
+ const params = {
82
+ selector,
83
+ strict: true,
84
+ modifiers: toKeyboardModifiers(action.modifiers),
85
+ button: action.button,
86
+ clickCount: action.clickCount,
87
+ position: action.position
88
+ };
89
+ return { method: "click", params };
90
+ }
91
+ case "press": {
92
+ const params = {
93
+ selector,
94
+ strict: true,
95
+ key: [...toKeyboardModifiers(action.modifiers), action.key].join("+")
96
+ };
97
+ return { method: "press", params };
98
+ }
99
+ case "fill": {
100
+ const params = {
101
+ selector,
102
+ strict: true,
103
+ value: action.text
104
+ };
105
+ return { method: "fill", params };
106
+ }
107
+ case "setInputFiles": {
108
+ const params = {
109
+ selector,
110
+ strict: true,
111
+ localPaths: action.files
112
+ };
113
+ return { method: "setInputFiles", params };
114
+ }
115
+ case "check": {
116
+ const params = {
117
+ selector,
118
+ strict: true
119
+ };
120
+ return { method: "check", params };
121
+ }
122
+ case "uncheck": {
123
+ const params = {
124
+ selector,
125
+ strict: true
126
+ };
127
+ return { method: "uncheck", params };
128
+ }
129
+ case "select": {
130
+ const params = {
131
+ selector,
132
+ strict: true,
133
+ options: action.options.map((option) => ({ value: option }))
134
+ };
135
+ return { method: "selectOption", params };
136
+ }
137
+ case "assertChecked": {
138
+ const params = {
139
+ selector: action.selector,
140
+ expression: "to.be.checked",
141
+ isNot: !action.checked
142
+ };
143
+ return { method: "expect", params };
144
+ }
145
+ case "assertText": {
146
+ const params = {
147
+ selector,
148
+ expression: "to.have.text",
149
+ expectedText: [],
150
+ isNot: false
151
+ };
152
+ return { method: "expect", params };
153
+ }
154
+ case "assertValue": {
155
+ const params = {
156
+ selector,
157
+ expression: "to.have.value",
158
+ expectedValue: void 0,
159
+ isNot: false
160
+ };
161
+ return { method: "expect", params };
162
+ }
163
+ case "assertVisible": {
164
+ const params = {
165
+ selector,
166
+ expression: "to.be.visible",
167
+ isNot: false
168
+ };
169
+ return { method: "expect", params };
170
+ }
171
+ }
172
+ }
173
+ function toKeyboardModifiers(modifiers) {
174
+ const result = [];
175
+ if (modifiers & 1)
176
+ result.push("Alt");
177
+ if (modifiers & 2)
178
+ result.push("ControlOrMeta");
179
+ if (modifiers & 4)
180
+ result.push("ControlOrMeta");
181
+ if (modifiers & 8)
182
+ result.push("Shift");
183
+ return result;
184
+ }
185
+ const ActionList = ListView;
186
+ const ActionListView = ({
187
+ sdkLanguage,
188
+ actions,
189
+ selectedAction,
190
+ onSelectedAction
191
+ }) => {
192
+ const render = reactExports.useCallback((action) => {
193
+ return renderAction(sdkLanguage, action);
194
+ }, [sdkLanguage]);
195
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "vbox", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
196
+ ActionList,
197
+ {
198
+ name: "actions",
199
+ items: actions,
200
+ selectedItem: selectedAction,
201
+ onSelected: onSelectedAction,
202
+ render
203
+ }
204
+ ) });
205
+ };
206
+ const renderAction = (sdkLanguage, action) => {
207
+ const { method, params } = traceParamsForAction(action);
208
+ const locator = params.selector ? asLocator(sdkLanguage || "javascript", params.selector) : void 0;
209
+ const apiName = `page.${method}`;
210
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "action-title", title: apiName, children: [
211
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: apiName }),
212
+ locator && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "action-selector", title: locator, children: locator }),
213
+ method === "goto" && params.url && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "action-url", title: params.url, children: params.url })
214
+ ] }) });
215
+ };
216
+ const BackendContext = reactExports.createContext(void 0);
217
+ const BackendProvider = ({ guid, children }) => {
218
+ const [connection, setConnection] = reactExports.useState(void 0);
219
+ const [mode, setMode] = reactExports.useState("none");
220
+ const [actions, setActions] = reactExports.useState({ actions: [], sources: [] });
221
+ const callbacks = reactExports.useRef({ setMode, setActions });
222
+ reactExports.useEffect(() => {
223
+ const wsURL = new URL(`../${guid}`, window.location.toString());
224
+ wsURL.protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
225
+ const webSocket = new WebSocket(wsURL.toString());
226
+ setConnection(new Connection(webSocket, callbacks.current));
227
+ return () => {
228
+ webSocket.close();
229
+ };
230
+ }, [guid]);
231
+ const backend = reactExports.useMemo(() => {
232
+ return connection ? { mode, actions: actions.actions, sources: actions.sources, connection } : void 0;
233
+ }, [actions, mode, connection]);
234
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(BackendContext.Provider, { value: backend, children });
235
+ };
236
+ class Connection {
237
+ constructor(webSocket, options) {
238
+ __publicField(this, "_lastId", 0);
239
+ __publicField(this, "_webSocket");
240
+ __publicField(this, "_callbacks", /* @__PURE__ */ new Map());
241
+ __publicField(this, "_options");
242
+ this._webSocket = webSocket;
243
+ this._callbacks = /* @__PURE__ */ new Map();
244
+ this._options = options;
245
+ this._webSocket.addEventListener("message", (event) => {
246
+ const message = JSON.parse(event.data);
247
+ const { id, result, error, method, params } = message;
248
+ if (id) {
249
+ const callback = this._callbacks.get(id);
250
+ if (!callback)
251
+ return;
252
+ this._callbacks.delete(id);
253
+ if (error)
254
+ callback.reject(new Error(error));
255
+ else
256
+ callback.resolve(result);
257
+ } else {
258
+ this._dispatchEvent(method, params);
259
+ }
260
+ });
261
+ }
262
+ setMode(mode) {
263
+ this._sendMessageNoReply("setMode", { mode });
264
+ }
265
+ async _sendMessage(method, params) {
266
+ const id = ++this._lastId;
267
+ const message = { id, method, params };
268
+ this._webSocket.send(JSON.stringify(message));
269
+ return new Promise((resolve, reject) => {
270
+ this._callbacks.set(id, { resolve, reject });
271
+ });
272
+ }
273
+ _sendMessageNoReply(method, params) {
274
+ this._sendMessage(method, params).catch(() => {
275
+ });
276
+ }
277
+ _dispatchEvent(method, params) {
278
+ if (method === "setMode") {
279
+ const { mode } = params;
280
+ this._options.setMode(mode);
281
+ }
282
+ if (method === "setActions") {
283
+ const { actions, sources } = params;
284
+ this._options.setActions({ actions: actions.filter((a) => a.action.name !== "openPage" && a.action.name !== "closePage"), sources });
285
+ window.playwrightSourcesEchoForTest = sources;
286
+ }
287
+ }
288
+ }
289
+ const RecorderView = () => {
290
+ const searchParams = new URLSearchParams(window.location.search);
291
+ const guid = searchParams.get("ws");
292
+ const trace = searchParams.get("trace") + ".json";
293
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(BackendProvider, { guid, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ModelProvider, { trace, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Workbench, {}) }) });
294
+ };
295
+ const Workbench = () => {
296
+ const backend = reactExports.useContext(BackendContext);
297
+ const model = reactExports.useContext(ModelContext);
298
+ const [fileId, setFileId] = reactExports.useState();
299
+ const [selectedStartTime, setSelectedStartTime] = reactExports.useState(void 0);
300
+ const [isInspecting, setIsInspecting] = reactExports.useState(false);
301
+ const [highlightedLocatorInProperties, setHighlightedLocatorInProperties] = reactExports.useState("");
302
+ const [highlightedLocatorInTrace, setHighlightedLocatorInTrace] = reactExports.useState("");
303
+ const [traceCallId, setTraceCallId] = reactExports.useState();
304
+ const setSelectedAction = reactExports.useCallback((action) => {
305
+ setSelectedStartTime(action == null ? void 0 : action.startTime);
306
+ }, []);
307
+ const selectedAction = reactExports.useMemo(() => {
308
+ return backend == null ? void 0 : backend.actions.find((a) => a.startTime === selectedStartTime);
309
+ }, [backend == null ? void 0 : backend.actions, selectedStartTime]);
310
+ reactExports.useEffect(() => {
311
+ var _a;
312
+ const callId = (_a = model == null ? void 0 : model.actions.find((a) => a.endTime && a.endTime === (selectedAction == null ? void 0 : selectedAction.endTime))) == null ? void 0 : _a.callId;
313
+ if (callId)
314
+ setTraceCallId(callId);
315
+ }, [model, selectedAction]);
316
+ const source = reactExports.useMemo(() => (backend == null ? void 0 : backend.sources.find((s) => s.id === fileId)) || (backend == null ? void 0 : backend.sources[0]), [backend == null ? void 0 : backend.sources, fileId]);
317
+ const sourceLocation = reactExports.useMemo(() => {
318
+ if (!source)
319
+ return void 0;
320
+ const sourceLocation2 = {
321
+ file: "",
322
+ line: 0,
323
+ column: 0,
324
+ source: {
325
+ errors: [],
326
+ content: source.text
327
+ }
328
+ };
329
+ return sourceLocation2;
330
+ }, [source]);
331
+ const sdkLanguage = (source == null ? void 0 : source.language) || "javascript";
332
+ const { boundaries } = reactExports.useMemo(() => {
333
+ const boundaries2 = { minimum: (model == null ? void 0 : model.startTime) || 0, maximum: (model == null ? void 0 : model.endTime) || 3e4 };
334
+ if (boundaries2.minimum > boundaries2.maximum) {
335
+ boundaries2.minimum = 0;
336
+ boundaries2.maximum = 3e4;
337
+ }
338
+ boundaries2.maximum += (boundaries2.maximum - boundaries2.minimum) / 20;
339
+ return { boundaries: boundaries2 };
340
+ }, [model]);
341
+ const locatorPickedInTrace = reactExports.useCallback((locator) => {
342
+ setHighlightedLocatorInProperties(locator);
343
+ setHighlightedLocatorInTrace("");
344
+ setIsInspecting(false);
345
+ }, []);
346
+ const locatorTypedInProperties = reactExports.useCallback((locator) => {
347
+ setHighlightedLocatorInTrace(locator);
348
+ setHighlightedLocatorInProperties(locator);
349
+ }, []);
350
+ const actionList = /* @__PURE__ */ jsxRuntimeExports.jsx(
351
+ ActionListView,
352
+ {
353
+ sdkLanguage,
354
+ actions: (backend == null ? void 0 : backend.actions) || [],
355
+ selectedAction,
356
+ onSelectedAction: setSelectedAction
357
+ }
358
+ );
359
+ const actionsTab = {
360
+ id: "actions",
361
+ title: "Actions",
362
+ component: actionList
363
+ };
364
+ const toolbar = /* @__PURE__ */ jsxRuntimeExports.jsxs(Toolbar, { sidebarBackground: true, children: [
365
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: 4 } }),
366
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ToolbarButton, { icon: "inspect", title: "Pick locator", toggled: isInspecting, onClick: () => {
367
+ setIsInspecting(!isInspecting);
368
+ } }),
369
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ToolbarButton, { icon: "eye", title: "Assert visibility", onClick: () => {
370
+ } }),
371
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ToolbarButton, { icon: "whole-word", title: "Assert text", onClick: () => {
372
+ } }),
373
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ToolbarButton, { icon: "symbol-constant", title: "Assert value", onClick: () => {
374
+ } }),
375
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ToolbarSeparator, {}),
376
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ToolbarButton, { icon: "files", title: "Copy", disabled: !source || !source.text, onClick: () => {
377
+ if (source == null ? void 0 : source.text)
378
+ copy(source.text);
379
+ } }),
380
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { flex: "auto" } }),
381
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Target:" }),
382
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SourceChooser, { fileId, sources: (backend == null ? void 0 : backend.sources) || [], setFileId: (fileId2) => {
383
+ setFileId(fileId2);
384
+ } }),
385
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ToolbarButton, { icon: "color-mode", title: "Toggle color mode", toggled: false, onClick: () => toggleTheme() })
386
+ ] });
387
+ const sidebarTabbedPane = /* @__PURE__ */ jsxRuntimeExports.jsx(TabbedPane, { tabs: [actionsTab] });
388
+ const traceView = /* @__PURE__ */ jsxRuntimeExports.jsx(
389
+ TraceView,
390
+ {
391
+ sdkLanguage,
392
+ callId: traceCallId,
393
+ isInspecting,
394
+ setIsInspecting,
395
+ highlightedLocator: highlightedLocatorInTrace,
396
+ setHighlightedLocator: locatorPickedInTrace
397
+ }
398
+ );
399
+ const propertiesView = /* @__PURE__ */ jsxRuntimeExports.jsx(
400
+ PropertiesView,
401
+ {
402
+ sdkLanguage,
403
+ boundaries,
404
+ setIsInspecting,
405
+ highlightedLocator: highlightedLocatorInProperties,
406
+ setHighlightedLocator: locatorTypedInProperties,
407
+ sourceLocation
408
+ }
409
+ );
410
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "vbox workbench", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
411
+ SplitView,
412
+ {
413
+ sidebarSize: 250,
414
+ orientation: "horizontal",
415
+ settingName: "recorderActionListSidebar",
416
+ sidebarIsFirst: true,
417
+ main: /* @__PURE__ */ jsxRuntimeExports.jsx(
418
+ SplitView,
419
+ {
420
+ sidebarSize: 250,
421
+ orientation: "vertical",
422
+ settingName: "recorderPropertiesSidebar",
423
+ main: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "vbox", children: [
424
+ toolbar,
425
+ traceView
426
+ ] }),
427
+ sidebar: propertiesView
428
+ }
429
+ ),
430
+ sidebar: sidebarTabbedPane
431
+ }
432
+ ) });
433
+ };
434
+ const PropertiesView = ({
435
+ sdkLanguage,
436
+ boundaries,
437
+ setIsInspecting,
438
+ highlightedLocator,
439
+ setHighlightedLocator,
440
+ sourceLocation
441
+ }) => {
442
+ const model = reactExports.useContext(ModelContext);
443
+ const consoleModel = useConsoleTabModel(model, boundaries);
444
+ const networkModel = useNetworkTabModel(model, boundaries);
445
+ const sourceModel = reactExports.useRef(/* @__PURE__ */ new Map());
446
+ const [selectedPropertiesTab, setSelectedPropertiesTab] = useSetting("recorderPropertiesTab", "source");
447
+ const inspectorTab = {
448
+ id: "inspector",
449
+ title: "Locator",
450
+ render: () => /* @__PURE__ */ jsxRuntimeExports.jsx(
451
+ InspectorTab,
452
+ {
453
+ showScreenshot: false,
454
+ sdkLanguage,
455
+ setIsInspecting,
456
+ highlightedLocator,
457
+ setHighlightedLocator
458
+ }
459
+ )
460
+ };
461
+ const sourceTab = {
462
+ id: "source",
463
+ title: "Source",
464
+ render: () => /* @__PURE__ */ jsxRuntimeExports.jsx(
465
+ SourceTab,
466
+ {
467
+ sources: sourceModel.current,
468
+ stackFrameLocation: "right",
469
+ fallbackLocation: sourceLocation
470
+ }
471
+ )
472
+ };
473
+ const consoleTab = {
474
+ id: "console",
475
+ title: "Console",
476
+ count: consoleModel.entries.length,
477
+ render: () => /* @__PURE__ */ jsxRuntimeExports.jsx(ConsoleTab, { boundaries, consoleModel })
478
+ };
479
+ const networkTab = {
480
+ id: "network",
481
+ title: "Network",
482
+ count: networkModel.resources.length,
483
+ render: () => /* @__PURE__ */ jsxRuntimeExports.jsx(NetworkTab, { boundaries, networkModel })
484
+ };
485
+ const tabs = [
486
+ sourceTab,
487
+ inspectorTab,
488
+ consoleTab,
489
+ networkTab
490
+ ];
491
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
492
+ TabbedPane,
493
+ {
494
+ tabs,
495
+ selectedTab: selectedPropertiesTab,
496
+ setSelectedTab: setSelectedPropertiesTab
497
+ }
498
+ );
499
+ };
500
+ const TraceView = ({
501
+ sdkLanguage,
502
+ callId,
503
+ isInspecting,
504
+ setIsInspecting,
505
+ highlightedLocator,
506
+ setHighlightedLocator
507
+ }) => {
508
+ const model = reactExports.useContext(ModelContext);
509
+ const action = reactExports.useMemo(() => {
510
+ return model == null ? void 0 : model.actions.find((a) => a.callId === callId);
511
+ }, [model, callId]);
512
+ const snapshot = reactExports.useMemo(() => {
513
+ const snapshot2 = collectSnapshots(action);
514
+ return snapshot2.action || snapshot2.after || snapshot2.before;
515
+ }, [action]);
516
+ const snapshotUrls = reactExports.useMemo(() => {
517
+ return snapshot ? extendSnapshot(snapshot) : void 0;
518
+ }, [snapshot]);
519
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
520
+ SnapshotView,
521
+ {
522
+ sdkLanguage,
523
+ testIdAttributeName: "data-testid",
524
+ isInspecting,
525
+ setIsInspecting,
526
+ highlightedLocator,
527
+ setHighlightedLocator,
528
+ snapshotUrls
529
+ }
530
+ );
531
+ };
532
+ (async () => {
533
+ applyTheme();
534
+ if (window.location.protocol !== "file:") {
535
+ if (!navigator.serviceWorker)
536
+ throw new Error(`Service workers are not supported.
537
+ Make sure to serve the Recorder (${window.location}) via HTTPS or localhost.`);
538
+ navigator.serviceWorker.register("sw.bundle.js");
539
+ if (!navigator.serviceWorker.controller) {
540
+ await new Promise((f) => {
541
+ navigator.serviceWorker.oncontrollerchange = () => f();
542
+ });
543
+ }
544
+ setInterval(function() {
545
+ fetch("ping");
546
+ }, 1e4);
547
+ }
548
+ createRoot(document.querySelector("#root")).render(/* @__PURE__ */ jsxRuntimeExports.jsx(RecorderView, {}));
549
+ })();
550
+ //# sourceMappingURL=recorder.7Wl6HrQl.js.map
File without changes