@checkly/playwright-core 1.41.23 → 1.41.25

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 (77) hide show
  1. package/lib/cli/driver.js +1 -9
  2. package/lib/cli/program.js +3 -11
  3. package/lib/client/channelOwner.js +1 -1
  4. package/lib/client/clientHelper.js +1 -5
  5. package/lib/client/connection.js +1 -1
  6. package/lib/client/consoleMessage.js +1 -1
  7. package/lib/client/electron.js +0 -3
  8. package/lib/client/events.js +0 -1
  9. package/lib/client/frame.js +1 -2
  10. package/lib/client/harRouter.js +1 -7
  11. package/lib/client/page.js +6 -25
  12. package/lib/common/debugLogger.js +0 -1
  13. package/lib/common/socksProxy.js +1 -1
  14. package/lib/generated/consoleApiSource.js +1 -1
  15. package/lib/generated/injectedScriptSource.js +1 -1
  16. package/lib/generated/recorderSource.js +1 -1
  17. package/lib/outofprocess.js +1 -1
  18. package/lib/protocol/validator.js +29 -46
  19. package/lib/remote/playwrightConnection.js +1 -1
  20. package/lib/remote/playwrightServer.js +166 -72
  21. package/lib/server/android/android.js +1 -1
  22. package/lib/server/browserType.js +2 -2
  23. package/lib/server/chromium/chromium.js +4 -5
  24. package/lib/server/chromium/crConnection.js +1 -1
  25. package/lib/server/chromium/crPage.js +2 -45
  26. package/lib/server/console.js +3 -1
  27. package/lib/server/debugController.js +3 -0
  28. package/lib/server/deviceDescriptorsSource.json +50 -50
  29. package/lib/server/dispatchers/browserContextDispatcher.js +2 -3
  30. package/lib/server/dispatchers/dispatcher.js +10 -9
  31. package/lib/server/dispatchers/electronDispatcher.js +0 -13
  32. package/lib/server/dispatchers/frameDispatcher.js +6 -0
  33. package/lib/server/dispatchers/pageDispatcher.js +10 -14
  34. package/lib/server/dom.js +167 -130
  35. package/lib/server/electron/electron.js +12 -38
  36. package/lib/server/electron/loader.js +2 -4
  37. package/lib/server/firefox/ffAccessibility.js +1 -2
  38. package/lib/server/firefox/ffConnection.js +1 -1
  39. package/lib/server/firefox/ffPage.js +1 -1
  40. package/lib/server/frames.js +20 -39
  41. package/lib/server/helper.js +1 -1
  42. package/lib/server/page.js +5 -49
  43. package/lib/server/pipeTransport.js +1 -1
  44. package/lib/server/playwright.js +1 -1
  45. package/lib/server/progress.js +11 -3
  46. package/lib/server/recorder/csharp.js +1 -1
  47. package/lib/server/recorder.js +1 -1
  48. package/lib/server/registry/browserFetcher.js +1 -1
  49. package/lib/server/registry/dependencies.js +4 -5
  50. package/lib/server/registry/index.js +30 -48
  51. package/lib/server/registry/nativeDeps.js +94 -0
  52. package/lib/server/trace/recorder/snapshotter.js +1 -1
  53. package/lib/server/trace/recorder/tracing.js +2 -5
  54. package/lib/server/trace/viewer/traceViewer.js +1 -1
  55. package/lib/server/transport.js +2 -4
  56. package/lib/server/webkit/wkConnection.js +1 -1
  57. package/lib/server/webkit/wkPage.js +2 -2
  58. package/lib/utils/comparators.js +4 -4
  59. package/lib/utils/fileUtils.js +0 -4
  60. package/lib/utils/hostPlatform.js +1 -1
  61. package/lib/utils/index.js +0 -11
  62. package/lib/utils/isomorphic/locatorParser.js +4 -6
  63. package/lib/utils/network.js +0 -33
  64. package/lib/utils/processLauncher.js +0 -7
  65. package/lib/vite/htmlReport/index.html +11 -11
  66. package/lib/vite/traceViewer/assets/codeMirrorModule-2mdjgmqe.js +24 -0
  67. package/lib/vite/traceViewer/assets/codeMirrorModule-GJA8DRmd.js +24 -0
  68. package/lib/vite/traceViewer/assets/wsPort-93o0i57c.js +69 -0
  69. package/lib/vite/traceViewer/assets/wsPort-qI0zJPR7.js +69 -0
  70. package/lib/vite/traceViewer/index.LR1HufLs.js +2 -0
  71. package/lib/vite/traceViewer/index.Ox-CymYJ.js +2 -0
  72. package/lib/vite/traceViewer/index.html +3 -3
  73. package/lib/vite/traceViewer/sw.bundle.js +4 -4
  74. package/lib/vite/traceViewer/uiMode.YGPXSUMv.js +10 -0
  75. package/lib/vite/traceViewer/uiMode.YYFJGvtV.js +10 -0
  76. package/lib/vite/traceViewer/uiMode.html +3 -3
  77. package/package.json +1 -1
@@ -429,6 +429,13 @@ _validatorPrimitives.scheme.DebugControllerSourceChangedEvent = (0, _validatorPr
429
429
  _validatorPrimitives.scheme.DebugControllerPausedEvent = (0, _validatorPrimitives.tObject)({
430
430
  paused: _validatorPrimitives.tBoolean
431
431
  });
432
+ _validatorPrimitives.scheme.DebugControllerBrowsersChangedEvent = (0, _validatorPrimitives.tObject)({
433
+ browsers: (0, _validatorPrimitives.tArray)((0, _validatorPrimitives.tObject)({
434
+ contexts: (0, _validatorPrimitives.tArray)((0, _validatorPrimitives.tObject)({
435
+ pages: (0, _validatorPrimitives.tArray)(_validatorPrimitives.tString)
436
+ }))
437
+ }))
438
+ });
432
439
  _validatorPrimitives.scheme.DebugControllerInitializeParams = (0, _validatorPrimitives.tObject)({
433
440
  codegenId: _validatorPrimitives.tString,
434
441
  sdkLanguage: (0, _validatorPrimitives.tEnum)(['javascript', 'python', 'java', 'csharp'])
@@ -812,6 +819,7 @@ _validatorPrimitives.scheme.BrowserContextBindingCallEvent = (0, _validatorPrimi
812
819
  binding: (0, _validatorPrimitives.tChannel)(['BindingCall'])
813
820
  });
814
821
  _validatorPrimitives.scheme.BrowserContextConsoleEvent = (0, _validatorPrimitives.tObject)({
822
+ page: (0, _validatorPrimitives.tChannel)(['Page']),
815
823
  type: _validatorPrimitives.tString,
816
824
  text: _validatorPrimitives.tString,
817
825
  args: (0, _validatorPrimitives.tArray)((0, _validatorPrimitives.tChannel)(['ElementHandle', 'JSHandle'])),
@@ -819,8 +827,7 @@ _validatorPrimitives.scheme.BrowserContextConsoleEvent = (0, _validatorPrimitive
819
827
  url: _validatorPrimitives.tString,
820
828
  lineNumber: _validatorPrimitives.tNumber,
821
829
  columnNumber: _validatorPrimitives.tNumber
822
- }),
823
- page: (0, _validatorPrimitives.tChannel)(['Page'])
830
+ })
824
831
  });
825
832
  _validatorPrimitives.scheme.BrowserContextCloseEvent = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
826
833
  _validatorPrimitives.scheme.BrowserContextDialogEvent = (0, _validatorPrimitives.tObject)({
@@ -1023,9 +1030,6 @@ _validatorPrimitives.scheme.PageFrameAttachedEvent = (0, _validatorPrimitives.tO
1023
1030
  _validatorPrimitives.scheme.PageFrameDetachedEvent = (0, _validatorPrimitives.tObject)({
1024
1031
  frame: (0, _validatorPrimitives.tChannel)(['Frame'])
1025
1032
  });
1026
- _validatorPrimitives.scheme.PageLocatorHandlerTriggeredEvent = (0, _validatorPrimitives.tObject)({
1027
- uid: _validatorPrimitives.tNumber
1028
- });
1029
1033
  _validatorPrimitives.scheme.PageRouteEvent = (0, _validatorPrimitives.tObject)({
1030
1034
  route: (0, _validatorPrimitives.tChannel)(['Route'])
1031
1035
  });
@@ -1081,16 +1085,6 @@ _validatorPrimitives.scheme.PageGoForwardParams = (0, _validatorPrimitives.tObje
1081
1085
  _validatorPrimitives.scheme.PageGoForwardResult = (0, _validatorPrimitives.tObject)({
1082
1086
  response: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tChannel)(['Response']))
1083
1087
  });
1084
- _validatorPrimitives.scheme.PageRegisterLocatorHandlerParams = (0, _validatorPrimitives.tObject)({
1085
- selector: _validatorPrimitives.tString
1086
- });
1087
- _validatorPrimitives.scheme.PageRegisterLocatorHandlerResult = (0, _validatorPrimitives.tObject)({
1088
- uid: _validatorPrimitives.tNumber
1089
- });
1090
- _validatorPrimitives.scheme.PageResolveLocatorHandlerNoReplyParams = (0, _validatorPrimitives.tObject)({
1091
- uid: _validatorPrimitives.tNumber
1092
- });
1093
- _validatorPrimitives.scheme.PageResolveLocatorHandlerNoReplyResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
1094
1088
  _validatorPrimitives.scheme.PageReloadParams = (0, _validatorPrimitives.tObject)({
1095
1089
  timeout: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tNumber),
1096
1090
  waitUntil: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tType)('LifecycleEvent'))
@@ -1106,22 +1100,26 @@ _validatorPrimitives.scheme.PageExpectScreenshotParams = (0, _validatorPrimitive
1106
1100
  frame: (0, _validatorPrimitives.tChannel)(['Frame']),
1107
1101
  selector: _validatorPrimitives.tString
1108
1102
  })),
1109
- comparator: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
1110
- maxDiffPixels: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tNumber),
1111
- maxDiffPixelRatio: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tNumber),
1112
- threshold: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tNumber),
1113
- fullPage: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tBoolean),
1114
- clip: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tType)('Rect')),
1115
- omitBackground: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tBoolean),
1116
- caret: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tEnum)(['hide', 'initial'])),
1117
- animations: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tEnum)(['disabled', 'allow'])),
1118
- scale: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tEnum)(['css', 'device'])),
1119
- mask: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tArray)((0, _validatorPrimitives.tObject)({
1120
- frame: (0, _validatorPrimitives.tChannel)(['Frame']),
1121
- selector: _validatorPrimitives.tString
1122
- }))),
1123
- maskColor: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
1124
- style: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString)
1103
+ comparatorOptions: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({
1104
+ comparator: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
1105
+ maxDiffPixels: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tNumber),
1106
+ maxDiffPixelRatio: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tNumber),
1107
+ threshold: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tNumber)
1108
+ })),
1109
+ screenshotOptions: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({
1110
+ fullPage: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tBoolean),
1111
+ clip: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tType)('Rect')),
1112
+ omitBackground: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tBoolean),
1113
+ caret: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tEnum)(['hide', 'initial'])),
1114
+ animations: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tEnum)(['disabled', 'allow'])),
1115
+ scale: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tEnum)(['css', 'device'])),
1116
+ mask: (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tArray)((0, _validatorPrimitives.tObject)({
1117
+ frame: (0, _validatorPrimitives.tChannel)(['Frame']),
1118
+ selector: _validatorPrimitives.tString
1119
+ }))),
1120
+ maskColor: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString),
1121
+ style: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tString)
1122
+ }))
1125
1123
  });
1126
1124
  _validatorPrimitives.scheme.PageExpectScreenshotResult = (0, _validatorPrimitives.tObject)({
1127
1125
  diff: (0, _validatorPrimitives.tOptional)(_validatorPrimitives.tBinary),
@@ -2301,16 +2299,6 @@ _validatorPrimitives.scheme.ElectronApplicationInitializer = (0, _validatorPrimi
2301
2299
  context: (0, _validatorPrimitives.tChannel)(['BrowserContext'])
2302
2300
  });
2303
2301
  _validatorPrimitives.scheme.ElectronApplicationCloseEvent = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
2304
- _validatorPrimitives.scheme.ElectronApplicationConsoleEvent = (0, _validatorPrimitives.tObject)({
2305
- type: _validatorPrimitives.tString,
2306
- text: _validatorPrimitives.tString,
2307
- args: (0, _validatorPrimitives.tArray)((0, _validatorPrimitives.tChannel)(['ElementHandle', 'JSHandle'])),
2308
- location: (0, _validatorPrimitives.tObject)({
2309
- url: _validatorPrimitives.tString,
2310
- lineNumber: _validatorPrimitives.tNumber,
2311
- columnNumber: _validatorPrimitives.tNumber
2312
- })
2313
- });
2314
2302
  _validatorPrimitives.scheme.ElectronApplicationBrowserWindowParams = (0, _validatorPrimitives.tObject)({
2315
2303
  page: (0, _validatorPrimitives.tChannel)(['Page'])
2316
2304
  });
@@ -2333,11 +2321,6 @@ _validatorPrimitives.scheme.ElectronApplicationEvaluateExpressionHandleParams =
2333
2321
  _validatorPrimitives.scheme.ElectronApplicationEvaluateExpressionHandleResult = (0, _validatorPrimitives.tObject)({
2334
2322
  handle: (0, _validatorPrimitives.tChannel)(['ElementHandle', 'JSHandle'])
2335
2323
  });
2336
- _validatorPrimitives.scheme.ElectronApplicationUpdateSubscriptionParams = (0, _validatorPrimitives.tObject)({
2337
- event: (0, _validatorPrimitives.tEnum)(['console']),
2338
- enabled: _validatorPrimitives.tBoolean
2339
- });
2340
- _validatorPrimitives.scheme.ElectronApplicationUpdateSubscriptionResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
2341
2324
  _validatorPrimitives.scheme.ElectronApplicationCloseParams = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
2342
2325
  _validatorPrimitives.scheme.ElectronApplicationCloseResult = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
2343
2326
  _validatorPrimitives.scheme.AndroidInitializer = (0, _validatorPrimitives.tOptional)((0, _validatorPrimitives.tObject)({}));
@@ -11,7 +11,7 @@ var _socksProxy = require("../common/socksProxy");
11
11
  var _utils = require("../utils");
12
12
  var _android = require("../server/android/android");
13
13
  var _debugControllerDispatcher = require("../server/dispatchers/debugControllerDispatcher");
14
- var _debugLogger = require("../utils/debugLogger");
14
+ var _debugLogger = require("../common/debugLogger");
15
15
  /**
16
16
  * Copyright (c) Microsoft Corporation.
17
17
  *
@@ -3,13 +3,14 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.PlaywrightServer = void 0;
6
+ exports.Semaphore = exports.PlaywrightServer = void 0;
7
+ var _utilsBundle = require("../utilsBundle");
7
8
  var _playwright = require("../server/playwright");
8
9
  var _playwrightConnection = require("./playwrightConnection");
9
- var _semaphore = require("../utils/semaphore");
10
- var _debugLogger = require("../utils/debugLogger");
10
+ var _manualPromise = require("../utils/manualPromise");
11
+ var _debugLogger = require("../common/debugLogger");
11
12
  var _utils = require("../utils");
12
- var _wsServer = require("../utils/wsServer");
13
+ var _transport = require("../server/transport");
13
14
  /**
14
15
  * Copyright (c) Microsoft Corporation.
15
16
  *
@@ -26,85 +27,178 @@ var _wsServer = require("../utils/wsServer");
26
27
  * limitations under the License.
27
28
  */
28
29
 
30
+ let lastConnectionId = 0;
31
+ const kConnectionSymbol = Symbol('kConnection');
29
32
  class PlaywrightServer {
30
33
  constructor(options) {
31
34
  this._preLaunchedPlaywright = void 0;
32
- this._options = void 0;
33
35
  this._wsServer = void 0;
36
+ this._server = void 0;
37
+ this._options = void 0;
34
38
  this._options = options;
35
39
  if (options.preLaunchedBrowser) this._preLaunchedPlaywright = options.preLaunchedBrowser.attribution.playwright;
36
40
  if (options.preLaunchedAndroidDevice) this._preLaunchedPlaywright = options.preLaunchedAndroidDevice._android.attribution.playwright;
37
- const browserSemaphore = new _semaphore.Semaphore(this._options.maxConnections);
38
- const controllerSemaphore = new _semaphore.Semaphore(1);
39
- const reuseBrowserSemaphore = new _semaphore.Semaphore(1);
40
- this._wsServer = new _wsServer.WSServer({
41
- onUpgrade: (request, socket) => {
42
- const uaError = (0, _utils.userAgentVersionMatchesErrorMessage)(request.headers['user-agent'] || '');
43
- if (uaError) return {
44
- error: `HTTP/${request.httpVersion} 428 Precondition Required\r\n\r\n${uaError}`
45
- };
46
- },
47
- onHeaders: headers => {
48
- if (process.env.PWTEST_SERVER_WS_HEADERS) headers.push(process.env.PWTEST_SERVER_WS_HEADERS);
49
- },
50
- onConnection: (request, url, ws, id) => {
51
- const browserHeader = request.headers['x-playwright-browser'];
52
- const browserName = url.searchParams.get('browser') || (Array.isArray(browserHeader) ? browserHeader[0] : browserHeader) || null;
53
- const proxyHeader = request.headers['x-playwright-proxy'];
54
- const proxyValue = url.searchParams.get('proxy') || (Array.isArray(proxyHeader) ? proxyHeader[0] : proxyHeader);
55
- const launchOptionsHeader = request.headers['x-playwright-launch-options'] || '';
56
- const launchOptionsHeaderValue = Array.isArray(launchOptionsHeader) ? launchOptionsHeader[0] : launchOptionsHeader;
57
- const launchOptionsParam = url.searchParams.get('launch-options');
58
- let launchOptions = {};
59
- try {
60
- launchOptions = JSON.parse(launchOptionsParam || launchOptionsHeaderValue);
61
- } catch (e) {}
62
-
63
- // Instantiate playwright for the extension modes.
64
- const isExtension = this._options.mode === 'extension';
65
- if (isExtension) {
66
- if (!this._preLaunchedPlaywright) this._preLaunchedPlaywright = (0, _playwright.createPlaywright)({
67
- sdkLanguage: 'javascript',
68
- isServer: true
69
- });
70
- }
71
- let clientType = 'launch-browser';
72
- let semaphore = browserSemaphore;
73
- if (isExtension && url.searchParams.has('debug-controller')) {
74
- clientType = 'controller';
75
- semaphore = controllerSemaphore;
76
- } else if (isExtension) {
77
- clientType = 'reuse-browser';
78
- semaphore = reuseBrowserSemaphore;
79
- } else if (this._options.mode === 'launchServer') {
80
- clientType = 'pre-launched-browser-or-android';
81
- semaphore = browserSemaphore;
41
+ }
42
+ async listen(port = 0, hostname) {
43
+ _debugLogger.debugLogger.log('server', `Server started at ${new Date()}`);
44
+ const server = (0, _utils.createHttpServer)((request, response) => {
45
+ if (request.method === 'GET' && request.url === '/json') {
46
+ response.setHeader('Content-Type', 'application/json');
47
+ response.end(JSON.stringify({
48
+ wsEndpointPath: this._options.path
49
+ }));
50
+ return;
51
+ }
52
+ response.end('Running');
53
+ });
54
+ server.on('error', error => _debugLogger.debugLogger.log('server', String(error)));
55
+ this._server = server;
56
+ const wsEndpoint = await new Promise((resolve, reject) => {
57
+ server.listen(port, hostname, () => {
58
+ const address = server.address();
59
+ if (!address) {
60
+ reject(new Error('Could not bind server socket'));
61
+ return;
82
62
  }
83
- return new _playwrightConnection.PlaywrightConnection(semaphore.acquire(), clientType, ws, {
84
- socksProxyPattern: proxyValue,
85
- browserName,
86
- launchOptions
87
- }, {
88
- playwright: this._preLaunchedPlaywright,
89
- browser: this._options.preLaunchedBrowser,
90
- androidDevice: this._options.preLaunchedAndroidDevice,
91
- socksProxy: this._options.preLaunchedSocksProxy
92
- }, id, () => semaphore.release());
93
- },
94
- onClose: async () => {
95
- _debugLogger.debugLogger.log('server', 'closing browsers');
96
- if (this._preLaunchedPlaywright) await Promise.all(this._preLaunchedPlaywright.allBrowsers().map(browser => browser.close({
97
- reason: 'Playwright Server stopped'
98
- })));
99
- _debugLogger.debugLogger.log('server', 'closed browsers');
63
+ const wsEndpoint = typeof address === 'string' ? `${address}${this._options.path}` : `ws://${hostname || 'localhost'}:${address.port}${this._options.path}`;
64
+ resolve(wsEndpoint);
65
+ }).on('error', reject);
66
+ });
67
+ _debugLogger.debugLogger.log('server', 'Listening at ' + wsEndpoint);
68
+ this._wsServer = new _utilsBundle.wsServer({
69
+ noServer: true,
70
+ perMessageDeflate: _transport.perMessageDeflate
71
+ });
72
+ const browserSemaphore = new Semaphore(this._options.maxConnections);
73
+ const controllerSemaphore = new Semaphore(1);
74
+ const reuseBrowserSemaphore = new Semaphore(1);
75
+ if (process.env.PWTEST_SERVER_WS_HEADERS) {
76
+ this._wsServer.on('headers', (headers, request) => {
77
+ headers.push(process.env.PWTEST_SERVER_WS_HEADERS);
78
+ });
79
+ }
80
+ server.on('upgrade', (request, socket, head) => {
81
+ var _this$_wsServer;
82
+ const pathname = new URL('http://localhost' + request.url).pathname;
83
+ if (pathname !== this._options.path) {
84
+ socket.write(`HTTP/${request.httpVersion} 400 Bad Request\r\n\r\n`);
85
+ socket.destroy();
86
+ return;
87
+ }
88
+ const uaError = (0, _utils.userAgentVersionMatchesErrorMessage)(request.headers['user-agent'] || '');
89
+ if (uaError) {
90
+ socket.write(`HTTP/${request.httpVersion} 428 Precondition Required\r\n\r\n${uaError}`);
91
+ socket.destroy();
92
+ return;
100
93
  }
94
+ (_this$_wsServer = this._wsServer) === null || _this$_wsServer === void 0 || _this$_wsServer.handleUpgrade(request, socket, head, ws => {
95
+ var _this$_wsServer2;
96
+ return (_this$_wsServer2 = this._wsServer) === null || _this$_wsServer2 === void 0 ? void 0 : _this$_wsServer2.emit('connection', ws, request);
97
+ });
101
98
  });
102
- }
103
- async listen(port = 0, hostname) {
104
- return this._wsServer.listen(port, hostname, this._options.path);
99
+ this._wsServer.on('connection', (ws, request) => {
100
+ _debugLogger.debugLogger.log('server', 'Connected client ws.extension=' + ws.extensions);
101
+ const url = new URL('http://localhost' + (request.url || ''));
102
+ const browserHeader = request.headers['x-playwright-browser'];
103
+ const browserName = url.searchParams.get('browser') || (Array.isArray(browserHeader) ? browserHeader[0] : browserHeader) || null;
104
+ const proxyHeader = request.headers['x-playwright-proxy'];
105
+ const proxyValue = url.searchParams.get('proxy') || (Array.isArray(proxyHeader) ? proxyHeader[0] : proxyHeader);
106
+ const launchOptionsHeader = request.headers['x-playwright-launch-options'] || '';
107
+ const launchOptionsHeaderValue = Array.isArray(launchOptionsHeader) ? launchOptionsHeader[0] : launchOptionsHeader;
108
+ const launchOptionsParam = url.searchParams.get('launch-options');
109
+ let launchOptions = {};
110
+ try {
111
+ launchOptions = JSON.parse(launchOptionsParam || launchOptionsHeaderValue);
112
+ } catch (e) {}
113
+ const id = String(++lastConnectionId);
114
+ _debugLogger.debugLogger.log('server', `[${id}] serving connection: ${request.url}`);
115
+
116
+ // Instantiate playwright for the extension modes.
117
+ const isExtension = this._options.mode === 'extension';
118
+ if (isExtension) {
119
+ if (!this._preLaunchedPlaywright) this._preLaunchedPlaywright = (0, _playwright.createPlaywright)({
120
+ sdkLanguage: 'javascript',
121
+ isServer: true
122
+ });
123
+ }
124
+ let clientType = 'launch-browser';
125
+ let semaphore = browserSemaphore;
126
+ if (isExtension && url.searchParams.has('debug-controller')) {
127
+ clientType = 'controller';
128
+ semaphore = controllerSemaphore;
129
+ } else if (isExtension) {
130
+ clientType = 'reuse-browser';
131
+ semaphore = reuseBrowserSemaphore;
132
+ } else if (this._options.mode === 'launchServer') {
133
+ clientType = 'pre-launched-browser-or-android';
134
+ semaphore = browserSemaphore;
135
+ }
136
+ const connection = new _playwrightConnection.PlaywrightConnection(semaphore.acquire(), clientType, ws, {
137
+ socksProxyPattern: proxyValue,
138
+ browserName,
139
+ launchOptions
140
+ }, {
141
+ playwright: this._preLaunchedPlaywright,
142
+ browser: this._options.preLaunchedBrowser,
143
+ androidDevice: this._options.preLaunchedAndroidDevice,
144
+ socksProxy: this._options.preLaunchedSocksProxy
145
+ }, id, () => semaphore.release());
146
+ ws[kConnectionSymbol] = connection;
147
+ });
148
+ return wsEndpoint;
105
149
  }
106
150
  async close() {
107
- await this._wsServer.close();
151
+ const server = this._wsServer;
152
+ if (!server) return;
153
+ _debugLogger.debugLogger.log('server', 'closing websocket server');
154
+ const waitForClose = new Promise(f => server.close(f));
155
+ // First disconnect all remaining clients.
156
+ await Promise.all(Array.from(server.clients).map(async ws => {
157
+ const connection = ws[kConnectionSymbol];
158
+ if (connection) await connection.close();
159
+ try {
160
+ ws.terminate();
161
+ } catch (e) {}
162
+ }));
163
+ await waitForClose;
164
+ _debugLogger.debugLogger.log('server', 'closing http server');
165
+ if (this._server) await new Promise(f => this._server.close(f));
166
+ this._wsServer = undefined;
167
+ this._server = undefined;
168
+ _debugLogger.debugLogger.log('server', 'closed server');
169
+ _debugLogger.debugLogger.log('server', 'closing browsers');
170
+ if (this._preLaunchedPlaywright) await Promise.all(this._preLaunchedPlaywright.allBrowsers().map(browser => browser.close({
171
+ reason: 'Playwright Server stopped'
172
+ })));
173
+ _debugLogger.debugLogger.log('server', 'closed browsers');
174
+ }
175
+ }
176
+ exports.PlaywrightServer = PlaywrightServer;
177
+ class Semaphore {
178
+ constructor(max) {
179
+ this._max = void 0;
180
+ this._acquired = 0;
181
+ this._queue = [];
182
+ this._max = max;
183
+ }
184
+ setMax(max) {
185
+ this._max = max;
186
+ }
187
+ acquire() {
188
+ const lock = new _manualPromise.ManualPromise();
189
+ this._queue.push(lock);
190
+ this._flush();
191
+ return lock;
192
+ }
193
+ release() {
194
+ --this._acquired;
195
+ this._flush();
196
+ }
197
+ _flush() {
198
+ while (this._acquired < this._max && this._queue.length) {
199
+ ++this._acquired;
200
+ this._queue.shift().resolve();
201
+ }
108
202
  }
109
203
  }
110
- exports.PlaywrightServer = PlaywrightServer;
204
+ exports.Semaphore = Semaphore;
@@ -16,7 +16,7 @@ var _progress = require("../progress");
16
16
  var _crBrowser = require("../chromium/crBrowser");
17
17
  var _helper = require("../helper");
18
18
  var _transport = require("../../protocol/transport");
19
- var _debugLogger = require("../../utils/debugLogger");
19
+ var _debugLogger = require("../../common/debugLogger");
20
20
  var _processLauncher = require("../../utils/processLauncher");
21
21
  var _timeoutSettings = require("../../common/timeoutSettings");
22
22
  var _instrumentation = require("../instrumentation");
@@ -17,7 +17,7 @@ var _timeoutSettings = require("../common/timeoutSettings");
17
17
  var _utils = require("../utils");
18
18
  var _fileUtils = require("../utils/fileUtils");
19
19
  var _helper = require("./helper");
20
- var _debugLogger = require("../utils/debugLogger");
20
+ var _debugLogger = require("../common/debugLogger");
21
21
  var _instrumentation = require("./instrumentation");
22
22
  var _manualPromise = require("../utils/manualPromise");
23
23
  var _protocolError = require("./protocolError");
@@ -164,7 +164,7 @@ class BrowserType extends _instrumentation.SdkObject {
164
164
  const registryExecutable = _registry.registry.findExecutable(options.channel || this._name);
165
165
  if (!registryExecutable || registryExecutable.browserName !== this._name) throw new Error(`Unsupported ${this._name} channel "${options.channel}"`);
166
166
  executable = registryExecutable.executablePathOrDie(this.attribution.playwright.options.sdkLanguage);
167
- await _registry.registry.validateHostRequirementsForExecutablesIfNeeded([registryExecutable], this.attribution.playwright.options.sdkLanguage);
167
+ await registryExecutable.validateHostRequirements(this.attribution.playwright.options.sdkLanguage);
168
168
  }
169
169
  const waitForWSEndpoint = options.useWebSocket || (_options$args = options.args) !== null && _options$args !== void 0 && _options$args.some(a => a.startsWith('--remote-debugging-port')) ? new _manualPromise.ManualPromise() : undefined;
170
170
  const waitForJuggler = this._name === 'firefox' ? new _manualPromise.ManualPromise() : undefined;
@@ -19,7 +19,7 @@ var _userAgent = require("../../utils/userAgent");
19
19
  var _ascii = require("../../utils/ascii");
20
20
  var _utils = require("../../utils");
21
21
  var _fileUtils = require("../../utils/fileUtils");
22
- var _debugLogger = require("../../utils/debugLogger");
22
+ var _debugLogger = require("../../common/debugLogger");
23
23
  var _progress = require("../progress");
24
24
  var _timeoutSettings = require("../../common/timeoutSettings");
25
25
  var _helper = require("../helper");
@@ -68,7 +68,7 @@ class Chromium extends _browserType.BrowserType {
68
68
  'User-Agent': (0, _userAgent.getUserAgent)()
69
69
  };else if (headersMap && !Object.keys(headersMap).some(key => key.toLowerCase() === 'user-agent')) headersMap['User-Agent'] = (0, _userAgent.getUserAgent)();
70
70
  const artifactsDir = await _fs.default.promises.mkdtemp(ARTIFACTS_FOLDER);
71
- const wsEndpoint = await urlToWSEndpoint(progress, endpointURL, headersMap);
71
+ const wsEndpoint = await urlToWSEndpoint(progress, endpointURL);
72
72
  progress.throwIfAborted();
73
73
  const chromeTransport = await _transport.WebSocketTransport.connect(progress, wsEndpoint, headersMap);
74
74
  const cleanedUp = new _manualPromise.ManualPromise();
@@ -305,13 +305,12 @@ class Chromium extends _browserType.BrowserType {
305
305
  }
306
306
  }
307
307
  exports.Chromium = Chromium;
308
- async function urlToWSEndpoint(progress, endpointURL, headers) {
308
+ async function urlToWSEndpoint(progress, endpointURL) {
309
309
  if (endpointURL.startsWith('ws')) return endpointURL;
310
310
  progress.log(`<ws preparing> retrieving websocket url from ${endpointURL}`);
311
311
  const httpURL = endpointURL.endsWith('/') ? `${endpointURL}json/version/` : `${endpointURL}/json/version/`;
312
312
  const json = await (0, _network.fetchData)({
313
- url: httpURL,
314
- headers
313
+ url: httpURL
315
314
  }, async (_, resp) => new Error(`Unexpected status ${resp.statusCode} when connecting to ${httpURL}.\n` + `This does not look like a DevTools server, try connecting via ws://.`));
316
315
  return JSON.parse(json).webSocketDebuggerUrl;
317
316
  }
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.kBrowserCloseMessageId = exports.ConnectionEvents = exports.CRSession = exports.CRConnection = exports.CDPSession = void 0;
7
7
  var _utils = require("../../utils");
8
8
  var _events = require("events");
9
- var _debugLogger = require("../../utils/debugLogger");
9
+ var _debugLogger = require("../../common/debugLogger");
10
10
  var _helper = require("../helper");
11
11
  var _protocolError = require("../protocolError");
12
12
  /**
@@ -970,8 +970,7 @@ class FrameSession {
970
970
  const options = this._crPage._browserContext._options;
971
971
  await this._client.send('Emulation.setUserAgentOverride', {
972
972
  userAgent: options.userAgent || '',
973
- acceptLanguage: options.locale,
974
- userAgentMetadata: calculateUserAgentMetadata(options)
973
+ acceptLanguage: options.locale
975
974
  });
976
975
  }
977
976
  async _setDefaultFontFamilies(session) {
@@ -1128,46 +1127,4 @@ async function emulateTimezone(session, timezoneId) {
1128
1127
  throw exception;
1129
1128
  }
1130
1129
  }
1131
- const contextDelegateSymbol = Symbol('delegate');
1132
-
1133
- // Chromium reference: https://source.chromium.org/chromium/chromium/src/+/main:components/embedder_support/user_agent_utils.cc;l=434;drc=70a6711e08e9f9e0d8e4c48e9ba5cab62eb010c2
1134
- function calculateUserAgentMetadata(options) {
1135
- const ua = options.userAgent;
1136
- if (!ua) return undefined;
1137
- const metadata = {
1138
- mobile: !!options.isMobile,
1139
- model: '',
1140
- architecture: 'x64',
1141
- platform: 'Windows',
1142
- platformVersion: ''
1143
- };
1144
- const androidMatch = ua.match(/Android (\d+(\.\d+)?(\.\d+)?)/);
1145
- const iPhoneMatch = ua.match(/iPhone OS (\d+(_\d+)?)/);
1146
- const iPadMatch = ua.match(/iPad; CPU OS (\d+(_\d+)?)/);
1147
- const macOSMatch = ua.match(/Mac OS X (\d+(_\d+)?(_\d+)?)/);
1148
- const windowsMatch = ua.match(/Windows\D+(\d+(\.\d+)?(\.\d+)?)/);
1149
- if (androidMatch) {
1150
- metadata.platform = 'Android';
1151
- metadata.platformVersion = androidMatch[1];
1152
- metadata.architecture = 'arm';
1153
- } else if (iPhoneMatch) {
1154
- metadata.platform = 'iOS';
1155
- metadata.platformVersion = iPhoneMatch[1];
1156
- metadata.architecture = 'arm';
1157
- } else if (iPadMatch) {
1158
- metadata.platform = 'iOS';
1159
- metadata.platformVersion = iPadMatch[1];
1160
- metadata.architecture = 'arm';
1161
- } else if (macOSMatch) {
1162
- metadata.platform = 'macOS';
1163
- metadata.platformVersion = macOSMatch[1];
1164
- if (!ua.includes('Intel')) metadata.architecture = 'arm';
1165
- } else if (windowsMatch) {
1166
- metadata.platform = 'Windows';
1167
- metadata.platformVersion = windowsMatch[1];
1168
- } else if (ua.toLowerCase().includes('linux')) {
1169
- metadata.platform = 'Linux';
1170
- }
1171
- if (ua.includes('ARM')) metadata.architecture = 'arm';
1172
- return metadata;
1173
- }
1130
+ const contextDelegateSymbol = Symbol('delegate');
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.ConsoleMessage = void 0;
7
+ var _instrumentation = require("./instrumentation");
7
8
  /**
8
9
  * Copyright (c) Microsoft Corporation.
9
10
  *
@@ -20,8 +21,9 @@ exports.ConsoleMessage = void 0;
20
21
  * limitations under the License.
21
22
  */
22
23
 
23
- class ConsoleMessage {
24
+ class ConsoleMessage extends _instrumentation.SdkObject {
24
25
  constructor(page, type, text, args, location) {
26
+ super(page, 'console-message');
25
27
  this._type = void 0;
26
28
  this._text = void 0;
27
29
  this._args = void 0;
@@ -160,6 +160,8 @@ class DebugController extends _instrumentation.SdkObject {
160
160
  pageCount += context.pages().length;
161
161
  }
162
162
  }
163
+ // TODO: browsers is deprecated, remove it.
164
+ this.emit(DebugController.Events.BrowsersChanged, browsers);
163
165
  this.emit(DebugController.Events.StateChanged, {
164
166
  pageCount
165
167
  });
@@ -187,6 +189,7 @@ class DebugController extends _instrumentation.SdkObject {
187
189
  }
188
190
  exports.DebugController = DebugController;
189
191
  DebugController.Events = {
192
+ BrowsersChanged: 'browsersChanged',
190
193
  StateChanged: 'stateChanged',
191
194
  InspectRequested: 'inspectRequested',
192
195
  SourceChanged: 'sourceChanged',