rebrowser-playwright-core 1.47.100 → 1.48.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/README.md +1 -1
  2. package/browsers.json +14 -10
  3. package/lib/cli/program.js +26 -14
  4. package/lib/client/api.js +6 -0
  5. package/lib/client/browserContext.js +20 -2
  6. package/lib/client/channelOwner.js +5 -1
  7. package/lib/client/connection.js +3 -0
  8. package/lib/client/fetch.js +16 -21
  9. package/lib/client/jsHandle.js +0 -8
  10. package/lib/client/localUtils.js +1 -0
  11. package/lib/client/network.js +175 -17
  12. package/lib/client/page.js +21 -0
  13. package/lib/client/playwright.js +6 -3
  14. package/lib/client/tracing.js +16 -20
  15. package/lib/generated/consoleApiSource.js +1 -1
  16. package/lib/generated/injectedScriptSource.js +1 -1
  17. package/lib/generated/pollingRecorderSource.js +7 -0
  18. package/lib/generated/webSocketMockSource.js +7 -0
  19. package/lib/protocol/validator.js +80 -14
  20. package/lib/server/bidi/bidiBrowser.js +23 -8
  21. package/lib/server/bidi/bidiChromium.js +124 -0
  22. package/lib/server/bidi/bidiConnection.js +1 -1
  23. package/lib/server/bidi/bidiExecutionContext.js +0 -3
  24. package/lib/server/bidi/bidiFirefox.js +15 -21
  25. package/lib/server/bidi/bidiInput.js +16 -32
  26. package/lib/server/bidi/bidiNetworkManager.js +39 -5
  27. package/lib/server/bidi/bidiOverCdp.js +103 -0
  28. package/lib/server/bidi/bidiPage.js +98 -25
  29. package/lib/server/bidi/bidiPdf.js +140 -0
  30. package/lib/server/bidi/third_party/firefoxPrefs.js +221 -0
  31. package/lib/server/browser.js +13 -2
  32. package/lib/server/browserContext.js +6 -23
  33. package/lib/server/browserType.js +39 -11
  34. package/lib/server/chromium/chromium.js +3 -15
  35. package/lib/server/chromium/chromiumSwitches.js +3 -1
  36. package/lib/server/chromium/crBrowser.js +4 -3
  37. package/lib/server/chromium/crExecutionContext.js +0 -7
  38. package/lib/server/chromium/crPage.js +16 -6
  39. package/lib/server/chromium/videoRecorder.js +1 -1
  40. package/lib/server/codegen/csharp.js +1 -1
  41. package/lib/server/codegen/java.js +1 -1
  42. package/lib/server/codegen/javascript.js +1 -1
  43. package/lib/server/codegen/language.js +14 -2
  44. package/lib/server/codegen/python.js +1 -1
  45. package/lib/server/cookieStore.js +73 -0
  46. package/lib/server/debugController.js +2 -2
  47. package/lib/server/deviceDescriptorsSource.json +50 -50
  48. package/lib/server/dialog.js +1 -0
  49. package/lib/server/dispatchers/browserContextDispatcher.js +19 -2
  50. package/lib/server/dispatchers/jsHandleDispatcher.js +0 -5
  51. package/lib/server/dispatchers/pageDispatcher.js +9 -0
  52. package/lib/server/dispatchers/playwrightDispatcher.js +2 -1
  53. package/lib/server/dispatchers/webSocketRouteDispatcher.js +189 -0
  54. package/lib/server/download.js +9 -2
  55. package/lib/server/fetch.js +90 -94
  56. package/lib/server/firefox/ffBrowser.js +6 -4
  57. package/lib/server/firefox/ffExecutionContext.js +0 -3
  58. package/lib/server/firefox/ffPage.js +6 -3
  59. package/lib/server/firefox/firefox.js +2 -13
  60. package/lib/server/frameSelectors.js +1 -1
  61. package/lib/server/frames.js +158 -27
  62. package/lib/server/har/harTracer.js +11 -0
  63. package/lib/server/input.js +0 -1
  64. package/lib/server/javascript.js +0 -7
  65. package/lib/server/page.js +5 -1
  66. package/lib/server/playwright.js +5 -2
  67. package/lib/server/recorder/contextRecorder.js +33 -50
  68. package/lib/server/recorder/recorderApp.js +16 -10
  69. package/lib/server/recorder/recorderCollection.js +68 -79
  70. package/lib/server/recorder/recorderInTraceViewer.js +144 -0
  71. package/lib/server/recorder/recorderRunner.js +75 -97
  72. package/lib/server/recorder/recorderUtils.js +47 -6
  73. package/lib/server/recorder.js +30 -25
  74. package/lib/server/registry/index.js +85 -4
  75. package/lib/server/socksClientCertificatesInterceptor.js +15 -3
  76. package/lib/server/trace/recorder/snapshotter.js +1 -0
  77. package/lib/server/trace/recorder/snapshotterInjected.js +2 -2
  78. package/lib/server/trace/recorder/tracing.js +58 -2
  79. package/lib/server/trace/test/inMemorySnapshotter.js +1 -1
  80. package/lib/server/trace/viewer/traceViewer.js +2 -5
  81. package/lib/server/webkit/webkit.js +1 -1
  82. package/lib/server/webkit/wkBrowser.js +6 -5
  83. package/lib/server/webkit/wkExecutionContext.js +0 -3
  84. package/lib/server/webkit/wkPage.js +7 -4
  85. package/lib/utils/happy-eyeballs.js +13 -0
  86. package/lib/utils/hostPlatform.js +2 -2
  87. package/lib/utils/httpServer.js +1 -0
  88. package/lib/utils/isomorphic/locatorGenerators.js +9 -18
  89. package/lib/utils/isomorphic/locatorParser.js +2 -2
  90. package/lib/utils/isomorphic/recorderUtils.js +195 -0
  91. package/lib/vite/htmlReport/index.html +12 -12
  92. package/lib/vite/recorder/assets/{codeMirrorModule-aW6Vz3gf.js → codeMirrorModule-baozm8ur.js} +1 -1
  93. package/lib/vite/recorder/assets/{index-DCpXOVIh.js → index-2ElAIWFB.js} +10 -15
  94. package/lib/vite/recorder/assets/{index-B-MT5gKo.css → index-BW-aOBcL.css} +1 -1
  95. package/lib/vite/recorder/index.html +2 -2
  96. package/lib/vite/traceViewer/assets/{codeMirrorModule-eFKCUIu2.js → codeMirrorModule-Bh1rfd2w.js} +1 -1
  97. package/lib/vite/traceViewer/assets/inspectorTab-7GHnKvSD.js +64 -0
  98. package/lib/vite/traceViewer/assets/workbench-DPQnTHYP.js +9 -0
  99. package/lib/vite/traceViewer/embedded.BlHoW5LY.js +2 -0
  100. package/lib/vite/traceViewer/embedded.html +5 -3
  101. package/lib/vite/traceViewer/index.DaWVfou1.js +2 -0
  102. package/lib/vite/traceViewer/index.html +5 -3
  103. package/lib/vite/traceViewer/inspectorTab.DLjBDrQR.css +1 -0
  104. package/lib/vite/traceViewer/recorder.B_SY1GJM.css +0 -0
  105. package/lib/vite/traceViewer/recorder.C4zxcvd2.js +2 -0
  106. package/lib/vite/traceViewer/recorder.html +17 -0
  107. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  108. package/lib/vite/traceViewer/{uiMode.D3cNFP6u.css → uiMode.CAYqod-m.css} +1 -1
  109. package/lib/vite/traceViewer/uiMode.html +6 -4
  110. package/lib/vite/traceViewer/uiMode.mTXWniJb.js +5 -0
  111. package/lib/vite/traceViewer/workbench.D3JVcA9K.css +1 -0
  112. package/package.json +1 -1
  113. package/types/protocol.d.ts +79 -8
  114. package/types/types.d.ts +2037 -949
  115. package/lib/generated/recorderSource.js +0 -7
  116. package/lib/vite/traceViewer/assets/workbench-D0cirtfA.js +0 -72
  117. package/lib/vite/traceViewer/embedded.BkuvsLJp.js +0 -2
  118. package/lib/vite/traceViewer/index.C968kAiC.js +0 -2
  119. package/lib/vite/traceViewer/uiMode.BkFnr4V0.js +0 -10
  120. package/lib/vite/traceViewer/workbench.DjbIuxix.css +0 -1
  121. /package/lib/server/recorder/{recorderActions.js → recorderFrontend.js} +0 -0
@@ -5,6 +5,11 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.RecorderCollection = void 0;
7
7
  var _events = require("events");
8
+ var _time = require("../../utils/time");
9
+ var _recorderUtils = require("./recorderUtils");
10
+ var _errors = require("../errors");
11
+ var _recorderRunner = require("./recorderRunner");
12
+ var _debug = require("../../utils/debug");
8
13
  /**
9
14
  * Copyright (c) Microsoft Corporation.
10
15
  *
@@ -22,106 +27,90 @@ var _events = require("events");
22
27
  */
23
28
 
24
29
  class RecorderCollection extends _events.EventEmitter {
25
- constructor(enabled) {
30
+ constructor(pageAliases) {
26
31
  super();
27
- this._currentAction = null;
28
- this._lastAction = null;
29
32
  this._actions = [];
30
- this._enabled = void 0;
31
- this._enabled = enabled;
32
- this.restart();
33
+ this._enabled = false;
34
+ this._pageAliases = void 0;
35
+ this._pageAliases = pageAliases;
33
36
  }
34
37
  restart() {
35
- this._currentAction = null;
36
- this._lastAction = null;
37
38
  this._actions = [];
38
- this.emit('change');
39
- }
40
- actions() {
41
- return this._actions;
39
+ this._fireChange();
42
40
  }
43
41
  setEnabled(enabled) {
44
42
  this._enabled = enabled;
45
43
  }
46
- addAction(action) {
47
- if (!this._enabled) return;
48
- this.willPerformAction(action);
49
- this.didPerformAction(action);
50
- }
51
- willPerformAction(action) {
52
- if (!this._enabled) return;
53
- this._currentAction = action;
44
+ async performAction(actionInContext) {
45
+ await this._addAction(actionInContext, async callMetadata => {
46
+ await (0, _recorderRunner.performAction)(callMetadata, this._pageAliases, actionInContext);
47
+ });
54
48
  }
55
- performedActionFailed(action) {
56
- if (!this._enabled) return;
57
- if (this._currentAction === action) this._currentAction = null;
49
+ addRecordedAction(actionInContext) {
50
+ if (['openPage', 'closePage'].includes(actionInContext.action.name)) {
51
+ this._actions.push(actionInContext);
52
+ this._fireChange();
53
+ return;
54
+ }
55
+ this._addAction(actionInContext).catch(() => {});
58
56
  }
59
- didPerformAction(actionInContext) {
57
+ async _addAction(actionInContext, callback) {
60
58
  if (!this._enabled) return;
61
- const action = actionInContext.action;
62
- let eraseLastAction = false;
63
- if (this._lastAction && this._lastAction.frame.pageAlias === actionInContext.frame.pageAlias) {
64
- const lastAction = this._lastAction.action;
65
- // We augment last action based on the type.
66
- if (this._lastAction && action.name === 'fill' && lastAction.name === 'fill') {
67
- if (action.selector === lastAction.selector) eraseLastAction = true;
68
- }
69
- if (lastAction && action.name === 'click' && lastAction.name === 'click') {
70
- if (action.selector === lastAction.selector && action.clickCount > lastAction.clickCount) eraseLastAction = true;
71
- }
72
- if (lastAction && action.name === 'navigate' && lastAction.name === 'navigate') {
73
- if (action.url === lastAction.url) {
74
- // Already at a target URL.
75
- this._currentAction = null;
76
- return;
77
- }
78
- }
79
- // Check and uncheck erase click.
80
- if (lastAction && (action.name === 'check' || action.name === 'uncheck') && lastAction.name === 'click') {
81
- if (action.selector === lastAction.selector) eraseLastAction = true;
82
- }
59
+ if (actionInContext.action.name === 'openPage' || actionInContext.action.name === 'closePage') {
60
+ this._actions.push(actionInContext);
61
+ this._fireChange();
62
+ return;
83
63
  }
84
- this._lastAction = actionInContext;
85
- this._currentAction = null;
86
- if (eraseLastAction) this._actions.pop();
64
+ const {
65
+ callMetadata,
66
+ mainFrame
67
+ } = (0, _recorderUtils.callMetadataForAction)(this._pageAliases, actionInContext);
68
+ await mainFrame.instrumentation.onBeforeCall(mainFrame, callMetadata);
87
69
  this._actions.push(actionInContext);
88
- this.emit('change');
89
- }
90
- commitLastAction() {
91
- if (!this._enabled) return;
92
- const action = this._lastAction;
93
- if (action) action.committed = true;
70
+ this._fireChange();
71
+ const error = await (callback === null || callback === void 0 ? void 0 : callback(callMetadata).catch(e => e));
72
+ callMetadata.endTime = (0, _time.monotonicTime)();
73
+ actionInContext.endTime = callMetadata.endTime;
74
+ callMetadata.error = error ? (0, _errors.serializeError)(error) : undefined;
75
+ // Do not wait for onAfterCall so that performAction returned immediately after the action.
76
+ mainFrame.instrumentation.onAfterCall(mainFrame, callMetadata).then(() => {
77
+ this._fireChange();
78
+ }).catch(() => {});
94
79
  }
95
80
  signal(pageAlias, frame, signal) {
96
81
  if (!this._enabled) return;
97
-
98
- // Signal either arrives while action is being performed or shortly after.
99
- if (this._currentAction) {
100
- this._currentAction.action.signals.push(signal);
82
+ if (signal.name === 'navigation' && frame._page.mainFrame() === frame) {
83
+ const timestamp = (0, _time.monotonicTime)();
84
+ const lastAction = this._actions[this._actions.length - 1];
85
+ const signalThreshold = (0, _debug.isUnderTest)() ? 500 : 5000;
86
+ let generateGoto = false;
87
+ if (!lastAction) generateGoto = true;else if (lastAction.action.name !== 'click' && lastAction.action.name !== 'press') generateGoto = true;else if (timestamp - lastAction.startTime > signalThreshold) generateGoto = true;
88
+ if (generateGoto) {
89
+ this.addRecordedAction({
90
+ frame: {
91
+ pageAlias,
92
+ framePath: []
93
+ },
94
+ action: {
95
+ name: 'navigate',
96
+ url: frame.url(),
97
+ signals: []
98
+ },
99
+ startTime: timestamp,
100
+ endTime: timestamp
101
+ });
102
+ }
101
103
  return;
102
104
  }
103
- if (this._lastAction && (!this._lastAction.committed || signal.name !== 'navigation')) {
104
- const signals = this._lastAction.action.signals;
105
- if (signal.name === 'navigation' && signals.length && signals[signals.length - 1].name === 'download') return;
106
- if (signal.name === 'download' && signals.length && signals[signals.length - 1].name === 'navigation') signals.length = signals.length - 1;
107
- this._lastAction.action.signals.push(signal);
108
- this.emit('change');
105
+ if (this._actions.length) {
106
+ this._actions[this._actions.length - 1].action.signals.push(signal);
107
+ this._fireChange();
109
108
  return;
110
109
  }
111
- if (signal.name === 'navigation' && frame._page.mainFrame() === frame) {
112
- this.addAction({
113
- frame: {
114
- pageAlias,
115
- framePath: []
116
- },
117
- committed: true,
118
- action: {
119
- name: 'navigate',
120
- url: frame.url(),
121
- signals: []
122
- }
123
- });
124
- }
110
+ }
111
+ _fireChange() {
112
+ if (!this._enabled) return;
113
+ this.emit('change', (0, _recorderUtils.collapseActions)(this._actions));
125
114
  }
126
115
  }
127
116
  exports.RecorderCollection = RecorderCollection;
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.RecorderInTraceViewer = void 0;
7
+ var _path = _interopRequireDefault(require("path"));
8
+ var _events = require("events");
9
+ var _traceViewer = require("../trace/viewer/traceViewer");
10
+ var _manualPromise = require("../../utils/manualPromise");
11
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
+ /**
13
+ * Copyright (c) Microsoft Corporation.
14
+ *
15
+ * Licensed under the Apache License, Version 2.0 (the "License");
16
+ * you may not use this file except in compliance with the License.
17
+ * You may obtain a copy of the License at
18
+ *
19
+ * http://www.apache.org/licenses/LICENSE-2.0
20
+ *
21
+ * Unless required by applicable law or agreed to in writing, software
22
+ * distributed under the License is distributed on an "AS IS" BASIS,
23
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
+ * See the License for the specific language governing permissions and
25
+ * limitations under the License.
26
+ */
27
+
28
+ class RecorderInTraceViewer extends _events.EventEmitter {
29
+ static factory(context) {
30
+ return async recorder => {
31
+ const transport = new RecorderTransport();
32
+ const trace = _path.default.join(context._browser.options.tracesDir, 'trace');
33
+ const {
34
+ wsEndpointForTest,
35
+ tracePage,
36
+ traceServer
37
+ } = await openApp(trace, {
38
+ transport,
39
+ headless: !context._browser.options.headful
40
+ });
41
+ return new RecorderInTraceViewer(transport, tracePage, traceServer, wsEndpointForTest);
42
+ };
43
+ }
44
+ constructor(transport, tracePage, traceServer, wsEndpointForTest) {
45
+ super();
46
+ this.wsEndpointForTest = void 0;
47
+ this._transport = void 0;
48
+ this._tracePage = void 0;
49
+ this._traceServer = void 0;
50
+ this._transport = transport;
51
+ this._transport.eventSink.resolve(this);
52
+ this._tracePage = tracePage;
53
+ this._traceServer = traceServer;
54
+ this.wsEndpointForTest = wsEndpointForTest;
55
+ this._tracePage.once('close', () => {
56
+ this.close();
57
+ });
58
+ }
59
+ async close() {
60
+ await this._tracePage.context().close({
61
+ reason: 'Recorder window closed'
62
+ });
63
+ await this._traceServer.stop();
64
+ }
65
+ async setPaused(paused) {
66
+ this._transport.deliverEvent('setPaused', {
67
+ paused
68
+ });
69
+ }
70
+ async setMode(mode) {
71
+ this._transport.deliverEvent('setMode', {
72
+ mode
73
+ });
74
+ }
75
+ async setRunningFile(file) {
76
+ this._transport.deliverEvent('setRunningFile', {
77
+ file
78
+ });
79
+ }
80
+ async setSelector(selector, userGesture) {
81
+ this._transport.deliverEvent('setSelector', {
82
+ selector,
83
+ userGesture
84
+ });
85
+ }
86
+ async updateCallLogs(callLogs) {
87
+ this._transport.deliverEvent('updateCallLogs', {
88
+ callLogs
89
+ });
90
+ }
91
+ async setSources(sources) {
92
+ this._transport.deliverEvent('setSources', {
93
+ sources
94
+ });
95
+ if (process.env.PWTEST_CLI_IS_UNDER_TEST && sources.length) {
96
+ if (process._didSetSourcesForTest(sources[0].text)) this.close();
97
+ }
98
+ }
99
+ async setActions(actions, sources) {
100
+ this._transport.deliverEvent('setActions', {
101
+ actions,
102
+ sources
103
+ });
104
+ }
105
+ }
106
+ exports.RecorderInTraceViewer = RecorderInTraceViewer;
107
+ async function openApp(trace, options) {
108
+ const traceServer = await (0, _traceViewer.startTraceViewerServer)(options);
109
+ await (0, _traceViewer.installRootRedirect)(traceServer, [trace], {
110
+ ...options,
111
+ webApp: 'recorder.html'
112
+ });
113
+ const page = await (0, _traceViewer.openTraceViewerApp)(traceServer.urlPrefix('precise'), 'chromium', options);
114
+ return {
115
+ wsEndpointForTest: page.context()._browser.options.wsEndpoint,
116
+ tracePage: page,
117
+ traceServer
118
+ };
119
+ }
120
+ class RecorderTransport {
121
+ constructor() {
122
+ this._connected = new _manualPromise.ManualPromise();
123
+ this.eventSink = new _manualPromise.ManualPromise();
124
+ this.sendEvent = void 0;
125
+ this.close = void 0;
126
+ }
127
+ onconnect() {
128
+ this._connected.resolve();
129
+ }
130
+ async dispatch(method, params) {
131
+ const eventSink = await this.eventSink;
132
+ eventSink.emit('event', {
133
+ event: method,
134
+ params
135
+ });
136
+ }
137
+ onclose() {}
138
+ deliverEvent(method, params) {
139
+ this._connected.then(() => {
140
+ var _this$sendEvent;
141
+ return (_this$sendEvent = this.sendEvent) === null || _this$sendEvent === void 0 ? void 0 : _this$sendEvent.call(this, method, params);
142
+ });
143
+ }
144
+ }
@@ -4,9 +4,11 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.performAction = performAction;
7
+ exports.toClickOptions = toClickOptions;
7
8
  var _utils = require("../../utils");
8
9
  var _language = require("../codegen/language");
9
10
  var _recorderUtils = require("./recorderUtils");
11
+ var _recorderUtils2 = require("../../utils/isomorphic/recorderUtils");
10
12
  /**
11
13
  * Copyright (c) Microsoft Corporation.
12
14
  *
@@ -23,125 +25,93 @@ var _recorderUtils = require("./recorderUtils");
23
25
  * limitations under the License.
24
26
  */
25
27
 
26
- async function innerPerformAction(mainFrame, action, params, cb) {
27
- const callMetadata = {
28
- id: `call@${(0, _utils.createGuid)()}`,
29
- apiName: 'frame.' + action,
30
- objectId: mainFrame.guid,
31
- pageId: mainFrame._page.guid,
32
- frameId: mainFrame.guid,
33
- startTime: (0, _utils.monotonicTime)(),
34
- endTime: 0,
35
- type: 'Frame',
36
- method: action,
37
- params,
38
- log: []
39
- };
40
- try {
41
- await mainFrame.instrumentation.onBeforeCall(mainFrame, callMetadata);
42
- await cb(callMetadata);
43
- } catch (e) {
44
- callMetadata.endTime = (0, _utils.monotonicTime)();
45
- await mainFrame.instrumentation.onAfterCall(mainFrame, callMetadata);
46
- return false;
47
- }
48
- callMetadata.endTime = (0, _utils.monotonicTime)();
49
- await mainFrame.instrumentation.onAfterCall(mainFrame, callMetadata);
50
- return true;
51
- }
52
- async function performAction(pageAliases, actionInContext) {
53
- var _find;
54
- const pageAlias = actionInContext.frame.pageAlias;
55
- const page = (_find = [...pageAliases.entries()].find(([, alias]) => pageAlias === alias)) === null || _find === void 0 ? void 0 : _find[0];
56
- if (!page) throw new Error('Internal error: page not found');
57
- const mainFrame = page.mainFrame();
28
+ async function performAction(callMetadata, pageAliases, actionInContext) {
29
+ const mainFrame = (0, _recorderUtils.mainFrameForAction)(pageAliases, actionInContext);
58
30
  const {
59
31
  action
60
32
  } = actionInContext;
61
33
  const kActionTimeout = 5000;
62
- if (action.name === 'navigate') return await innerPerformAction(mainFrame, 'goto', {
63
- url: action.url
64
- }, callMetadata => mainFrame.goto(callMetadata, action.url, {
65
- timeout: kActionTimeout
66
- }));
34
+ if (action.name === 'navigate') {
35
+ await mainFrame.goto(callMetadata, action.url, {
36
+ timeout: kActionTimeout
37
+ });
38
+ return;
39
+ }
67
40
  if (action.name === 'openPage') throw Error('Not reached');
68
- if (action.name === 'closePage') return await innerPerformAction(mainFrame, 'close', {}, callMetadata => mainFrame._page.close(callMetadata));
69
- const selector = (0, _recorderUtils.buildFullSelector)(actionInContext.frame.framePath, action.selector);
41
+ if (action.name === 'closePage') {
42
+ await mainFrame._page.close(callMetadata);
43
+ return;
44
+ }
45
+ const selector = (0, _recorderUtils2.buildFullSelector)(actionInContext.frame.framePath, action.selector);
70
46
  if (action.name === 'click') {
71
- const options = (0, _language.toClickOptions)(action);
72
- return await innerPerformAction(mainFrame, 'click', {
73
- selector
74
- }, callMetadata => mainFrame.click(callMetadata, selector, {
47
+ const options = toClickOptions(action);
48
+ await mainFrame.click(callMetadata, selector, {
75
49
  ...options,
76
50
  timeout: kActionTimeout,
77
51
  strict: true
78
- }));
52
+ });
53
+ return;
79
54
  }
80
55
  if (action.name === 'press') {
81
56
  const modifiers = (0, _language.toKeyboardModifiers)(action.modifiers);
82
57
  const shortcut = [...modifiers, action.key].join('+');
83
- return await innerPerformAction(mainFrame, 'press', {
58
+ await mainFrame.press(callMetadata, selector, shortcut, {
59
+ timeout: kActionTimeout,
60
+ strict: true
61
+ });
62
+ return;
63
+ }
64
+ if (action.name === 'fill') {
65
+ await mainFrame.fill(callMetadata, selector, action.text, {
66
+ timeout: kActionTimeout,
67
+ strict: true
68
+ });
69
+ return;
70
+ }
71
+ if (action.name === 'setInputFiles') {
72
+ await mainFrame.setInputFiles(callMetadata, selector, {
84
73
  selector,
85
- key: shortcut
86
- }, callMetadata => mainFrame.press(callMetadata, selector, shortcut, {
74
+ payloads: [],
87
75
  timeout: kActionTimeout,
88
76
  strict: true
89
- }));
77
+ });
78
+ return;
79
+ }
80
+ if (action.name === 'check') {
81
+ await mainFrame.check(callMetadata, selector, {
82
+ timeout: kActionTimeout,
83
+ strict: true
84
+ });
85
+ return;
86
+ }
87
+ if (action.name === 'uncheck') {
88
+ await mainFrame.uncheck(callMetadata, selector, {
89
+ timeout: kActionTimeout,
90
+ strict: true
91
+ });
92
+ return;
90
93
  }
91
- if (action.name === 'fill') return await innerPerformAction(mainFrame, 'fill', {
92
- selector,
93
- text: action.text
94
- }, callMetadata => mainFrame.fill(callMetadata, selector, action.text, {
95
- timeout: kActionTimeout,
96
- strict: true
97
- }));
98
- if (action.name === 'setInputFiles') return await innerPerformAction(mainFrame, 'setInputFiles', {
99
- selector,
100
- files: action.files
101
- }, callMetadata => mainFrame.setInputFiles(callMetadata, selector, {
102
- selector,
103
- payloads: [],
104
- timeout: kActionTimeout,
105
- strict: true
106
- }));
107
- if (action.name === 'check') return await innerPerformAction(mainFrame, 'check', {
108
- selector
109
- }, callMetadata => mainFrame.check(callMetadata, selector, {
110
- timeout: kActionTimeout,
111
- strict: true
112
- }));
113
- if (action.name === 'uncheck') return await innerPerformAction(mainFrame, 'uncheck', {
114
- selector
115
- }, callMetadata => mainFrame.uncheck(callMetadata, selector, {
116
- timeout: kActionTimeout,
117
- strict: true
118
- }));
119
94
  if (action.name === 'select') {
120
95
  const values = action.options.map(value => ({
121
96
  value
122
97
  }));
123
- return await innerPerformAction(mainFrame, 'selectOption', {
124
- selector,
125
- values
126
- }, callMetadata => mainFrame.selectOption(callMetadata, selector, [], values, {
98
+ await mainFrame.selectOption(callMetadata, selector, [], values, {
127
99
  timeout: kActionTimeout,
128
100
  strict: true
129
- }));
101
+ });
102
+ return;
130
103
  }
131
104
  if (action.name === 'assertChecked') {
132
- return await innerPerformAction(mainFrame, 'expect', {
133
- selector
134
- }, callMetadata => mainFrame.expect(callMetadata, selector, {
105
+ await mainFrame.expect(callMetadata, selector, {
135
106
  selector,
136
107
  expression: 'to.be.checked',
137
108
  isNot: !action.checked,
138
109
  timeout: kActionTimeout
139
- }));
110
+ });
111
+ return;
140
112
  }
141
113
  if (action.name === 'assertText') {
142
- return await innerPerformAction(mainFrame, 'expect', {
143
- selector
144
- }, callMetadata => mainFrame.expect(callMetadata, selector, {
114
+ await mainFrame.expect(callMetadata, selector, {
145
115
  selector,
146
116
  expression: 'to.have.text',
147
117
  expectedText: (0, _utils.serializeExpectedTextValues)([action.text], {
@@ -150,28 +120,36 @@ async function performAction(pageAliases, actionInContext) {
150
120
  }),
151
121
  isNot: false,
152
122
  timeout: kActionTimeout
153
- }));
123
+ });
124
+ return;
154
125
  }
155
126
  if (action.name === 'assertValue') {
156
- return await innerPerformAction(mainFrame, 'expect', {
157
- selector
158
- }, callMetadata => mainFrame.expect(callMetadata, selector, {
127
+ await mainFrame.expect(callMetadata, selector, {
159
128
  selector,
160
129
  expression: 'to.have.value',
161
130
  expectedValue: action.value,
162
131
  isNot: false,
163
132
  timeout: kActionTimeout
164
- }));
133
+ });
134
+ return;
165
135
  }
166
136
  if (action.name === 'assertVisible') {
167
- return await innerPerformAction(mainFrame, 'expect', {
168
- selector
169
- }, callMetadata => mainFrame.expect(callMetadata, selector, {
137
+ await mainFrame.expect(callMetadata, selector, {
170
138
  selector,
171
139
  expression: 'to.be.visible',
172
140
  isNot: false,
173
141
  timeout: kActionTimeout
174
- }));
142
+ });
143
+ return;
175
144
  }
176
145
  throw new Error('Internal error: unexpected action ' + action.name);
146
+ }
147
+ function toClickOptions(action) {
148
+ const modifiers = (0, _language.toKeyboardModifiers)(action.modifiers);
149
+ const options = {};
150
+ if (action.button !== 'left') options.button = action.button;
151
+ if (modifiers.length) options.modifiers = modifiers;
152
+ if (action.clickCount > 1) options.clickCount = action.clickCount;
153
+ if (action.position) options.position = action.position;
154
+ return options;
177
155
  }
@@ -3,10 +3,13 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.buildFullSelector = buildFullSelector;
6
+ exports.callMetadataForAction = callMetadataForAction;
7
+ exports.collapseActions = collapseActions;
7
8
  exports.frameForAction = frameForAction;
8
9
  exports.mainFrameForAction = mainFrameForAction;
9
10
  exports.metadataToCallLog = metadataToCallLog;
11
+ var _utils = require("../../utils");
12
+ var _recorderUtils = require("../../utils/isomorphic/recorderUtils");
10
13
  /**
11
14
  * Copyright (c) Microsoft Corporation.
12
15
  *
@@ -49,14 +52,11 @@ function metadataToCallLog(metadata, status) {
49
52
  };
50
53
  return callLog;
51
54
  }
52
- function buildFullSelector(framePath, selector) {
53
- return [...framePath, selector].join(' >> internal:control=enter-frame >> ');
54
- }
55
55
  function mainFrameForAction(pageAliases, actionInContext) {
56
56
  var _find;
57
57
  const pageAlias = actionInContext.frame.pageAlias;
58
58
  const page = (_find = [...pageAliases.entries()].find(([, alias]) => pageAlias === alias)) === null || _find === void 0 ? void 0 : _find[0];
59
- if (!page) throw new Error('Internal error: page not found');
59
+ if (!page) throw new Error(`Internal error: page ${pageAlias} not found in [${[...pageAliases.values()]}]`);
60
60
  return page.mainFrame();
61
61
  }
62
62
  async function frameForAction(pageAliases, actionInContext, action) {
@@ -64,8 +64,49 @@ async function frameForAction(pageAliases, actionInContext, action) {
64
64
  const pageAlias = actionInContext.frame.pageAlias;
65
65
  const page = (_find2 = [...pageAliases.entries()].find(([, alias]) => pageAlias === alias)) === null || _find2 === void 0 ? void 0 : _find2[0];
66
66
  if (!page) throw new Error('Internal error: page not found');
67
- const fullSelector = buildFullSelector(actionInContext.frame.framePath, action.selector);
67
+ const fullSelector = (0, _recorderUtils.buildFullSelector)(actionInContext.frame.framePath, action.selector);
68
68
  const result = await page.mainFrame().selectors.resolveFrameForSelector(fullSelector);
69
69
  if (!result) throw new Error('Internal error: frame not found');
70
70
  return result.frame;
71
+ }
72
+ function callMetadataForAction(pageAliases, actionInContext) {
73
+ const mainFrame = mainFrameForAction(pageAliases, actionInContext);
74
+ const {
75
+ method,
76
+ params
77
+ } = (0, _recorderUtils.traceParamsForAction)(actionInContext);
78
+ const callMetadata = {
79
+ id: `call@${(0, _utils.createGuid)()}`,
80
+ apiName: 'page.' + method,
81
+ objectId: mainFrame.guid,
82
+ pageId: mainFrame._page.guid,
83
+ frameId: mainFrame.guid,
84
+ startTime: actionInContext.startTime,
85
+ endTime: 0,
86
+ type: 'Frame',
87
+ method,
88
+ params,
89
+ log: []
90
+ };
91
+ return {
92
+ callMetadata,
93
+ mainFrame
94
+ };
95
+ }
96
+ function collapseActions(actions) {
97
+ const result = [];
98
+ for (const action of actions) {
99
+ const lastAction = result[result.length - 1];
100
+ const isSameAction = lastAction && lastAction.action.name === action.action.name && lastAction.frame.pageAlias === action.frame.pageAlias && lastAction.frame.framePath.join('|') === action.frame.framePath.join('|');
101
+ const isSameSelector = lastAction && 'selector' in lastAction.action && 'selector' in action.action && action.action.selector === lastAction.action.selector;
102
+ const shouldMerge = isSameAction && (action.action.name === 'navigate' || action.action.name === 'fill' && isSameSelector);
103
+ if (!shouldMerge) {
104
+ result.push(action);
105
+ continue;
106
+ }
107
+ const startTime = result[result.length - 1].startTime;
108
+ result[result.length - 1] = action;
109
+ result[result.length - 1].startTime = startTime;
110
+ }
111
+ return result;
71
112
  }