rebrowser-playwright-core 1.48.2 → 1.49.1
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 +2 -2
- 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 +19 -11
- package/lib/cli/program.js +23 -5
- package/lib/client/channelOwner.js +2 -2
- package/lib/client/locator.js +7 -0
- package/lib/client/network.js +5 -0
- package/lib/client/page.js +4 -2
- package/lib/client/tracing.js +13 -0
- 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 +1 -1
- package/lib/generated/webSocketMockSource.js +1 -1
- package/lib/protocol/validator.js +23 -3
- package/lib/server/ariaSnapshot.js +33 -0
- package/lib/server/bidi/bidiChromium.js +1 -1
- package/lib/server/bidi/bidiConnection.js +0 -2
- package/lib/server/bidi/bidiExecutionContext.js +0 -3
- package/lib/server/browserType.js +4 -1
- package/lib/server/chromium/chromium.js +6 -2
- package/lib/server/chromium/crConnection.js +153 -0
- package/lib/server/chromium/crExecutionContext.js +0 -13
- package/lib/server/chromium/crPage.js +8 -10
- package/lib/server/codegen/csharp.js +11 -16
- package/lib/server/codegen/java.js +4 -7
- package/lib/server/codegen/javascript.js +28 -6
- package/lib/server/codegen/python.js +12 -16
- package/lib/server/debugController.js +8 -5
- package/lib/server/deviceDescriptorsSource.json +127 -127
- package/lib/server/dispatchers/androidDispatcher.js +13 -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/tracingDispatcher.js +10 -0
- package/lib/server/dom.js +79 -36
- package/lib/server/fetch.js +30 -17
- package/lib/server/firefox/ffExecutionContext.js +0 -12
- package/lib/server/firefox/ffNetworkManager.js +1 -1
- package/lib/server/frames.js +66 -196
- package/lib/server/index.js +0 -6
- package/lib/server/javascript.js +0 -6
- package/lib/server/launchApp.js +5 -5
- package/lib/server/page.js +52 -8
- package/lib/server/progress.js +0 -3
- package/lib/server/recorder/recorderApp.js +6 -15
- package/lib/server/recorder/recorderCollection.js +1 -1
- package/lib/server/recorder/recorderInTraceViewer.js +3 -3
- package/lib/server/recorder/recorderUtils.js +2 -1
- package/lib/server/recorder.js +66 -31
- package/lib/server/registry/index.js +70 -23
- package/lib/server/registry/nativeDeps.js +6 -3
- package/lib/server/socksClientCertificatesInterceptor.js +1 -1
- package/lib/server/trace/recorder/snapshotter.js +1 -12
- package/lib/server/trace/recorder/snapshotterInjected.js +19 -1
- package/lib/server/trace/recorder/tracing.js +69 -15
- package/lib/server/trace/test/inMemorySnapshotter.js +3 -3
- package/lib/server/trace/viewer/traceViewer.js +2 -1
- package/lib/server/webkit/wkBrowser.js +2 -2
- package/lib/server/webkit/wkExecutionContext.js +0 -13
- package/lib/server/webkit/wkPage.js +6 -0
- package/lib/utils/comparators.js +12 -30
- package/lib/utils/crypto.js +1 -4
- package/lib/utils/hostPlatform.js +6 -0
- package/lib/utils/isomorphic/ariaSnapshot.js +267 -0
- package/lib/utils/isomorphic/locatorGenerators.js +23 -5
- package/lib/utils/isomorphic/recorderUtils.js +36 -4
- 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-C5j27SYZ.js +24 -0
- package/lib/vite/recorder/assets/{index-BW-aOBcL.css → index-iA1aAGZg.css} +1 -1
- package/lib/vite/recorder/assets/index-m0XdVJHe.js +184 -0
- package/lib/vite/recorder/index.html +2 -2
- package/lib/vite/traceViewer/assets/codeMirrorModule-BBCX0spr.js +24 -0
- package/lib/vite/traceViewer/assets/inspectorTab-B4Iw34Ow.js +68 -0
- package/lib/vite/traceViewer/assets/workbench-DFlGYqou.js +9 -0
- package/lib/vite/traceViewer/{embedded.BlHoW5LY.js → embedded.CmarehFk.js} +1 -1
- package/lib/vite/traceViewer/embedded.html +5 -5
- package/lib/vite/traceViewer/{index.DaWVfou1.js → index.FBucu_gE.js} +1 -1
- package/lib/vite/traceViewer/index.html +24 -7
- package/lib/vite/traceViewer/{inspectorTab.DLjBDrQR.css → inspectorTab.DEOUW62d.css} +1 -1
- package/lib/vite/traceViewer/recorder.CW_rzcEp.js +2 -0
- package/lib/vite/traceViewer/recorder.html +3 -3
- package/lib/vite/traceViewer/sw.bundle.js +3 -3
- package/lib/vite/traceViewer/uiMode.CDUVjusr.js +5 -0
- package/lib/vite/traceViewer/uiMode.html +6 -6
- package/lib/vite/traceViewer/{uiMode.CAYqod-m.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 +58 -10
- package/types/types.d.ts +134 -29
- package/lib/third_party/diff_match_patch.js +0 -2222
- package/lib/vite/recorder/assets/codeMirrorModule-baozm8ur.js +0 -24
- package/lib/vite/recorder/assets/index-2ElAIWFB.js +0 -42
- package/lib/vite/traceViewer/assets/codeMirrorModule-Bh1rfd2w.js +0 -24
- package/lib/vite/traceViewer/assets/inspectorTab-7GHnKvSD.js +0 -64
- package/lib/vite/traceViewer/assets/workbench-DPQnTHYP.js +0 -9
- package/lib/vite/traceViewer/recorder.C4zxcvd2.js +0 -2
- package/lib/vite/traceViewer/uiMode.mTXWniJb.js +0 -5
- package/lib/vite/traceViewer/workbench.D3JVcA9K.css +0 -1
package/lib/server/page.js
CHANGED
|
@@ -22,6 +22,7 @@ var _instrumentation = require("./instrumentation");
|
|
|
22
22
|
var _selectorParser = require("../utils/isomorphic/selectorParser");
|
|
23
23
|
var _utilityScriptSerializers = require("./isomorphic/utilityScriptSerializers");
|
|
24
24
|
var _errors = require("./errors");
|
|
25
|
+
var _helper = require("./helper");
|
|
25
26
|
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); }
|
|
26
27
|
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; }
|
|
27
28
|
/**
|
|
@@ -308,7 +309,29 @@ class Page extends _instrumentation.SdkObject {
|
|
|
308
309
|
unregisterLocatorHandler(uid) {
|
|
309
310
|
this._locatorHandlers.delete(uid);
|
|
310
311
|
}
|
|
311
|
-
async
|
|
312
|
+
async performActionPreChecks(progress) {
|
|
313
|
+
await this._performWaitForNavigationCheck(progress);
|
|
314
|
+
progress.throwIfAborted();
|
|
315
|
+
await this._performLocatorHandlersCheckpoint(progress);
|
|
316
|
+
progress.throwIfAborted();
|
|
317
|
+
// Wait once again, just in case a locator handler caused a navigation.
|
|
318
|
+
await this._performWaitForNavigationCheck(progress);
|
|
319
|
+
}
|
|
320
|
+
async _performWaitForNavigationCheck(progress) {
|
|
321
|
+
var _mainFrame$pendingDoc;
|
|
322
|
+
if (process.env.PLAYWRIGHT_SKIP_NAVIGATION_CHECK) return;
|
|
323
|
+
const mainFrame = this._frameManager.mainFrame();
|
|
324
|
+
if (!mainFrame || !mainFrame.pendingDocument()) return;
|
|
325
|
+
const url = (_mainFrame$pendingDoc = mainFrame.pendingDocument()) === null || _mainFrame$pendingDoc === void 0 || (_mainFrame$pendingDoc = _mainFrame$pendingDoc.request) === null || _mainFrame$pendingDoc === void 0 ? void 0 : _mainFrame$pendingDoc.url();
|
|
326
|
+
const toUrl = url ? `" ${(0, _utils.trimStringWithEllipsis)(url, 200)}"` : '';
|
|
327
|
+
progress.log(` waiting for${toUrl} navigation to finish...`);
|
|
328
|
+
await _helper.helper.waitForEvent(progress, mainFrame, frames.Frame.Events.InternalNavigation, e => {
|
|
329
|
+
if (!e.isPublic) return false;
|
|
330
|
+
if (!e.error) progress.log(` navigated to "${(0, _utils.trimStringWithEllipsis)(mainFrame.url(), 200)}"`);
|
|
331
|
+
return true;
|
|
332
|
+
}).promise;
|
|
333
|
+
}
|
|
334
|
+
async _performLocatorHandlersCheckpoint(progress) {
|
|
312
335
|
// Do not run locator handlers from inside locator handler callbacks to avoid deadlocks.
|
|
313
336
|
if (this._locatorHandlerRunningCounter) return;
|
|
314
337
|
for (const [uid, handler] of this._locatorHandlers) {
|
|
@@ -409,7 +432,7 @@ class Page extends _instrumentation.SdkObject {
|
|
|
409
432
|
const rafrafScreenshot = locator ? async (progress, timeout) => {
|
|
410
433
|
return await locator.frame.rafrafTimeoutScreenshotElementWithProgress(progress, locator.selector, timeout, options || {});
|
|
411
434
|
} : async (progress, timeout) => {
|
|
412
|
-
await this.
|
|
435
|
+
await this.performActionPreChecks(progress);
|
|
413
436
|
await this.mainFrame().rafrafTimeout(timeout);
|
|
414
437
|
return await this._screenshotter.screenshotPage(progress, options || {});
|
|
415
438
|
};
|
|
@@ -472,19 +495,23 @@ class Page extends _instrumentation.SdkObject {
|
|
|
472
495
|
progress.log(`screenshot matched expectation`);
|
|
473
496
|
return {};
|
|
474
497
|
}
|
|
475
|
-
if (areEqualScreenshots(actual, options.expected,
|
|
498
|
+
if (areEqualScreenshots(actual, options.expected, undefined)) {
|
|
476
499
|
progress.log(`screenshot matched expectation`);
|
|
477
500
|
return {};
|
|
478
501
|
}
|
|
479
502
|
throw new Error(intermediateResult.errorMessage);
|
|
480
503
|
}, callTimeout).catch(e => {
|
|
504
|
+
var _intermediateResult;
|
|
481
505
|
// Q: Why not throw upon isSessionClosedError(e) as in other places?
|
|
482
506
|
// A: We want user to receive a friendly diff between actual and expected/previous.
|
|
483
507
|
if (js.isJavaScriptErrorInEvaluate(e) || (0, _selectorParser.isInvalidSelectorError)(e)) throw e;
|
|
508
|
+
let errorMessage = e.message;
|
|
509
|
+
if (e instanceof _errors.TimeoutError && (_intermediateResult = intermediateResult) !== null && _intermediateResult !== void 0 && _intermediateResult.previous) errorMessage = `Failed to take two consecutive stable screenshots.`;
|
|
484
510
|
return {
|
|
485
|
-
log: e.message ? [...metadata.log, e.message] : metadata.log,
|
|
511
|
+
log: (0, _utils.compressCallLog)(e.message ? [...metadata.log, e.message] : metadata.log),
|
|
486
512
|
...intermediateResult,
|
|
487
|
-
errorMessage
|
|
513
|
+
errorMessage,
|
|
514
|
+
timedOut: e instanceof _errors.TimeoutError
|
|
488
515
|
};
|
|
489
516
|
});
|
|
490
517
|
}
|
|
@@ -596,16 +623,20 @@ Page.Events = {
|
|
|
596
623
|
Worker: 'worker'
|
|
597
624
|
};
|
|
598
625
|
class Worker extends _instrumentation.SdkObject {
|
|
599
|
-
constructor(parent, url) {
|
|
626
|
+
constructor(parent, url, targetId, session) {
|
|
600
627
|
super(parent, 'worker');
|
|
601
628
|
this._url = void 0;
|
|
602
629
|
this._executionContextPromise = void 0;
|
|
603
630
|
this._executionContextCallback = void 0;
|
|
604
631
|
this._existingExecutionContext = null;
|
|
605
632
|
this.openScope = new _utils.LongStandingScope();
|
|
633
|
+
this._targetId = void 0;
|
|
634
|
+
this._session = void 0;
|
|
606
635
|
this._url = url;
|
|
607
636
|
this._executionContextCallback = () => {};
|
|
608
637
|
this._executionContextPromise = new Promise(x => this._executionContextCallback = x);
|
|
638
|
+
this._targetId = targetId;
|
|
639
|
+
this._session = session;
|
|
609
640
|
}
|
|
610
641
|
_createExecutionContext(delegate) {
|
|
611
642
|
this._existingExecutionContext = new js.ExecutionContext(this, delegate, 'worker');
|
|
@@ -619,14 +650,23 @@ class Worker extends _instrumentation.SdkObject {
|
|
|
619
650
|
this.emit(Worker.Events.Close, this);
|
|
620
651
|
this.openScope.close(new Error('Worker closed'));
|
|
621
652
|
}
|
|
653
|
+
async getExecutionContext() {
|
|
654
|
+
if (process.env['REBROWSER_PATCHES_RUNTIME_FIX_MODE'] !== '0' && !this._existingExecutionContext) {
|
|
655
|
+
await this._session.__re__emitExecutionContext({
|
|
656
|
+
world: 'main',
|
|
657
|
+
targetId: this._targetId
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
return this._executionContextPromise;
|
|
661
|
+
}
|
|
622
662
|
async evaluateExpression(expression, isFunction, arg) {
|
|
623
|
-
return js.evaluateExpression(await this.
|
|
663
|
+
return js.evaluateExpression(await this.getExecutionContext(), expression, {
|
|
624
664
|
returnByValue: true,
|
|
625
665
|
isFunction
|
|
626
666
|
}, arg);
|
|
627
667
|
}
|
|
628
668
|
async evaluateExpressionHandle(expression, isFunction, arg) {
|
|
629
|
-
return js.evaluateExpression(await this.
|
|
669
|
+
return js.evaluateExpression(await this.getExecutionContext(), expression, {
|
|
630
670
|
returnByValue: false,
|
|
631
671
|
isFunction
|
|
632
672
|
}, arg);
|
|
@@ -650,6 +690,10 @@ class PageBinding {
|
|
|
650
690
|
this.internal = name.startsWith('__pw');
|
|
651
691
|
}
|
|
652
692
|
static async dispatch(page, payload, context) {
|
|
693
|
+
if (process.env['REBROWSER_PATCHES_RUNTIME_FIX_MODE'] !== '0' && !payload.includes('{')) {
|
|
694
|
+
// ignore as it's not a JSON but a string from addBinding method
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
653
697
|
const {
|
|
654
698
|
name,
|
|
655
699
|
seq,
|
package/lib/server/progress.js
CHANGED
|
@@ -70,9 +70,6 @@ class ProgressController {
|
|
|
70
70
|
throwIfAborted: () => {
|
|
71
71
|
if (this._state === 'aborted') throw new AbortedError();
|
|
72
72
|
},
|
|
73
|
-
beforeInputAction: async element => {
|
|
74
|
-
await this.instrumentation.onBeforeInputAction(this.sdkObject, this.metadata, element);
|
|
75
|
-
},
|
|
76
73
|
metadata: this.metadata
|
|
77
74
|
};
|
|
78
75
|
const timeoutError = new _errors.TimeoutError(`Timeout ${this._timeout}ms exceeded.`);
|
|
@@ -38,7 +38,7 @@ class EmptyRecorderApp extends _events.EventEmitter {
|
|
|
38
38
|
async setPaused(paused) {}
|
|
39
39
|
async setMode(mode) {}
|
|
40
40
|
async setRunningFile(file) {}
|
|
41
|
-
async
|
|
41
|
+
async elementPicked(elementInfo, userGesture) {}
|
|
42
42
|
async updateCallLogs(callLogs) {}
|
|
43
43
|
async setSources(sources) {}
|
|
44
44
|
async setActions(actions, sources) {}
|
|
@@ -165,23 +165,14 @@ class RecorderApp extends _events.EventEmitter {
|
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
async setActions(actions, sources) {}
|
|
168
|
-
async
|
|
169
|
-
if (userGesture)
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
this._recorder.setMode('standby');
|
|
173
|
-
this._page.bringToFront();
|
|
174
|
-
} else {
|
|
175
|
-
var _this$_recorder2;
|
|
176
|
-
(_this$_recorder2 = this._recorder) === null || _this$_recorder2 === void 0 || _this$_recorder2.setMode('recording');
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
await this._page.mainFrame().evaluateExpression((data => {
|
|
180
|
-
window.playwrightSetSelector(data.selector, data.userGesture);
|
|
168
|
+
async elementPicked(elementInfo, userGesture) {
|
|
169
|
+
if (userGesture) this._page.bringToFront();
|
|
170
|
+
await this._page.mainFrame().evaluateExpression((param => {
|
|
171
|
+
window.playwrightElementPicked(param.elementInfo, param.userGesture);
|
|
181
172
|
}).toString(), {
|
|
182
173
|
isFunction: true
|
|
183
174
|
}, {
|
|
184
|
-
|
|
175
|
+
elementInfo,
|
|
185
176
|
userGesture
|
|
186
177
|
}).catch(() => {});
|
|
187
178
|
}
|
|
@@ -77,9 +77,9 @@ class RecorderInTraceViewer extends _events.EventEmitter {
|
|
|
77
77
|
file
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
|
-
async
|
|
81
|
-
this._transport.deliverEvent('
|
|
82
|
-
|
|
80
|
+
async elementPicked(elementInfo, userGesture) {
|
|
81
|
+
this._transport.deliverEvent('elementPicked', {
|
|
82
|
+
elementInfo,
|
|
83
83
|
userGesture
|
|
84
84
|
});
|
|
85
85
|
}
|
|
@@ -73,11 +73,12 @@ function callMetadataForAction(pageAliases, actionInContext) {
|
|
|
73
73
|
const mainFrame = mainFrameForAction(pageAliases, actionInContext);
|
|
74
74
|
const {
|
|
75
75
|
method,
|
|
76
|
+
apiName,
|
|
76
77
|
params
|
|
77
78
|
} = (0, _recorderUtils.traceParamsForAction)(actionInContext);
|
|
78
79
|
const callMetadata = {
|
|
79
80
|
id: `call@${(0, _utils.createGuid)()}`,
|
|
80
|
-
apiName
|
|
81
|
+
apiName,
|
|
81
82
|
objectId: mainFrame.guid,
|
|
82
83
|
pageId: mainFrame._page.guid,
|
|
83
84
|
frameId: mainFrame.guid,
|
package/lib/server/recorder.js
CHANGED
|
@@ -13,6 +13,7 @@ var _debugger = require("./debugger");
|
|
|
13
13
|
var _contextRecorder = require("./recorder/contextRecorder");
|
|
14
14
|
var _recorderUtils = require("./recorder/recorderUtils");
|
|
15
15
|
var _recorderUtils2 = require("../utils/isomorphic/recorderUtils");
|
|
16
|
+
var _selectorParser = require("../utils/isomorphic/selectorParser");
|
|
16
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); }
|
|
17
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; }
|
|
18
19
|
/**
|
|
@@ -58,7 +59,7 @@ class Recorder {
|
|
|
58
59
|
this.handleSIGINT = void 0;
|
|
59
60
|
this._context = void 0;
|
|
60
61
|
this._mode = void 0;
|
|
61
|
-
this.
|
|
62
|
+
this._highlightedElement = {};
|
|
62
63
|
this._overlayState = {
|
|
63
64
|
offsetX: 0
|
|
64
65
|
};
|
|
@@ -94,8 +95,9 @@ class Recorder {
|
|
|
94
95
|
this.setMode(data.params.mode);
|
|
95
96
|
return;
|
|
96
97
|
}
|
|
97
|
-
if (data.event === '
|
|
98
|
-
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);
|
|
99
101
|
return;
|
|
100
102
|
}
|
|
101
103
|
if (data.event === 'step') {
|
|
@@ -133,12 +135,12 @@ class Recorder {
|
|
|
133
135
|
recorderApp.setRunningFile(undefined);
|
|
134
136
|
this._pushAllSources();
|
|
135
137
|
});
|
|
136
|
-
await this._context.exposeBinding('__pw_recorderState', false, source => {
|
|
137
|
-
let actionSelector
|
|
138
|
+
await this._context.exposeBinding('__pw_recorderState', false, async source => {
|
|
139
|
+
let actionSelector;
|
|
138
140
|
let actionPoint;
|
|
139
141
|
const hasActiveScreenshotCommand = [...this._currentCallsMetadata.keys()].some(isScreenshotCommand);
|
|
140
142
|
if (!hasActiveScreenshotCommand) {
|
|
141
|
-
actionSelector = this.
|
|
143
|
+
actionSelector = await this._scopeHighlightedSelectorToFrame(source.frame);
|
|
142
144
|
for (const [metadata, sdkObject] of this._currentCallsMetadata) {
|
|
143
145
|
if (source.page === sdkObject.attribution.page) {
|
|
144
146
|
actionPoint = metadata.point || actionPoint;
|
|
@@ -150,18 +152,22 @@ class Recorder {
|
|
|
150
152
|
mode: this._mode,
|
|
151
153
|
actionPoint,
|
|
152
154
|
actionSelector,
|
|
155
|
+
ariaTemplate: this._highlightedElement.ariaTemplate,
|
|
153
156
|
language: this._currentLanguage,
|
|
154
157
|
testIdAttributeName: this._contextRecorder.testIdAttributeName(),
|
|
155
158
|
overlay: this._overlayState
|
|
156
159
|
};
|
|
157
160
|
return uiState;
|
|
158
161
|
});
|
|
159
|
-
await this._context.exposeBinding('
|
|
162
|
+
await this._context.exposeBinding('__pw_recorderElementPicked', false, async ({
|
|
160
163
|
frame
|
|
161
|
-
},
|
|
164
|
+
}, elementInfo) => {
|
|
162
165
|
var _this$_recorderApp2;
|
|
163
166
|
const selectorChain = await (0, _contextRecorder.generateFrameSelector)(frame);
|
|
164
|
-
await ((_this$_recorderApp2 = this._recorderApp) === null || _this$_recorderApp2 === void 0 ? void 0 : _this$_recorderApp2.
|
|
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));
|
|
165
171
|
});
|
|
166
172
|
await this._context.exposeBinding('__pw_recorderSetMode', false, async ({
|
|
167
173
|
frame
|
|
@@ -200,11 +206,11 @@ class Recorder {
|
|
|
200
206
|
setMode(mode) {
|
|
201
207
|
var _this$_recorderApp4;
|
|
202
208
|
if (this._mode === mode) return;
|
|
203
|
-
this.
|
|
209
|
+
this._highlightedElement = {};
|
|
204
210
|
this._mode = mode;
|
|
205
211
|
(_this$_recorderApp4 = this._recorderApp) === null || _this$_recorderApp4 === void 0 || _this$_recorderApp4.setMode(this._mode);
|
|
206
|
-
this._contextRecorder.setEnabled(this.
|
|
207
|
-
this._debugger.setMuted(this.
|
|
212
|
+
this._contextRecorder.setEnabled(this._isRecording());
|
|
213
|
+
this._debugger.setMuted(this._isRecording());
|
|
208
214
|
if (this._mode !== 'none' && this._mode !== 'standby' && this._context.pages().length === 1) this._context.pages()[0].bringToFront().catch(() => {});
|
|
209
215
|
this._refreshOverlay();
|
|
210
216
|
}
|
|
@@ -215,40 +221,66 @@ class Recorder {
|
|
|
215
221
|
return this._mode;
|
|
216
222
|
}
|
|
217
223
|
setHighlightedSelector(language, selector) {
|
|
218
|
-
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
|
+
};
|
|
219
233
|
this._refreshOverlay();
|
|
220
234
|
}
|
|
221
235
|
hideHighlightedSelector() {
|
|
222
|
-
this.
|
|
236
|
+
this._highlightedElement = {};
|
|
223
237
|
this._refreshOverlay();
|
|
224
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
|
+
}
|
|
225
259
|
setOutput(codegenId, outputFile) {
|
|
226
260
|
this._contextRecorder.setOutput(codegenId, outputFile);
|
|
227
261
|
}
|
|
228
262
|
_refreshOverlay() {
|
|
229
|
-
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
|
+
}
|
|
230
266
|
}
|
|
231
267
|
async onBeforeCall(sdkObject, metadata) {
|
|
232
|
-
if (this._omitCallTracking || this.
|
|
268
|
+
if (this._omitCallTracking || this._isRecording()) return;
|
|
233
269
|
this._currentCallsMetadata.set(metadata, sdkObject);
|
|
234
270
|
this._updateUserSources();
|
|
235
271
|
this.updateCallLog([metadata]);
|
|
236
|
-
if (isScreenshotCommand(metadata)) {
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
var _this$_recorderApp5;
|
|
240
|
-
this._highlightedSelector = metadata.params.selector;
|
|
241
|
-
(_this$_recorderApp5 = this._recorderApp) === null || _this$_recorderApp5 === void 0 || _this$_recorderApp5.setSelector(this._highlightedSelector).catch(() => {});
|
|
242
|
-
}
|
|
272
|
+
if (isScreenshotCommand(metadata)) this.hideHighlightedSelector();else if (metadata.params && metadata.params.selector) this._highlightedElement = {
|
|
273
|
+
selector: metadata.params.selector
|
|
274
|
+
};
|
|
243
275
|
}
|
|
244
276
|
async onAfterCall(sdkObject, metadata) {
|
|
245
|
-
if (this._omitCallTracking || this.
|
|
277
|
+
if (this._omitCallTracking || this._isRecording()) return;
|
|
246
278
|
if (!metadata.error) this._currentCallsMetadata.delete(metadata);
|
|
247
279
|
this._updateUserSources();
|
|
248
280
|
this.updateCallLog([metadata]);
|
|
249
281
|
}
|
|
250
282
|
_updateUserSources() {
|
|
251
|
-
var _this$
|
|
283
|
+
var _this$_recorderApp5;
|
|
252
284
|
// Remove old decorations.
|
|
253
285
|
for (const source of this._userSources.values()) {
|
|
254
286
|
source.highlight = [];
|
|
@@ -286,19 +318,19 @@ class Recorder {
|
|
|
286
318
|
}
|
|
287
319
|
}
|
|
288
320
|
this._pushAllSources();
|
|
289
|
-
if (fileToSelect) (_this$
|
|
321
|
+
if (fileToSelect) (_this$_recorderApp5 = this._recorderApp) === null || _this$_recorderApp5 === void 0 || _this$_recorderApp5.setRunningFile(fileToSelect);
|
|
290
322
|
}
|
|
291
323
|
_pushAllSources() {
|
|
292
|
-
var _this$
|
|
293
|
-
(_this$
|
|
324
|
+
var _this$_recorderApp6;
|
|
325
|
+
(_this$_recorderApp6 = this._recorderApp) === null || _this$_recorderApp6 === void 0 || _this$_recorderApp6.setSources([...this._recorderSources, ...this._userSources.values()]);
|
|
294
326
|
}
|
|
295
327
|
async onBeforeInputAction(sdkObject, metadata) {}
|
|
296
328
|
async onCallLog(sdkObject, metadata, logName, message) {
|
|
297
329
|
this.updateCallLog([metadata]);
|
|
298
330
|
}
|
|
299
331
|
updateCallLog(metadatas) {
|
|
300
|
-
var _this$
|
|
301
|
-
if (this.
|
|
332
|
+
var _this$_recorderApp7;
|
|
333
|
+
if (this._isRecording()) return;
|
|
302
334
|
const logs = [];
|
|
303
335
|
for (const metadata of metadatas) {
|
|
304
336
|
if (!metadata.method || metadata.internal) continue;
|
|
@@ -307,7 +339,10 @@ class Recorder {
|
|
|
307
339
|
if (this._debugger.isPaused(metadata)) status = 'paused';
|
|
308
340
|
logs.push((0, _recorderUtils.metadataToCallLog)(metadata, status));
|
|
309
341
|
}
|
|
310
|
-
(_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);
|
|
311
346
|
}
|
|
312
347
|
_readSource(fileName) {
|
|
313
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'],
|
|
@@ -111,6 +115,35 @@ const DOWNLOAD_PATHS = {
|
|
|
111
115
|
'mac15-arm64': 'builds/chromium/%s/chromium-mac-arm64.zip',
|
|
112
116
|
'win64': 'builds/chromium/%s/chromium-win64.zip'
|
|
113
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
|
+
},
|
|
114
147
|
'chromium-tip-of-tree': {
|
|
115
148
|
'<unknown>': undefined,
|
|
116
149
|
'ubuntu18.04-x64': undefined,
|
|
@@ -313,7 +346,7 @@ const registryDirectory = exports.registryDirectory = (() => {
|
|
|
313
346
|
function isBrowserDirectory(browserDirectory) {
|
|
314
347
|
const baseName = _path.default.basename(browserDirectory);
|
|
315
348
|
for (const browserName of allDownloadable) {
|
|
316
|
-
if (baseName.startsWith(browserName + '-')) return true;
|
|
349
|
+
if (baseName.startsWith(browserName.replace(/-/g, '_') + '-')) return true;
|
|
317
350
|
}
|
|
318
351
|
return false;
|
|
319
352
|
}
|
|
@@ -326,6 +359,7 @@ function readDescriptors(browsersJSON) {
|
|
|
326
359
|
const descriptor = {
|
|
327
360
|
name,
|
|
328
361
|
revision,
|
|
362
|
+
hasRevisionOverride: !!revisionOverride,
|
|
329
363
|
// We only put browser version for the supported operating systems.
|
|
330
364
|
browserVersion: revisionOverride ? undefined : obj.browserVersion,
|
|
331
365
|
installByDefault: !!obj.installByDefault,
|
|
@@ -339,7 +373,7 @@ function readDescriptors(browsersJSON) {
|
|
|
339
373
|
return descriptor;
|
|
340
374
|
});
|
|
341
375
|
}
|
|
342
|
-
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'];
|
|
343
377
|
class Registry {
|
|
344
378
|
constructor(browsersJSON) {
|
|
345
379
|
this._executables = void 0;
|
|
@@ -372,13 +406,30 @@ class Registry {
|
|
|
372
406
|
executablePath: () => chromiumExecutable,
|
|
373
407
|
executablePathOrDie: sdkLanguage => executablePathOrDie('chromium', chromiumExecutable, chromium.installByDefault, sdkLanguage),
|
|
374
408
|
installType: chromium.installByDefault ? 'download-by-default' : 'download-on-demand',
|
|
375
|
-
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage,
|
|
409
|
+
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, chromium.dir, ['chrome-linux'], [], ['chrome-win']),
|
|
376
410
|
downloadURLs: this._downloadURLs(chromium),
|
|
377
411
|
browserVersion: chromium.browserVersion,
|
|
378
412
|
_install: () => this._downloadExecutable(chromium, chromiumExecutable),
|
|
379
413
|
_dependencyGroup: 'chromium',
|
|
380
414
|
_isHermeticInstallation: true
|
|
381
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
|
+
});
|
|
382
433
|
const chromiumTipOfTree = descriptors.find(d => d.name === 'chromium-tip-of-tree');
|
|
383
434
|
const chromiumTipOfTreeExecutable = findExecutablePath(chromiumTipOfTree.dir, 'chromium');
|
|
384
435
|
this._executables.push({
|
|
@@ -389,7 +440,7 @@ class Registry {
|
|
|
389
440
|
executablePath: () => chromiumTipOfTreeExecutable,
|
|
390
441
|
executablePathOrDie: sdkLanguage => executablePathOrDie('chromium-tip-of-tree', chromiumTipOfTreeExecutable, chromiumTipOfTree.installByDefault, sdkLanguage),
|
|
391
442
|
installType: chromiumTipOfTree.installByDefault ? 'download-by-default' : 'download-on-demand',
|
|
392
|
-
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage,
|
|
443
|
+
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, chromiumTipOfTree.dir, ['chrome-linux'], [], ['chrome-win']),
|
|
393
444
|
downloadURLs: this._downloadURLs(chromiumTipOfTree),
|
|
394
445
|
browserVersion: chromiumTipOfTree.browserVersion,
|
|
395
446
|
_install: () => this._downloadExecutable(chromiumTipOfTree, chromiumTipOfTreeExecutable),
|
|
@@ -489,7 +540,7 @@ class Registry {
|
|
|
489
540
|
executablePath: () => chromiumExecutable,
|
|
490
541
|
executablePathOrDie: sdkLanguage => executablePathOrDie('chromium', chromiumExecutable, chromium.installByDefault, sdkLanguage),
|
|
491
542
|
installType: 'download-on-demand',
|
|
492
|
-
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage,
|
|
543
|
+
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, chromium.dir, ['chrome-linux'], [], ['chrome-win']),
|
|
493
544
|
downloadURLs: this._downloadURLs(chromium),
|
|
494
545
|
browserVersion: chromium.browserVersion,
|
|
495
546
|
_install: () => this._downloadExecutable(chromium, chromiumExecutable),
|
|
@@ -506,7 +557,7 @@ class Registry {
|
|
|
506
557
|
executablePath: () => firefoxExecutable,
|
|
507
558
|
executablePathOrDie: sdkLanguage => executablePathOrDie('firefox', firefoxExecutable, firefox.installByDefault, sdkLanguage),
|
|
508
559
|
installType: firefox.installByDefault ? 'download-by-default' : 'download-on-demand',
|
|
509
|
-
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage,
|
|
560
|
+
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, firefox.dir, ['firefox'], [], ['firefox']),
|
|
510
561
|
downloadURLs: this._downloadURLs(firefox),
|
|
511
562
|
browserVersion: firefox.browserVersion,
|
|
512
563
|
_install: () => this._downloadExecutable(firefox, firefoxExecutable),
|
|
@@ -523,7 +574,7 @@ class Registry {
|
|
|
523
574
|
executablePath: () => firefoxBetaExecutable,
|
|
524
575
|
executablePathOrDie: sdkLanguage => executablePathOrDie('firefox-beta', firefoxBetaExecutable, firefoxBeta.installByDefault, sdkLanguage),
|
|
525
576
|
installType: firefoxBeta.installByDefault ? 'download-by-default' : 'download-on-demand',
|
|
526
|
-
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage,
|
|
577
|
+
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, firefoxBeta.dir, ['firefox'], [], ['firefox']),
|
|
527
578
|
downloadURLs: this._downloadURLs(firefoxBeta),
|
|
528
579
|
browserVersion: firefoxBeta.browserVersion,
|
|
529
580
|
_install: () => this._downloadExecutable(firefoxBeta, firefoxBetaExecutable),
|
|
@@ -541,7 +592,7 @@ class Registry {
|
|
|
541
592
|
executablePath: () => webkitExecutable,
|
|
542
593
|
executablePathOrDie: sdkLanguage => executablePathOrDie('webkit', webkitExecutable, webkit.installByDefault, sdkLanguage),
|
|
543
594
|
installType: webkit.installByDefault ? 'download-by-default' : 'download-on-demand',
|
|
544
|
-
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage,
|
|
595
|
+
_validateHostRequirements: sdkLanguage => this._validateHostRequirements(sdkLanguage, webkit.dir, webkitLinuxLddDirectories, ['libGLESv2.so.2', 'libx264.so'], ['']),
|
|
545
596
|
downloadURLs: this._downloadURLs(webkit),
|
|
546
597
|
browserVersion: webkit.browserVersion,
|
|
547
598
|
_install: () => this._downloadExecutable(webkit, webkitExecutable),
|
|
@@ -695,20 +746,15 @@ class Registry {
|
|
|
695
746
|
defaultExecutables() {
|
|
696
747
|
return this._executables.filter(e => e.installType === 'download-by-default');
|
|
697
748
|
}
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
for (const executable of executables) {
|
|
701
|
-
set.add(executable);
|
|
702
|
-
if (executable.browserName === 'chromium') set.add(this.findExecutable('ffmpeg'));
|
|
703
|
-
}
|
|
704
|
-
return Array.from(set);
|
|
749
|
+
_dedupe(executables) {
|
|
750
|
+
return Array.from(new Set(executables));
|
|
705
751
|
}
|
|
706
|
-
async _validateHostRequirements(sdkLanguage,
|
|
752
|
+
async _validateHostRequirements(sdkLanguage, browserDirectory, linuxLddDirectories, dlOpenLibraries, windowsExeAndDllDirectories) {
|
|
707
753
|
if (os.platform() === 'linux') return await (0, _dependencies.validateDependenciesLinux)(sdkLanguage, linuxLddDirectories.map(d => _path.default.join(browserDirectory, d)), dlOpenLibraries);
|
|
708
754
|
if (os.platform() === 'win32' && os.arch() === 'x64') return await (0, _dependencies.validateDependenciesWindows)(windowsExeAndDllDirectories.map(d => _path.default.join(browserDirectory, d)));
|
|
709
755
|
}
|
|
710
756
|
async installDeps(executablesToInstallDeps, dryRun) {
|
|
711
|
-
const executables = this.
|
|
757
|
+
const executables = this._dedupe(executablesToInstallDeps);
|
|
712
758
|
const targets = new Set();
|
|
713
759
|
for (const executable of executables) {
|
|
714
760
|
if (executable._dependencyGroup) targets.add(executable._dependencyGroup);
|
|
@@ -718,7 +764,7 @@ class Registry {
|
|
|
718
764
|
if (os.platform() === 'linux') return await (0, _dependencies.installDependenciesLinux)(targets, dryRun);
|
|
719
765
|
}
|
|
720
766
|
async install(executablesToInstall, forceReinstall) {
|
|
721
|
-
const executables = this.
|
|
767
|
+
const executables = this._dedupe(executablesToInstall);
|
|
722
768
|
await fs.promises.mkdir(registryDirectory, {
|
|
723
769
|
recursive: true
|
|
724
770
|
});
|
|
@@ -826,6 +872,11 @@ class Registry {
|
|
|
826
872
|
const downloadURLs = this._downloadURLs(descriptor);
|
|
827
873
|
if (!downloadURLs.length) throw new Error(`ERROR: Playwright does not support ${descriptor.name} on ${_hostPlatform.hostPlatform}`);
|
|
828
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
|
+
}
|
|
829
880
|
const displayName = descriptor.name.split('-').map(word => {
|
|
830
881
|
return word === 'ffmpeg' ? 'FFMPEG' : word.charAt(0).toUpperCase() + word.slice(1);
|
|
831
882
|
}).join(' ');
|
|
@@ -959,10 +1010,6 @@ function buildPlaywrightCLICommand(sdkLanguage, parameters) {
|
|
|
959
1010
|
}
|
|
960
1011
|
}
|
|
961
1012
|
}
|
|
962
|
-
async function installDefaultBrowsersForNpmInstall() {
|
|
963
|
-
const defaultBrowserNames = registry.defaultExecutables().map(e => e.name);
|
|
964
|
-
return installBrowsersForNpmInstall(defaultBrowserNames);
|
|
965
|
-
}
|
|
966
1013
|
async function installBrowsersForNpmInstall(browsers) {
|
|
967
1014
|
// PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD should have a value of 0 or 1
|
|
968
1015
|
if ((0, _utils.getAsBooleanFromENV)('PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD')) {
|