rebrowser-playwright-core 1.47.100 → 1.49.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.
- package/README.md +1 -1
- package/ThirdPartyNotices.txt +70 -384
- package/bin/reinstall_chrome_beta_linux.sh +10 -8
- package/bin/reinstall_chrome_stable_linux.sh +10 -8
- package/bin/reinstall_msedge_beta_linux.sh +11 -9
- package/bin/reinstall_msedge_dev_linux.sh +11 -9
- package/bin/reinstall_msedge_stable_linux.sh +11 -9
- package/browsers.json +24 -12
- package/lib/cli/program.js +49 -19
- package/lib/client/api.js +6 -0
- package/lib/client/browserContext.js +20 -2
- package/lib/client/channelOwner.js +6 -2
- package/lib/client/connection.js +3 -0
- package/lib/client/fetch.js +16 -21
- package/lib/client/jsHandle.js +0 -8
- package/lib/client/localUtils.js +1 -0
- package/lib/client/locator.js +7 -0
- package/lib/client/network.js +180 -17
- package/lib/client/page.js +25 -2
- package/lib/client/playwright.js +6 -3
- package/lib/client/tracing.js +29 -20
- package/lib/client/waiter.js +15 -11
- package/lib/generated/consoleApiSource.js +1 -1
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/pollingRecorderSource.js +7 -0
- package/lib/generated/webSocketMockSource.js +7 -0
- package/lib/protocol/validator.js +103 -17
- package/lib/server/ariaSnapshot.js +33 -0
- package/lib/server/bidi/bidiBrowser.js +23 -8
- package/lib/server/bidi/bidiChromium.js +124 -0
- package/lib/server/bidi/bidiConnection.js +1 -3
- package/lib/server/bidi/bidiExecutionContext.js +0 -6
- package/lib/server/bidi/bidiFirefox.js +15 -21
- package/lib/server/bidi/bidiInput.js +16 -32
- package/lib/server/bidi/bidiNetworkManager.js +39 -5
- package/lib/server/bidi/bidiOverCdp.js +103 -0
- package/lib/server/bidi/bidiPage.js +98 -25
- package/lib/server/bidi/bidiPdf.js +140 -0
- package/lib/server/bidi/third_party/firefoxPrefs.js +221 -0
- package/lib/server/browser.js +13 -2
- package/lib/server/browserContext.js +6 -23
- package/lib/server/browserType.js +43 -12
- package/lib/server/chromium/chromium.js +9 -17
- package/lib/server/chromium/chromiumSwitches.js +3 -1
- package/lib/server/chromium/crBrowser.js +4 -3
- package/lib/server/chromium/crConnection.js +153 -0
- package/lib/server/chromium/crExecutionContext.js +0 -20
- package/lib/server/chromium/crPage.js +13 -7
- package/lib/server/chromium/videoRecorder.js +1 -1
- package/lib/server/codegen/csharp.js +12 -17
- package/lib/server/codegen/java.js +5 -8
- package/lib/server/codegen/javascript.js +29 -7
- package/lib/server/codegen/language.js +14 -2
- package/lib/server/codegen/python.js +13 -17
- package/lib/server/cookieStore.js +73 -0
- package/lib/server/debugController.js +10 -7
- package/lib/server/deviceDescriptorsSource.json +127 -127
- package/lib/server/dialog.js +1 -0
- package/lib/server/dispatchers/androidDispatcher.js +13 -2
- package/lib/server/dispatchers/browserContextDispatcher.js +19 -2
- package/lib/server/dispatchers/debugControllerDispatcher.js +1 -1
- package/lib/server/dispatchers/dispatcher.js +1 -1
- package/lib/server/dispatchers/frameDispatcher.js +8 -1
- package/lib/server/dispatchers/jsHandleDispatcher.js +0 -5
- package/lib/server/dispatchers/pageDispatcher.js +9 -0
- package/lib/server/dispatchers/playwrightDispatcher.js +2 -1
- package/lib/server/dispatchers/tracingDispatcher.js +10 -0
- package/lib/server/dispatchers/webSocketRouteDispatcher.js +189 -0
- package/lib/server/dom.js +79 -36
- package/lib/server/download.js +9 -2
- package/lib/server/fetch.js +105 -96
- package/lib/server/firefox/ffBrowser.js +6 -4
- package/lib/server/firefox/ffExecutionContext.js +0 -15
- package/lib/server/firefox/ffNetworkManager.js +1 -1
- package/lib/server/firefox/ffPage.js +6 -3
- package/lib/server/firefox/firefox.js +2 -13
- package/lib/server/frameSelectors.js +1 -1
- package/lib/server/frames.js +68 -67
- package/lib/server/har/harTracer.js +11 -0
- package/lib/server/index.js +0 -6
- package/lib/server/input.js +0 -1
- package/lib/server/javascript.js +0 -13
- package/lib/server/page.js +53 -9
- package/lib/server/playwright.js +5 -2
- package/lib/server/progress.js +0 -3
- package/lib/server/recorder/contextRecorder.js +33 -50
- package/lib/server/recorder/recorderApp.js +22 -25
- package/lib/server/recorder/recorderCollection.js +68 -79
- package/lib/server/recorder/recorderInTraceViewer.js +144 -0
- package/lib/server/recorder/recorderRunner.js +75 -97
- package/lib/server/recorder/recorderUtils.js +48 -6
- package/lib/server/recorder.js +87 -47
- package/lib/server/registry/index.js +154 -26
- package/lib/server/registry/nativeDeps.js +6 -3
- package/lib/server/socksClientCertificatesInterceptor.js +15 -3
- package/lib/server/trace/recorder/snapshotter.js +2 -12
- package/lib/server/trace/recorder/snapshotterInjected.js +21 -3
- package/lib/server/trace/recorder/tracing.js +127 -17
- package/lib/server/trace/test/inMemorySnapshotter.js +4 -4
- package/lib/server/trace/viewer/traceViewer.js +4 -6
- package/lib/server/webkit/webkit.js +1 -1
- package/lib/server/webkit/wkBrowser.js +8 -7
- package/lib/server/webkit/wkExecutionContext.js +0 -16
- package/lib/server/webkit/wkPage.js +11 -4
- package/lib/utils/comparators.js +12 -30
- package/lib/utils/crypto.js +1 -4
- package/lib/utils/happy-eyeballs.js +13 -0
- package/lib/utils/hostPlatform.js +8 -2
- package/lib/utils/httpServer.js +1 -0
- package/lib/utils/isomorphic/ariaSnapshot.js +267 -0
- package/lib/utils/isomorphic/locatorGenerators.js +30 -21
- package/lib/utils/isomorphic/locatorParser.js +2 -2
- package/lib/utils/isomorphic/recorderUtils.js +227 -0
- package/lib/utils/isomorphic/stringUtils.js +30 -0
- package/lib/utils/isomorphic/urlMatch.js +5 -1
- package/lib/utils/network.js +1 -1
- package/lib/utils/sequence.js +64 -0
- package/lib/utils/stackTrace.js +16 -3
- package/lib/utils/zones.js +32 -23
- package/lib/utilsBundle.js +4 -5
- package/lib/utilsBundleImpl/index.js +190 -33
- package/lib/vite/htmlReport/index.html +19 -16
- package/lib/vite/recorder/assets/codeMirrorModule-AFvV6hAs.js +24 -0
- package/lib/vite/recorder/assets/index-_cTWgVuJ.js +184 -0
- package/lib/vite/recorder/assets/{index-B-MT5gKo.css → index-iA1aAGZg.css} +1 -1
- package/lib/vite/recorder/index.html +2 -2
- package/lib/vite/traceViewer/assets/codeMirrorModule-KatbITLF.js +24 -0
- package/lib/vite/traceViewer/assets/inspectorTab-DdpLd2bb.js +68 -0
- package/lib/vite/traceViewer/assets/workbench-CdYbzWFD.js +9 -0
- package/lib/vite/traceViewer/embedded.6m3UZh7r.js +2 -0
- package/lib/vite/traceViewer/embedded.html +5 -3
- package/lib/vite/traceViewer/index.WUV-8boJ.js +2 -0
- package/lib/vite/traceViewer/index.html +24 -5
- package/lib/vite/traceViewer/inspectorTab.DEOUW62d.css +1 -0
- package/lib/vite/traceViewer/recorder.B_SY1GJM.css +0 -0
- package/lib/vite/traceViewer/recorder.OT2tVHgn.js +2 -0
- package/lib/vite/traceViewer/recorder.html +17 -0
- package/lib/vite/traceViewer/sw.bundle.js +3 -3
- package/lib/vite/traceViewer/uiMode.BZBTyvGn.js +5 -0
- package/lib/vite/traceViewer/uiMode.html +6 -4
- package/lib/vite/traceViewer/{uiMode.D3cNFP6u.css → uiMode.voC1ZiOQ.css} +1 -1
- package/lib/vite/traceViewer/workbench.C-zR9ysA.css +1 -0
- package/package.json +1 -1
- package/types/protocol.d.ts +135 -16
- package/types/types.d.ts +2149 -965
- package/lib/generated/recorderSource.js +0 -7
- package/lib/third_party/diff_match_patch.js +0 -2222
- package/lib/vite/recorder/assets/codeMirrorModule-aW6Vz3gf.js +0 -24
- package/lib/vite/recorder/assets/index-DCpXOVIh.js +0 -47
- package/lib/vite/traceViewer/assets/codeMirrorModule-eFKCUIu2.js +0 -24
- package/lib/vite/traceViewer/assets/workbench-D0cirtfA.js +0 -72
- package/lib/vite/traceViewer/embedded.BkuvsLJp.js +0 -2
- package/lib/vite/traceViewer/index.C968kAiC.js +0 -2
- package/lib/vite/traceViewer/uiMode.BkFnr4V0.js +0 -10
- package/lib/vite/traceViewer/workbench.DjbIuxix.css +0 -1
- /package/lib/server/recorder/{recorderActions.js → recorderFrontend.js} +0 -0
package/lib/server/recorder.js
CHANGED
|
@@ -12,6 +12,8 @@ var _browserContext = require("./browserContext");
|
|
|
12
12
|
var _debugger = require("./debugger");
|
|
13
13
|
var _contextRecorder = require("./recorder/contextRecorder");
|
|
14
14
|
var _recorderUtils = require("./recorder/recorderUtils");
|
|
15
|
+
var _recorderUtils2 = require("../utils/isomorphic/recorderUtils");
|
|
16
|
+
var _selectorParser = require("../utils/isomorphic/selectorParser");
|
|
15
17
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
16
18
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
17
19
|
/**
|
|
@@ -32,29 +34,32 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
32
34
|
|
|
33
35
|
const recorderSymbol = Symbol('recorderSymbol');
|
|
34
36
|
class Recorder {
|
|
35
|
-
static showInspector(context, recorderAppFactory) {
|
|
36
|
-
const params = {};
|
|
37
|
+
static async showInspector(context, params, recorderAppFactory) {
|
|
37
38
|
if ((0, _utils.isUnderTest)()) params.language = process.env.TEST_INSPECTOR_LANGUAGE;
|
|
38
|
-
Recorder.show(context, recorderAppFactory, params)
|
|
39
|
+
return await Recorder.show('actions', context, recorderAppFactory, params);
|
|
39
40
|
}
|
|
40
|
-
static
|
|
41
|
+
static showInspectorNoReply(context, recorderAppFactory) {
|
|
42
|
+
Recorder.showInspector(context, {}, recorderAppFactory).catch(() => {});
|
|
43
|
+
}
|
|
44
|
+
static show(codegenMode, context, recorderAppFactory, params) {
|
|
41
45
|
let recorderPromise = context[recorderSymbol];
|
|
42
46
|
if (!recorderPromise) {
|
|
43
|
-
recorderPromise = Recorder._create(context, recorderAppFactory, params);
|
|
47
|
+
recorderPromise = Recorder._create(codegenMode, context, recorderAppFactory, params);
|
|
44
48
|
context[recorderSymbol] = recorderPromise;
|
|
45
49
|
}
|
|
46
50
|
return recorderPromise;
|
|
47
51
|
}
|
|
48
|
-
static async _create(context, recorderAppFactory, params = {}) {
|
|
49
|
-
const recorder = new Recorder(context, params);
|
|
52
|
+
static async _create(codegenMode, context, recorderAppFactory, params = {}) {
|
|
53
|
+
const recorder = new Recorder(codegenMode, context, params);
|
|
50
54
|
const recorderApp = await recorderAppFactory(recorder);
|
|
51
55
|
await recorder._install(recorderApp);
|
|
52
56
|
return recorder;
|
|
53
57
|
}
|
|
54
|
-
constructor(context, params) {
|
|
58
|
+
constructor(codegenMode, context, params) {
|
|
59
|
+
this.handleSIGINT = void 0;
|
|
55
60
|
this._context = void 0;
|
|
56
61
|
this._mode = void 0;
|
|
57
|
-
this.
|
|
62
|
+
this._highlightedElement = {};
|
|
58
63
|
this._overlayState = {
|
|
59
64
|
offsetX: 0
|
|
60
65
|
};
|
|
@@ -67,7 +72,8 @@ class Recorder {
|
|
|
67
72
|
this._omitCallTracking = false;
|
|
68
73
|
this._currentLanguage = void 0;
|
|
69
74
|
this._mode = params.mode || 'none';
|
|
70
|
-
this.
|
|
75
|
+
this.handleSIGINT = params.handleSIGINT;
|
|
76
|
+
this._contextRecorder = new _contextRecorder.ContextRecorder(codegenMode, context, params, {});
|
|
71
77
|
this._context = context;
|
|
72
78
|
this._omitCallTracking = !!params.omitCallTracking;
|
|
73
79
|
this._debugger = context.debugger();
|
|
@@ -89,8 +95,9 @@ class Recorder {
|
|
|
89
95
|
this.setMode(data.params.mode);
|
|
90
96
|
return;
|
|
91
97
|
}
|
|
92
|
-
if (data.event === '
|
|
93
|
-
this.setHighlightedSelector(this._currentLanguage, data.params.selector);
|
|
98
|
+
if (data.event === 'highlightRequested') {
|
|
99
|
+
if (data.params.selector) this.setHighlightedSelector(this._currentLanguage, data.params.selector);
|
|
100
|
+
if (data.params.ariaTemplate) this.setHighlightedAriaTemplate(data.params.ariaTemplate);
|
|
94
101
|
return;
|
|
95
102
|
}
|
|
96
103
|
if (data.event === 'step') {
|
|
@@ -123,17 +130,17 @@ class Recorder {
|
|
|
123
130
|
(_this$_recorderApp = this._recorderApp) === null || _this$_recorderApp === void 0 || _this$_recorderApp.close().catch(() => {});
|
|
124
131
|
});
|
|
125
132
|
this._contextRecorder.on(_contextRecorder.ContextRecorder.Events.Change, data => {
|
|
126
|
-
var _this$_recorderApp2;
|
|
127
133
|
this._recorderSources = data.sources;
|
|
134
|
+
recorderApp.setActions(data.actions, data.sources);
|
|
135
|
+
recorderApp.setRunningFile(undefined);
|
|
128
136
|
this._pushAllSources();
|
|
129
|
-
(_this$_recorderApp2 = this._recorderApp) === null || _this$_recorderApp2 === void 0 || _this$_recorderApp2.setFileIfNeeded(data.primaryFileName);
|
|
130
137
|
});
|
|
131
|
-
await this._context.exposeBinding('__pw_recorderState', false, source => {
|
|
132
|
-
let actionSelector
|
|
138
|
+
await this._context.exposeBinding('__pw_recorderState', false, async source => {
|
|
139
|
+
let actionSelector;
|
|
133
140
|
let actionPoint;
|
|
134
141
|
const hasActiveScreenshotCommand = [...this._currentCallsMetadata.keys()].some(isScreenshotCommand);
|
|
135
142
|
if (!hasActiveScreenshotCommand) {
|
|
136
|
-
actionSelector = this.
|
|
143
|
+
actionSelector = await this._scopeHighlightedSelectorToFrame(source.frame);
|
|
137
144
|
for (const [metadata, sdkObject] of this._currentCallsMetadata) {
|
|
138
145
|
if (source.page === sdkObject.attribution.page) {
|
|
139
146
|
actionPoint = metadata.point || actionPoint;
|
|
@@ -145,18 +152,22 @@ class Recorder {
|
|
|
145
152
|
mode: this._mode,
|
|
146
153
|
actionPoint,
|
|
147
154
|
actionSelector,
|
|
155
|
+
ariaTemplate: this._highlightedElement.ariaTemplate,
|
|
148
156
|
language: this._currentLanguage,
|
|
149
157
|
testIdAttributeName: this._contextRecorder.testIdAttributeName(),
|
|
150
158
|
overlay: this._overlayState
|
|
151
159
|
};
|
|
152
160
|
return uiState;
|
|
153
161
|
});
|
|
154
|
-
await this._context.exposeBinding('
|
|
162
|
+
await this._context.exposeBinding('__pw_recorderElementPicked', false, async ({
|
|
155
163
|
frame
|
|
156
|
-
},
|
|
157
|
-
var _this$
|
|
164
|
+
}, elementInfo) => {
|
|
165
|
+
var _this$_recorderApp2;
|
|
158
166
|
const selectorChain = await (0, _contextRecorder.generateFrameSelector)(frame);
|
|
159
|
-
await ((_this$
|
|
167
|
+
await ((_this$_recorderApp2 = this._recorderApp) === null || _this$_recorderApp2 === void 0 ? void 0 : _this$_recorderApp2.elementPicked({
|
|
168
|
+
selector: (0, _recorderUtils2.buildFullSelector)(selectorChain, elementInfo.selector),
|
|
169
|
+
ariaSnapshot: elementInfo.ariaSnapshot
|
|
170
|
+
}, true));
|
|
160
171
|
});
|
|
161
172
|
await this._context.exposeBinding('__pw_recorderSetMode', false, async ({
|
|
162
173
|
frame
|
|
@@ -180,7 +191,7 @@ class Recorder {
|
|
|
180
191
|
this._context.recorderAppForTest = this._recorderApp;
|
|
181
192
|
}
|
|
182
193
|
_pausedStateChanged() {
|
|
183
|
-
var _this$
|
|
194
|
+
var _this$_recorderApp3;
|
|
184
195
|
// If we are called upon page.pause, we don't have metadatas, populate them.
|
|
185
196
|
for (const {
|
|
186
197
|
metadata,
|
|
@@ -188,18 +199,18 @@ class Recorder {
|
|
|
188
199
|
} of this._debugger.pausedDetails()) {
|
|
189
200
|
if (!this._currentCallsMetadata.has(metadata)) this.onBeforeCall(sdkObject, metadata);
|
|
190
201
|
}
|
|
191
|
-
(_this$
|
|
202
|
+
(_this$_recorderApp3 = this._recorderApp) === null || _this$_recorderApp3 === void 0 || _this$_recorderApp3.setPaused(this._debugger.isPaused());
|
|
192
203
|
this._updateUserSources();
|
|
193
204
|
this.updateCallLog([...this._currentCallsMetadata.keys()]);
|
|
194
205
|
}
|
|
195
206
|
setMode(mode) {
|
|
196
|
-
var _this$
|
|
207
|
+
var _this$_recorderApp4;
|
|
197
208
|
if (this._mode === mode) return;
|
|
198
|
-
this.
|
|
209
|
+
this._highlightedElement = {};
|
|
199
210
|
this._mode = mode;
|
|
200
|
-
(_this$
|
|
201
|
-
this._contextRecorder.setEnabled(this.
|
|
202
|
-
this._debugger.setMuted(this.
|
|
211
|
+
(_this$_recorderApp4 = this._recorderApp) === null || _this$_recorderApp4 === void 0 || _this$_recorderApp4.setMode(this._mode);
|
|
212
|
+
this._contextRecorder.setEnabled(this._isRecording());
|
|
213
|
+
this._debugger.setMuted(this._isRecording());
|
|
203
214
|
if (this._mode !== 'none' && this._mode !== 'standby' && this._context.pages().length === 1) this._context.pages()[0].bringToFront().catch(() => {});
|
|
204
215
|
this._refreshOverlay();
|
|
205
216
|
}
|
|
@@ -210,40 +221,66 @@ class Recorder {
|
|
|
210
221
|
return this._mode;
|
|
211
222
|
}
|
|
212
223
|
setHighlightedSelector(language, selector) {
|
|
213
|
-
this.
|
|
224
|
+
this._highlightedElement = {
|
|
225
|
+
selector: (0, _locatorParser.locatorOrSelectorAsSelector)(language, selector, this._context.selectors().testIdAttributeName())
|
|
226
|
+
};
|
|
227
|
+
this._refreshOverlay();
|
|
228
|
+
}
|
|
229
|
+
setHighlightedAriaTemplate(ariaTemplate) {
|
|
230
|
+
this._highlightedElement = {
|
|
231
|
+
ariaTemplate
|
|
232
|
+
};
|
|
214
233
|
this._refreshOverlay();
|
|
215
234
|
}
|
|
216
235
|
hideHighlightedSelector() {
|
|
217
|
-
this.
|
|
236
|
+
this._highlightedElement = {};
|
|
218
237
|
this._refreshOverlay();
|
|
219
238
|
}
|
|
239
|
+
async _scopeHighlightedSelectorToFrame(frame) {
|
|
240
|
+
if (!this._highlightedElement.selector) return;
|
|
241
|
+
try {
|
|
242
|
+
const mainFrame = frame._page.mainFrame();
|
|
243
|
+
const resolved = await mainFrame.selectors.resolveFrameForSelector(this._highlightedElement.selector);
|
|
244
|
+
// selector couldn't be found, don't highlight anything
|
|
245
|
+
if (!resolved) return '';
|
|
246
|
+
|
|
247
|
+
// selector points to no specific frame, highlight in all frames
|
|
248
|
+
if ((resolved === null || resolved === void 0 ? void 0 : resolved.frame) === mainFrame) return (0, _selectorParser.stringifySelector)(resolved.info.parsed);
|
|
249
|
+
|
|
250
|
+
// selector points to this frame, highlight it
|
|
251
|
+
if ((resolved === null || resolved === void 0 ? void 0 : resolved.frame) === frame) return (0, _selectorParser.stringifySelector)(resolved.info.parsed);
|
|
252
|
+
|
|
253
|
+
// selector points to a different frame, highlight nothing
|
|
254
|
+
return '';
|
|
255
|
+
} catch {
|
|
256
|
+
return '';
|
|
257
|
+
}
|
|
258
|
+
}
|
|
220
259
|
setOutput(codegenId, outputFile) {
|
|
221
260
|
this._contextRecorder.setOutput(codegenId, outputFile);
|
|
222
261
|
}
|
|
223
262
|
_refreshOverlay() {
|
|
224
|
-
for (const page of this._context.pages())
|
|
263
|
+
for (const page of this._context.pages()) {
|
|
264
|
+
for (const frame of page.frames()) frame.evaluateExpression('window.__pw_refreshOverlay()').catch(() => {});
|
|
265
|
+
}
|
|
225
266
|
}
|
|
226
267
|
async onBeforeCall(sdkObject, metadata) {
|
|
227
|
-
if (this._omitCallTracking || this.
|
|
268
|
+
if (this._omitCallTracking || this._isRecording()) return;
|
|
228
269
|
this._currentCallsMetadata.set(metadata, sdkObject);
|
|
229
270
|
this._updateUserSources();
|
|
230
271
|
this.updateCallLog([metadata]);
|
|
231
|
-
if (isScreenshotCommand(metadata)) {
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
var _this$_recorderApp6;
|
|
235
|
-
this._highlightedSelector = metadata.params.selector;
|
|
236
|
-
(_this$_recorderApp6 = this._recorderApp) === null || _this$_recorderApp6 === void 0 || _this$_recorderApp6.setSelector(this._highlightedSelector).catch(() => {});
|
|
237
|
-
}
|
|
272
|
+
if (isScreenshotCommand(metadata)) this.hideHighlightedSelector();else if (metadata.params && metadata.params.selector) this._highlightedElement = {
|
|
273
|
+
selector: metadata.params.selector
|
|
274
|
+
};
|
|
238
275
|
}
|
|
239
276
|
async onAfterCall(sdkObject, metadata) {
|
|
240
|
-
if (this._omitCallTracking || this.
|
|
277
|
+
if (this._omitCallTracking || this._isRecording()) return;
|
|
241
278
|
if (!metadata.error) this._currentCallsMetadata.delete(metadata);
|
|
242
279
|
this._updateUserSources();
|
|
243
280
|
this.updateCallLog([metadata]);
|
|
244
281
|
}
|
|
245
282
|
_updateUserSources() {
|
|
246
|
-
var _this$
|
|
283
|
+
var _this$_recorderApp5;
|
|
247
284
|
// Remove old decorations.
|
|
248
285
|
for (const source of this._userSources.values()) {
|
|
249
286
|
source.highlight = [];
|
|
@@ -281,19 +318,19 @@ class Recorder {
|
|
|
281
318
|
}
|
|
282
319
|
}
|
|
283
320
|
this._pushAllSources();
|
|
284
|
-
if (fileToSelect) (_this$
|
|
321
|
+
if (fileToSelect) (_this$_recorderApp5 = this._recorderApp) === null || _this$_recorderApp5 === void 0 || _this$_recorderApp5.setRunningFile(fileToSelect);
|
|
285
322
|
}
|
|
286
323
|
_pushAllSources() {
|
|
287
|
-
var _this$
|
|
288
|
-
(_this$
|
|
324
|
+
var _this$_recorderApp6;
|
|
325
|
+
(_this$_recorderApp6 = this._recorderApp) === null || _this$_recorderApp6 === void 0 || _this$_recorderApp6.setSources([...this._recorderSources, ...this._userSources.values()]);
|
|
289
326
|
}
|
|
290
327
|
async onBeforeInputAction(sdkObject, metadata) {}
|
|
291
328
|
async onCallLog(sdkObject, metadata, logName, message) {
|
|
292
329
|
this.updateCallLog([metadata]);
|
|
293
330
|
}
|
|
294
331
|
updateCallLog(metadatas) {
|
|
295
|
-
var _this$
|
|
296
|
-
if (this.
|
|
332
|
+
var _this$_recorderApp7;
|
|
333
|
+
if (this._isRecording()) return;
|
|
297
334
|
const logs = [];
|
|
298
335
|
for (const metadata of metadatas) {
|
|
299
336
|
if (!metadata.method || metadata.internal) continue;
|
|
@@ -302,7 +339,10 @@ class Recorder {
|
|
|
302
339
|
if (this._debugger.isPaused(metadata)) status = 'paused';
|
|
303
340
|
logs.push((0, _recorderUtils.metadataToCallLog)(metadata, status));
|
|
304
341
|
}
|
|
305
|
-
(_this$
|
|
342
|
+
(_this$_recorderApp7 = this._recorderApp) === null || _this$_recorderApp7 === void 0 || _this$_recorderApp7.updateCallLogs(logs);
|
|
343
|
+
}
|
|
344
|
+
_isRecording() {
|
|
345
|
+
return ['recording', 'assertingText', 'assertingVisibility', 'assertingValue', 'assertingSnapshot'].includes(this._mode);
|
|
306
346
|
}
|
|
307
347
|
_readSource(fileName) {
|
|
308
348
|
try {
|
|
@@ -8,7 +8,6 @@ exports.browserDirectoryToMarkerFilePath = browserDirectoryToMarkerFilePath;
|
|
|
8
8
|
exports.buildPlaywrightCLICommand = buildPlaywrightCLICommand;
|
|
9
9
|
exports.findChromiumChannel = findChromiumChannel;
|
|
10
10
|
exports.installBrowsersForNpmInstall = installBrowsersForNpmInstall;
|
|
11
|
-
exports.installDefaultBrowsersForNpmInstall = installDefaultBrowsersForNpmInstall;
|
|
12
11
|
exports.registryDirectory = exports.registry = void 0;
|
|
13
12
|
Object.defineProperty(exports, "writeDockerVersion", {
|
|
14
13
|
enumerable: true,
|
|
@@ -65,6 +64,11 @@ const EXECUTABLE_PATHS = {
|
|
|
65
64
|
'mac': ['chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium'],
|
|
66
65
|
'win': ['chrome-win', 'chrome.exe']
|
|
67
66
|
},
|
|
67
|
+
'chromium-headless-shell': {
|
|
68
|
+
'linux': ['chrome-linux', 'headless_shell'],
|
|
69
|
+
'mac': ['chrome-mac', 'headless_shell'],
|
|
70
|
+
'win': ['chrome-win', 'headless_shell.exe']
|
|
71
|
+
},
|
|
68
72
|
'firefox': {
|
|
69
73
|
'linux': ['firefox', 'firefox'],
|
|
70
74
|
'mac': ['firefox', 'Nightly.app', 'Contents', 'MacOS', 'firefox'],
|
|
@@ -107,8 +111,39 @@ const DOWNLOAD_PATHS = {
|
|
|
107
111
|
'mac13-arm64': 'builds/chromium/%s/chromium-mac-arm64.zip',
|
|
108
112
|
'mac14': 'builds/chromium/%s/chromium-mac.zip',
|
|
109
113
|
'mac14-arm64': 'builds/chromium/%s/chromium-mac-arm64.zip',
|
|
114
|
+
'mac15': 'builds/chromium/%s/chromium-mac.zip',
|
|
115
|
+
'mac15-arm64': 'builds/chromium/%s/chromium-mac-arm64.zip',
|
|
110
116
|
'win64': 'builds/chromium/%s/chromium-win64.zip'
|
|
111
117
|
},
|
|
118
|
+
'chromium-headless-shell': {
|
|
119
|
+
'<unknown>': undefined,
|
|
120
|
+
'ubuntu18.04-x64': undefined,
|
|
121
|
+
'ubuntu20.04-x64': 'builds/chromium/%s/chromium-headless-shell-linux.zip',
|
|
122
|
+
'ubuntu22.04-x64': 'builds/chromium/%s/chromium-headless-shell-linux.zip',
|
|
123
|
+
'ubuntu24.04-x64': 'builds/chromium/%s/chromium-headless-shell-linux.zip',
|
|
124
|
+
'ubuntu18.04-arm64': undefined,
|
|
125
|
+
'ubuntu20.04-arm64': 'builds/chromium/%s/chromium-headless-shell-linux-arm64.zip',
|
|
126
|
+
'ubuntu22.04-arm64': 'builds/chromium/%s/chromium-headless-shell-linux-arm64.zip',
|
|
127
|
+
'ubuntu24.04-arm64': 'builds/chromium/%s/chromium-headless-shell-linux-arm64.zip',
|
|
128
|
+
'debian11-x64': 'builds/chromium/%s/chromium-headless-shell-linux.zip',
|
|
129
|
+
'debian11-arm64': 'builds/chromium/%s/chromium-headless-shell-linux-arm64.zip',
|
|
130
|
+
'debian12-x64': 'builds/chromium/%s/chromium-headless-shell-linux.zip',
|
|
131
|
+
'debian12-arm64': 'builds/chromium/%s/chromium-headless-shell-linux-arm64.zip',
|
|
132
|
+
'mac10.13': undefined,
|
|
133
|
+
'mac10.14': undefined,
|
|
134
|
+
'mac10.15': undefined,
|
|
135
|
+
'mac11': 'builds/chromium/%s/chromium-headless-shell-mac.zip',
|
|
136
|
+
'mac11-arm64': 'builds/chromium/%s/chromium-headless-shell-mac-arm64.zip',
|
|
137
|
+
'mac12': 'builds/chromium/%s/chromium-headless-shell-mac.zip',
|
|
138
|
+
'mac12-arm64': 'builds/chromium/%s/chromium-headless-shell-mac-arm64.zip',
|
|
139
|
+
'mac13': 'builds/chromium/%s/chromium-headless-shell-mac.zip',
|
|
140
|
+
'mac13-arm64': 'builds/chromium/%s/chromium-headless-shell-mac-arm64.zip',
|
|
141
|
+
'mac14': 'builds/chromium/%s/chromium-headless-shell-mac.zip',
|
|
142
|
+
'mac14-arm64': 'builds/chromium/%s/chromium-headless-shell-mac-arm64.zip',
|
|
143
|
+
'mac15': 'builds/chromium/%s/chromium-headless-shell-mac.zip',
|
|
144
|
+
'mac15-arm64': 'builds/chromium/%s/chromium-headless-shell-mac-arm64.zip',
|
|
145
|
+
'win64': 'builds/chromium/%s/chromium-headless-shell-win64.zip'
|
|
146
|
+
},
|
|
112
147
|
'chromium-tip-of-tree': {
|
|
113
148
|
'<unknown>': undefined,
|
|
114
149
|
'ubuntu18.04-x64': undefined,
|
|
@@ -134,6 +169,8 @@ const DOWNLOAD_PATHS = {
|
|
|
134
169
|
'mac13-arm64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac-arm64.zip',
|
|
135
170
|
'mac14': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac.zip',
|
|
136
171
|
'mac14-arm64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac-arm64.zip',
|
|
172
|
+
'mac15': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac.zip',
|
|
173
|
+
'mac15-arm64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-mac-arm64.zip',
|
|
137
174
|
'win64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-win64.zip'
|
|
138
175
|
},
|
|
139
176
|
'firefox': {
|
|
@@ -161,6 +198,8 @@ const DOWNLOAD_PATHS = {
|
|
|
161
198
|
'mac13-arm64': 'builds/firefox/%s/firefox-mac-arm64.zip',
|
|
162
199
|
'mac14': 'builds/firefox/%s/firefox-mac.zip',
|
|
163
200
|
'mac14-arm64': 'builds/firefox/%s/firefox-mac-arm64.zip',
|
|
201
|
+
'mac15': 'builds/firefox/%s/firefox-mac.zip',
|
|
202
|
+
'mac15-arm64': 'builds/firefox/%s/firefox-mac-arm64.zip',
|
|
164
203
|
'win64': 'builds/firefox/%s/firefox-win64.zip'
|
|
165
204
|
},
|
|
166
205
|
'firefox-beta': {
|
|
@@ -188,6 +227,8 @@ const DOWNLOAD_PATHS = {
|
|
|
188
227
|
'mac13-arm64': 'builds/firefox-beta/%s/firefox-beta-mac-arm64.zip',
|
|
189
228
|
'mac14': 'builds/firefox-beta/%s/firefox-beta-mac.zip',
|
|
190
229
|
'mac14-arm64': 'builds/firefox-beta/%s/firefox-beta-mac-arm64.zip',
|
|
230
|
+
'mac15': 'builds/firefox-beta/%s/firefox-beta-mac.zip',
|
|
231
|
+
'mac15-arm64': 'builds/firefox-beta/%s/firefox-beta-mac-arm64.zip',
|
|
191
232
|
'win64': 'builds/firefox-beta/%s/firefox-beta-win64.zip'
|
|
192
233
|
},
|
|
193
234
|
'webkit': {
|
|
@@ -215,6 +256,8 @@ const DOWNLOAD_PATHS = {
|
|
|
215
256
|
'mac13-arm64': 'builds/webkit/%s/webkit-mac-13-arm64.zip',
|
|
216
257
|
'mac14': 'builds/webkit/%s/webkit-mac-14.zip',
|
|
217
258
|
'mac14-arm64': 'builds/webkit/%s/webkit-mac-14-arm64.zip',
|
|
259
|
+
'mac15': 'builds/webkit/%s/webkit-mac-15.zip',
|
|
260
|
+
'mac15-arm64': 'builds/webkit/%s/webkit-mac-15-arm64.zip',
|
|
218
261
|
'win64': 'builds/webkit/%s/webkit-win64.zip'
|
|
219
262
|
},
|
|
220
263
|
'ffmpeg': {
|
|
@@ -242,6 +285,8 @@ const DOWNLOAD_PATHS = {
|
|
|
242
285
|
'mac13-arm64': 'builds/ffmpeg/%s/ffmpeg-mac-arm64.zip',
|
|
243
286
|
'mac14': 'builds/ffmpeg/%s/ffmpeg-mac.zip',
|
|
244
287
|
'mac14-arm64': 'builds/ffmpeg/%s/ffmpeg-mac-arm64.zip',
|
|
288
|
+
'mac15': 'builds/ffmpeg/%s/ffmpeg-mac.zip',
|
|
289
|
+
'mac15-arm64': 'builds/ffmpeg/%s/ffmpeg-mac-arm64.zip',
|
|
245
290
|
'win64': 'builds/ffmpeg/%s/ffmpeg-win64.zip'
|
|
246
291
|
},
|
|
247
292
|
'android': {
|
|
@@ -269,6 +314,8 @@ const DOWNLOAD_PATHS = {
|
|
|
269
314
|
'mac13-arm64': 'builds/android/%s/android.zip',
|
|
270
315
|
'mac14': 'builds/android/%s/android.zip',
|
|
271
316
|
'mac14-arm64': 'builds/android/%s/android.zip',
|
|
317
|
+
'mac15': 'builds/android/%s/android.zip',
|
|
318
|
+
'mac15-arm64': 'builds/android/%s/android.zip',
|
|
272
319
|
'win64': 'builds/android/%s/android.zip'
|
|
273
320
|
},
|
|
274
321
|
// TODO(bidi): implement downloads.
|
|
@@ -299,7 +346,7 @@ const registryDirectory = exports.registryDirectory = (() => {
|
|
|
299
346
|
function isBrowserDirectory(browserDirectory) {
|
|
300
347
|
const baseName = _path.default.basename(browserDirectory);
|
|
301
348
|
for (const browserName of allDownloadable) {
|
|
302
|
-
if (baseName.startsWith(browserName + '-')) return true;
|
|
349
|
+
if (baseName.startsWith(browserName.replace(/-/g, '_') + '-')) return true;
|
|
303
350
|
}
|
|
304
351
|
return false;
|
|
305
352
|
}
|
|
@@ -312,6 +359,7 @@ function readDescriptors(browsersJSON) {
|
|
|
312
359
|
const descriptor = {
|
|
313
360
|
name,
|
|
314
361
|
revision,
|
|
362
|
+
hasRevisionOverride: !!revisionOverride,
|
|
315
363
|
// We only put browser version for the supported operating systems.
|
|
316
364
|
browserVersion: revisionOverride ? undefined : obj.browserVersion,
|
|
317
365
|
installByDefault: !!obj.installByDefault,
|
|
@@ -325,7 +373,7 @@ function readDescriptors(browsersJSON) {
|
|
|
325
373
|
return descriptor;
|
|
326
374
|
});
|
|
327
375
|
}
|
|
328
|
-
const allDownloadable = ['chromium', 'firefox', 'webkit', 'ffmpeg', 'firefox-beta', 'chromium-tip-of-tree'];
|
|
376
|
+
const allDownloadable = ['android', 'chromium', 'firefox', 'webkit', 'ffmpeg', 'firefox-beta', 'chromium-tip-of-tree', 'chromium-headless-shell'];
|
|
329
377
|
class Registry {
|
|
330
378
|
constructor(browsersJSON) {
|
|
331
379
|
this._executables = void 0;
|
|
@@ -358,13 +406,30 @@ class Registry {
|
|
|
358
406
|
executablePath: () => chromiumExecutable,
|
|
359
407
|
executablePathOrDie: sdkLanguage => executablePathOrDie('chromium', chromiumExecutable, chromium.installByDefault, sdkLanguage),
|
|
360
408
|
installType: chromium.installByDefault ? 'download-by-default' : 'download-on-demand',
|
|
361
|
-
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage,
|
|
409
|
+
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, chromium.dir, ['chrome-linux'], [], ['chrome-win']),
|
|
362
410
|
downloadURLs: this._downloadURLs(chromium),
|
|
363
411
|
browserVersion: chromium.browserVersion,
|
|
364
412
|
_install: () => this._downloadExecutable(chromium, chromiumExecutable),
|
|
365
413
|
_dependencyGroup: 'chromium',
|
|
366
414
|
_isHermeticInstallation: true
|
|
367
415
|
});
|
|
416
|
+
const chromiumHeadlessShell = descriptors.find(d => d.name === 'chromium-headless-shell');
|
|
417
|
+
const chromiumHeadlessShellExecutable = findExecutablePath(chromiumHeadlessShell.dir, 'chromium-headless-shell');
|
|
418
|
+
this._executables.push({
|
|
419
|
+
type: 'channel',
|
|
420
|
+
name: 'chromium-headless-shell',
|
|
421
|
+
browserName: 'chromium',
|
|
422
|
+
directory: chromiumHeadlessShell.dir,
|
|
423
|
+
executablePath: () => chromiumHeadlessShellExecutable,
|
|
424
|
+
executablePathOrDie: sdkLanguage => executablePathOrDie('chromium', chromiumHeadlessShellExecutable, chromiumHeadlessShell.installByDefault, sdkLanguage),
|
|
425
|
+
installType: chromiumHeadlessShell.installByDefault ? 'download-by-default' : 'download-on-demand',
|
|
426
|
+
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, chromiumHeadlessShell.dir, ['chrome-linux'], [], ['chrome-win']),
|
|
427
|
+
downloadURLs: this._downloadURLs(chromiumHeadlessShell),
|
|
428
|
+
browserVersion: chromium.browserVersion,
|
|
429
|
+
_install: () => this._downloadExecutable(chromiumHeadlessShell, chromiumHeadlessShellExecutable),
|
|
430
|
+
_dependencyGroup: 'chromium',
|
|
431
|
+
_isHermeticInstallation: true
|
|
432
|
+
});
|
|
368
433
|
const chromiumTipOfTree = descriptors.find(d => d.name === 'chromium-tip-of-tree');
|
|
369
434
|
const chromiumTipOfTreeExecutable = findExecutablePath(chromiumTipOfTree.dir, 'chromium');
|
|
370
435
|
this._executables.push({
|
|
@@ -375,7 +440,7 @@ class Registry {
|
|
|
375
440
|
executablePath: () => chromiumTipOfTreeExecutable,
|
|
376
441
|
executablePathOrDie: sdkLanguage => executablePathOrDie('chromium-tip-of-tree', chromiumTipOfTreeExecutable, chromiumTipOfTree.installByDefault, sdkLanguage),
|
|
377
442
|
installType: chromiumTipOfTree.installByDefault ? 'download-by-default' : 'download-on-demand',
|
|
378
|
-
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage,
|
|
443
|
+
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, chromiumTipOfTree.dir, ['chrome-linux'], [], ['chrome-win']),
|
|
379
444
|
downloadURLs: this._downloadURLs(chromiumTipOfTree),
|
|
380
445
|
browserVersion: chromiumTipOfTree.browserVersion,
|
|
381
446
|
_install: () => this._downloadExecutable(chromiumTipOfTree, chromiumTipOfTreeExecutable),
|
|
@@ -442,11 +507,46 @@ class Registry {
|
|
|
442
507
|
'darwin': '/Applications/Microsoft Edge Canary.app/Contents/MacOS/Microsoft Edge Canary',
|
|
443
508
|
'win32': `\\Microsoft\\Edge SxS\\Application\\msedge.exe`
|
|
444
509
|
}));
|
|
445
|
-
this._executables.push(this.
|
|
446
|
-
'linux': '/
|
|
447
|
-
'darwin': '/
|
|
448
|
-
'win32': '\\
|
|
510
|
+
this._executables.push(this._createBidiFirefoxChannel('bidi-firefox-stable', {
|
|
511
|
+
'linux': '/firefox/firefox',
|
|
512
|
+
'darwin': '/Firefox.app/Contents/MacOS/firefox',
|
|
513
|
+
'win32': '\\core\\firefox.exe'
|
|
514
|
+
}));
|
|
515
|
+
this._executables.push(this._createBidiFirefoxChannel('bidi-firefox-beta', {
|
|
516
|
+
'linux': '/firefox/firefox',
|
|
517
|
+
'darwin': '/Firefox.app/Contents/MacOS/firefox',
|
|
518
|
+
'win32': '\\core\\firefox.exe'
|
|
519
|
+
}));
|
|
520
|
+
this._executables.push(this._createBidiFirefoxChannel('bidi-firefox-nightly', {
|
|
521
|
+
'linux': '/firefox/firefox',
|
|
522
|
+
'darwin': '/Firefox Nightly.app/Contents/MacOS/firefox',
|
|
523
|
+
'win32': '\\firefox\\firefox.exe'
|
|
449
524
|
}));
|
|
525
|
+
this._executables.push(this._createBidiChannel('bidi-chrome-stable', {
|
|
526
|
+
'linux': '/opt/google/chrome/chrome',
|
|
527
|
+
'darwin': '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
|
528
|
+
'win32': `\\Google\\Chrome\\Application\\chrome.exe`
|
|
529
|
+
}));
|
|
530
|
+
this._executables.push(this._createBidiChannel('bidi-chrome-canary', {
|
|
531
|
+
'linux': '',
|
|
532
|
+
'darwin': '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
|
|
533
|
+
'win32': `\\Google\\Chrome SxS\\Application\\chrome.exe`
|
|
534
|
+
}));
|
|
535
|
+
this._executables.push({
|
|
536
|
+
type: 'browser',
|
|
537
|
+
name: 'bidi-chromium',
|
|
538
|
+
browserName: 'bidi',
|
|
539
|
+
directory: chromium.dir,
|
|
540
|
+
executablePath: () => chromiumExecutable,
|
|
541
|
+
executablePathOrDie: sdkLanguage => executablePathOrDie('chromium', chromiumExecutable, chromium.installByDefault, sdkLanguage),
|
|
542
|
+
installType: 'download-on-demand',
|
|
543
|
+
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, chromium.dir, ['chrome-linux'], [], ['chrome-win']),
|
|
544
|
+
downloadURLs: this._downloadURLs(chromium),
|
|
545
|
+
browserVersion: chromium.browserVersion,
|
|
546
|
+
_install: () => this._downloadExecutable(chromium, chromiumExecutable),
|
|
547
|
+
_dependencyGroup: 'chromium',
|
|
548
|
+
_isHermeticInstallation: true
|
|
549
|
+
});
|
|
450
550
|
const firefox = descriptors.find(d => d.name === 'firefox');
|
|
451
551
|
const firefoxExecutable = findExecutablePath(firefox.dir, 'firefox');
|
|
452
552
|
this._executables.push({
|
|
@@ -457,7 +557,7 @@ class Registry {
|
|
|
457
557
|
executablePath: () => firefoxExecutable,
|
|
458
558
|
executablePathOrDie: sdkLanguage => executablePathOrDie('firefox', firefoxExecutable, firefox.installByDefault, sdkLanguage),
|
|
459
559
|
installType: firefox.installByDefault ? 'download-by-default' : 'download-on-demand',
|
|
460
|
-
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage,
|
|
560
|
+
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, firefox.dir, ['firefox'], [], ['firefox']),
|
|
461
561
|
downloadURLs: this._downloadURLs(firefox),
|
|
462
562
|
browserVersion: firefox.browserVersion,
|
|
463
563
|
_install: () => this._downloadExecutable(firefox, firefoxExecutable),
|
|
@@ -474,7 +574,7 @@ class Registry {
|
|
|
474
574
|
executablePath: () => firefoxBetaExecutable,
|
|
475
575
|
executablePathOrDie: sdkLanguage => executablePathOrDie('firefox-beta', firefoxBetaExecutable, firefoxBeta.installByDefault, sdkLanguage),
|
|
476
576
|
installType: firefoxBeta.installByDefault ? 'download-by-default' : 'download-on-demand',
|
|
477
|
-
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage,
|
|
577
|
+
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, firefoxBeta.dir, ['firefox'], [], ['firefox']),
|
|
478
578
|
downloadURLs: this._downloadURLs(firefoxBeta),
|
|
479
579
|
browserVersion: firefoxBeta.browserVersion,
|
|
480
580
|
_install: () => this._downloadExecutable(firefoxBeta, firefoxBetaExecutable),
|
|
@@ -492,7 +592,7 @@ class Registry {
|
|
|
492
592
|
executablePath: () => webkitExecutable,
|
|
493
593
|
executablePathOrDie: sdkLanguage => executablePathOrDie('webkit', webkitExecutable, webkit.installByDefault, sdkLanguage),
|
|
494
594
|
installType: webkit.installByDefault ? 'download-by-default' : 'download-on-demand',
|
|
495
|
-
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage,
|
|
595
|
+
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, webkit.dir, webkitLinuxLddDirectories, ['libGLESv2.so.2', 'libx264.so'], ['']),
|
|
496
596
|
downloadURLs: this._downloadURLs(webkit),
|
|
497
597
|
browserVersion: webkit.browserVersion,
|
|
498
598
|
_install: () => this._downloadExecutable(webkit, webkitExecutable),
|
|
@@ -575,6 +675,38 @@ class Registry {
|
|
|
575
675
|
_install: install
|
|
576
676
|
};
|
|
577
677
|
}
|
|
678
|
+
_createBidiFirefoxChannel(name, lookAt, install) {
|
|
679
|
+
const executablePath = (sdkLanguage, shouldThrow) => {
|
|
680
|
+
const suffix = lookAt[process.platform];
|
|
681
|
+
if (!suffix) {
|
|
682
|
+
if (shouldThrow) throw new Error(`Firefox distribution '${name}' is not supported on ${process.platform}`);
|
|
683
|
+
return undefined;
|
|
684
|
+
}
|
|
685
|
+
const folder = _path.default.resolve('firefox');
|
|
686
|
+
let channelName = 'stable';
|
|
687
|
+
if (name.includes('beta')) channelName = 'beta';else if (name.includes('nightly')) channelName = 'nightly';
|
|
688
|
+
const installedVersions = fs.readdirSync(folder);
|
|
689
|
+
const found = installedVersions.filter(e => e.includes(channelName));
|
|
690
|
+
if (found.length === 1) return _path.default.join(folder, found[0], suffix);
|
|
691
|
+
if (found.length > 1) {
|
|
692
|
+
if (shouldThrow) throw new Error(`Multiple Firefox installations found for channel '${name}': ${found.join(', ')}`);else return undefined;
|
|
693
|
+
}
|
|
694
|
+
if (shouldThrow) throw new Error(`Cannot find Firefox installation for channel '${name}' under ${folder}`);
|
|
695
|
+
return undefined;
|
|
696
|
+
};
|
|
697
|
+
return {
|
|
698
|
+
type: 'channel',
|
|
699
|
+
name,
|
|
700
|
+
browserName: 'bidi',
|
|
701
|
+
directory: undefined,
|
|
702
|
+
executablePath: sdkLanguage => executablePath(sdkLanguage, false),
|
|
703
|
+
executablePathOrDie: sdkLanguage => executablePath(sdkLanguage, true),
|
|
704
|
+
installType: 'none',
|
|
705
|
+
_validateHostRequirements: () => Promise.resolve(),
|
|
706
|
+
_isHermeticInstallation: true,
|
|
707
|
+
_install: install
|
|
708
|
+
};
|
|
709
|
+
}
|
|
578
710
|
_createBidiChannel(name, lookAt, install) {
|
|
579
711
|
const executablePath = (sdkLanguage, shouldThrow) => {
|
|
580
712
|
const suffix = lookAt[process.platform];
|
|
@@ -614,20 +746,15 @@ class Registry {
|
|
|
614
746
|
defaultExecutables() {
|
|
615
747
|
return this._executables.filter(e => e.installType === 'download-by-default');
|
|
616
748
|
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
for (const executable of executables) {
|
|
620
|
-
set.add(executable);
|
|
621
|
-
if (executable.browserName === 'chromium') set.add(this.findExecutable('ffmpeg'));
|
|
622
|
-
}
|
|
623
|
-
return Array.from(set);
|
|
749
|
+
_dedupe(executables) {
|
|
750
|
+
return Array.from(new Set(executables));
|
|
624
751
|
}
|
|
625
|
-
async _validateHostRequirements(sdkLanguage,
|
|
752
|
+
async _validateHostRequirements(sdkLanguage, browserDirectory, linuxLddDirectories, dlOpenLibraries, windowsExeAndDllDirectories) {
|
|
626
753
|
if (os.platform() === 'linux') return await (0, _dependencies.validateDependenciesLinux)(sdkLanguage, linuxLddDirectories.map(d => _path.default.join(browserDirectory, d)), dlOpenLibraries);
|
|
627
754
|
if (os.platform() === 'win32' && os.arch() === 'x64') return await (0, _dependencies.validateDependenciesWindows)(windowsExeAndDllDirectories.map(d => _path.default.join(browserDirectory, d)));
|
|
628
755
|
}
|
|
629
756
|
async installDeps(executablesToInstallDeps, dryRun) {
|
|
630
|
-
const executables = this.
|
|
757
|
+
const executables = this._dedupe(executablesToInstallDeps);
|
|
631
758
|
const targets = new Set();
|
|
632
759
|
for (const executable of executables) {
|
|
633
760
|
if (executable._dependencyGroup) targets.add(executable._dependencyGroup);
|
|
@@ -637,7 +764,7 @@ class Registry {
|
|
|
637
764
|
if (os.platform() === 'linux') return await (0, _dependencies.installDependenciesLinux)(targets, dryRun);
|
|
638
765
|
}
|
|
639
766
|
async install(executablesToInstall, forceReinstall) {
|
|
640
|
-
const executables = this.
|
|
767
|
+
const executables = this._dedupe(executablesToInstall);
|
|
641
768
|
await fs.promises.mkdir(registryDirectory, {
|
|
642
769
|
recursive: true
|
|
643
770
|
});
|
|
@@ -745,6 +872,11 @@ class Registry {
|
|
|
745
872
|
const downloadURLs = this._downloadURLs(descriptor);
|
|
746
873
|
if (!downloadURLs.length) throw new Error(`ERROR: Playwright does not support ${descriptor.name} on ${_hostPlatform.hostPlatform}`);
|
|
747
874
|
if (!_hostPlatform.isOfficiallySupportedPlatform) (0, _browserFetcher.logPolitely)(`BEWARE: your OS is not officially supported by Playwright; downloading fallback build for ${_hostPlatform.hostPlatform}.`);
|
|
875
|
+
if (descriptor.hasRevisionOverride) {
|
|
876
|
+
const message = `You are using a frozen ${descriptor.name} browser which does not receive updates anymore on ${_hostPlatform.hostPlatform}. Please update to the latest version of your operating system to test up-to-date browsers.`;
|
|
877
|
+
if (process.env.GITHUB_ACTIONS) console.log(`::warning title=Playwright::${message}`); // eslint-disable-line no-console
|
|
878
|
+
else (0, _browserFetcher.logPolitely)(message);
|
|
879
|
+
}
|
|
748
880
|
const displayName = descriptor.name.split('-').map(word => {
|
|
749
881
|
return word === 'ffmpeg' ? 'FFMPEG' : word.charAt(0).toUpperCase() + word.slice(1);
|
|
750
882
|
}).join(' ');
|
|
@@ -878,10 +1010,6 @@ function buildPlaywrightCLICommand(sdkLanguage, parameters) {
|
|
|
878
1010
|
}
|
|
879
1011
|
}
|
|
880
1012
|
}
|
|
881
|
-
async function installDefaultBrowsersForNpmInstall() {
|
|
882
|
-
const defaultBrowserNames = registry.defaultExecutables().map(e => e.name);
|
|
883
|
-
return installBrowsersForNpmInstall(defaultBrowserNames);
|
|
884
|
-
}
|
|
885
1013
|
async function installBrowsersForNpmInstall(browsers) {
|
|
886
1014
|
// PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD should have a value of 0 or 1
|
|
887
1015
|
if ((0, _utils.getAsBooleanFromENV)('PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD')) {
|