brave-real-playwright-core 1.56.1 → 1.57.0-patch.10

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 (97) hide show
  1. package/README.md +5 -5
  2. package/advanced-stealth.js +52 -79
  3. package/lib/cli/program.js +14 -57
  4. package/lib/client/api.js +0 -3
  5. package/lib/client/browserContext.js +22 -4
  6. package/lib/client/consoleMessage.js +5 -1
  7. package/lib/client/electron.js +1 -1
  8. package/lib/client/events.js +2 -1
  9. package/lib/client/locator.js +4 -1
  10. package/lib/client/page.js +2 -5
  11. package/lib/client/playwright.js +1 -5
  12. package/lib/client/tracing.js +6 -4
  13. package/lib/client/worker.js +22 -0
  14. package/lib/generated/clockSource.js +1 -1
  15. package/lib/generated/injectedScriptSource.js +1 -1
  16. package/lib/generated/pollingRecorderSource.js +1 -1
  17. package/lib/inProcessFactory.js +0 -2
  18. package/lib/protocol/validator.js +24 -46
  19. package/lib/server/android/android.js +1 -1
  20. package/lib/server/bidi/bidiBrowser.js +26 -11
  21. package/lib/server/bidi/bidiChromium.js +1 -1
  22. package/lib/server/bidi/bidiFirefox.js +1 -1
  23. package/lib/server/bidi/bidiPage.js +25 -5
  24. package/lib/server/browserContext.js +9 -10
  25. package/lib/server/chromium/chromium.js +12 -1
  26. package/lib/server/chromium/chromiumSwitches.js +11 -2
  27. package/lib/server/chromium/crBrowser.js +8 -0
  28. package/lib/server/chromium/crPage.js +7 -7
  29. package/lib/server/chromium/crServiceWorker.js +16 -5
  30. package/lib/server/chromium/videoRecorder.js +14 -12
  31. package/lib/server/console.js +5 -1
  32. package/lib/server/deviceDescriptorsSource.json +56 -56
  33. package/lib/server/dispatchers/browserContextDispatcher.js +23 -6
  34. package/lib/server/dispatchers/pageDispatcher.js +10 -22
  35. package/lib/server/dispatchers/playwrightDispatcher.js +0 -4
  36. package/lib/server/electron/electron.js +1 -1
  37. package/lib/server/firefox/ffPage.js +3 -6
  38. package/lib/server/firefox/firefox.js +12 -1
  39. package/lib/server/frameSelectors.js +2 -4
  40. package/lib/server/frames.js +10 -3
  41. package/lib/server/input.js +7 -3
  42. package/lib/server/localUtils.js +4 -8
  43. package/lib/server/page.js +54 -40
  44. package/lib/server/playwright.js +2 -4
  45. package/lib/server/recorder/recorderApp.js +1 -1
  46. package/lib/server/recorder.js +3 -2
  47. package/lib/server/registry/index.js +113 -47
  48. package/lib/server/registry/oopDownloadBrowserMain.js +6 -2
  49. package/lib/server/socksClientCertificatesInterceptor.js +1 -1
  50. package/lib/server/trace/recorder/tracing.js +2 -0
  51. package/lib/server/trace/viewer/traceViewer.js +37 -36
  52. package/lib/server/utils/comparators.js +3 -25
  53. package/lib/server/utils/hostPlatform.js +15 -3
  54. package/lib/server/utils/imageUtils.js +141 -0
  55. package/lib/server/utils/network.js +22 -16
  56. package/lib/server/webkit/webkit.js +1 -10
  57. package/lib/server/webkit/wkPage.js +1 -5
  58. package/lib/server/webkit/wkWorkers.js +2 -1
  59. package/lib/utils/isomorphic/ariaSnapshot.js +5 -0
  60. package/lib/utils/isomorphic/locatorGenerators.js +24 -8
  61. package/lib/utils/isomorphic/mimeType.js +1 -1
  62. package/lib/utils/isomorphic/protocolFormatter.js +3 -0
  63. package/lib/utils/isomorphic/protocolMetainfo.js +2 -1
  64. package/lib/utils/isomorphic/urlMatch.js +19 -5
  65. package/lib/utils.js +2 -0
  66. package/lib/utilsBundle.js +6 -3
  67. package/lib/utilsBundleImpl/index.js +171 -171
  68. package/lib/vite/htmlReport/index.html +18 -18
  69. package/lib/vite/recorder/assets/codeMirrorModule-BoWUGj0J.js +25 -0
  70. package/lib/vite/recorder/assets/{index-Y-X2TGJv.js → index-DJqDAOZp.js} +32 -32
  71. package/lib/vite/recorder/index.html +1 -1
  72. package/lib/vite/traceViewer/assets/codeMirrorModule-Bucv2d7q.js +25 -0
  73. package/lib/vite/traceViewer/assets/defaultSettingsView-BEpdCv1S.js +266 -0
  74. package/lib/vite/traceViewer/defaultSettingsView.ConWv5KN.css +1 -0
  75. package/lib/vite/traceViewer/index.BxQ34UMZ.js +2 -0
  76. package/lib/vite/traceViewer/index.C4Y3Aw8n.css +1 -0
  77. package/lib/vite/traceViewer/index.html +6 -6
  78. package/lib/vite/traceViewer/manifest.webmanifest +16 -0
  79. package/lib/vite/traceViewer/snapshot.html +3 -3
  80. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  81. package/lib/vite/traceViewer/{uiMode.DRQ310U5.js → uiMode.BWTwXl41.js} +3 -3
  82. package/lib/vite/traceViewer/uiMode.html +3 -3
  83. package/package.json +9 -9
  84. package/stealth-injection.js +51 -78
  85. package/lib/client/accessibility.js +0 -49
  86. package/lib/server/accessibility.js +0 -69
  87. package/lib/server/chromium/crAccessibility.js +0 -263
  88. package/lib/server/firefox/ffAccessibility.js +0 -238
  89. package/lib/server/webkit/wkAccessibility.js +0 -237
  90. package/lib/server/webkit/wsl/webkit-wsl-transport-client.js +0 -74
  91. package/lib/server/webkit/wsl/webkit-wsl-transport-server.js +0 -113
  92. package/lib/vite/recorder/assets/codeMirrorModule-RJCXzfmE.js +0 -24
  93. package/lib/vite/traceViewer/assets/codeMirrorModule-eyVcHN77.js +0 -24
  94. package/lib/vite/traceViewer/assets/defaultSettingsView-w0zYjHsW.js +0 -265
  95. package/lib/vite/traceViewer/defaultSettingsView.TQ8_7ybu.css +0 -1
  96. package/lib/vite/traceViewer/index.Bx16ehp1.js +0 -2
  97. package/lib/vite/traceViewer/index.I8N9v4jT.css +0 -1
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
- # 🦁 brave-real-playwright-core v1.56.1
1
+ # 🦁 brave-real-playwright-core v1.57.0-patch.10
2
2
 
3
- **Based on Playwright Core v1.56.1**
3
+ **Based on Playwright Core v1.57.0**
4
4
 
5
5
  **Brave Real-World Optimized Playwright Core with comprehensive stealth patches**
6
6
 
7
- This is a pre-patched version of **Playwright Core v1.56.1** optimized for maximum stealth when using Brave browser.
7
+ This is a pre-patched version of **Playwright Core v1.57.0** optimized for maximum stealth when using Brave browser.
8
8
 
9
9
  ## ✨ Features
10
10
 
@@ -46,9 +46,9 @@ await page.goto('https://bot-detector.rebrowser.net/');
46
46
 
47
47
  ## 📦 Based On
48
48
 
49
- - **playwright-core**: v1.56.1
49
+ - **playwright-core**: v1.57.0
50
50
  - **rebrowser-patches**: Latest stealth optimizations
51
- - **Brave optimization**: v1.56.1
51
+ - **Brave optimization**: v1.57.0-patch.10
52
52
 
53
53
  ## 🔗 Links
54
54
 
@@ -5,7 +5,7 @@
5
5
  timingRange: '1-5ms',
6
6
  stealthLevel: 'professional',
7
7
  engine: 'playwright',
8
- braveVersion: '1.56.1',
8
+ braveVersion: '1.57.0-patch.10',
9
9
  features: {
10
10
  performanceOptimization: true,
11
11
  navigatorSpoofing: true,
@@ -71,7 +71,7 @@
71
71
  return Promise.resolve({
72
72
  ok: true,
73
73
  json: () => Promise.resolve([{
74
- version: '129.0.0.0',
74
+ version: '144.0.7559.59',
75
75
  time: new Date().toISOString()
76
76
  }])
77
77
  });
@@ -107,16 +107,11 @@
107
107
  delete navigator.webdriver;
108
108
  }
109
109
 
110
- // Define webdriver as undefined and make it non-enumerable
111
- Object.defineProperty(navigator, 'webdriver', {
112
- get: () => undefined,
113
- set: () => {},
114
- configurable: false,
115
- enumerable: false
116
- });
110
+
111
+
117
112
 
118
113
  // Additional webdriver property variations
119
- const webdriverProps = ['webdriver', '__webdriver__', '_webdriver', 'webDriver'];
114
+ const webdriverProps = ['__webdriver__', '_webdriver', 'webDriver'];
120
115
  webdriverProps.forEach(prop => {
121
116
  if (prop in navigator) {
122
117
  delete navigator[prop];
@@ -485,29 +480,15 @@
485
480
 
486
481
  // 4. BULLETPROOF USER AGENT STEALTH
487
482
 
488
- // BULLETPROOF User Agent spoofing - BRAVE BROWSER DEFAULT
483
+ // BULLETPROOF User Agent spoofing - DYNAMIC VERSION: 144.0.7559.59
489
484
  (function() {
490
- // 🦁 AUTO-DETECT BROWSER TYPE FOR OPTIMIZED USER AGENT
491
- const isBraveOptimized = process.env.REBROWSER_STEALTH_BRAVE_OPTIMIZATIONS === '1' ||
492
- process.env.REBROWSER_AUTO_BROWSER_TYPE === 'brave';
493
- const isChromeOptimized = process.env.REBROWSER_STEALTH_CHROME_OPTIMIZATIONS === '1' ||
494
- process.env.REBROWSER_AUTO_BROWSER_TYPE === 'chrome';
485
+ // 🦁 DYNAMIC CHROME VERSION - Auto-synced with latest stable
486
+ const INJECTED_CHROME_VERSION = '144.0.7559.59';
487
+ const INJECTED_MAJOR_VERSION = '144';
495
488
 
496
- // Define optimized user agents based on detected browser
497
- let bulletproofUserAgent;
498
- if (isBraveOptimized) {
499
- // Brave-optimized user agent (maximum stealth)
500
- bulletproofUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36';
501
- console.log('[🦁 BRAVE-STEALTH] Brave browser optimizations active - maximum stealth mode');
502
- } else if (isChromeOptimized) {
503
- // Chrome-optimized user agent
504
- bulletproofUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36';
505
- console.log('[🔵 CHROME-STEALTH] Chrome browser optimizations active');
506
- } else {
507
- // Default fallback user agent
508
- bulletproofUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36';
509
- console.log('[⚙️ DEFAULT-STEALTH] Using default browser stealth mode');
510
- }
489
+ // Dynamic user agent with latest Chrome version
490
+ const bulletproofUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.7559.59 Safari/537.36';
491
+ console.log('[🎯 DYNAMIC-STEALTH] Using Chrome version: ' + INJECTED_CHROME_VERSION);
511
492
 
512
493
  // COMPLETELY override navigator.userAgent
513
494
  Object.defineProperty(navigator, 'userAgent', {
@@ -518,43 +499,11 @@
518
499
 
519
500
  // COMPLETELY override appVersion
520
501
  Object.defineProperty(navigator, 'appVersion', {
521
- get: () => '5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
502
+ get: () => '5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.7559.59 Safari/537.36',
522
503
  configurable: false,
523
504
  enumerable: true
524
505
  });
525
506
 
526
- // BULLETPROOF webdriver property elimination
527
- if ('webdriver' in navigator) {
528
- delete navigator.webdriver;
529
- }
530
-
531
- // PREVENT webdriver property from being redefined
532
- Object.defineProperty(navigator, 'webdriver', {
533
- get: () => undefined,
534
- set: () => {},
535
- configurable: false,
536
- enumerable: false
537
- });
538
-
539
- // OVERRIDE Object.getOwnPropertyDescriptor to hide our modifications
540
- const originalGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
541
- Object.getOwnPropertyDescriptor = function(obj, prop) {
542
- if (obj === navigator && prop === 'webdriver') {
543
- return undefined;
544
- }
545
- return originalGetOwnPropertyDescriptor.call(this, obj, prop);
546
- };
547
-
548
- // OVERRIDE Object.getOwnPropertyNames to hide webdriver
549
- const originalGetOwnPropertyNames = Object.getOwnPropertyNames;
550
- Object.getOwnPropertyNames = function(obj) {
551
- const props = originalGetOwnPropertyNames.call(this, obj);
552
- if (obj === navigator) {
553
- return props.filter(prop => prop !== 'webdriver');
554
- }
555
- return props;
556
- };
557
-
558
507
  // BULLETPROOF platform detection
559
508
  Object.defineProperty(navigator, 'platform', {
560
509
  get: () => 'Win32',
@@ -587,13 +536,26 @@
587
536
  });
588
537
  })();
589
538
 
590
- // Enhanced userAgentData with getHighEntropyValues method
591
- Object.defineProperty(navigator, 'userAgentData', {
592
- get: () => ({
539
+ // Enhanced userAgentData with getHighEntropyValues method - DYNAMIC VERSION
540
+ (function() {
541
+ const INJECTED_CHROME_VERSION = '144.0.7559.59';
542
+ const INJECTED_MAJOR_VERSION = '144';
543
+
544
+ // Aggressively delete existing userAgentData
545
+ try {
546
+ delete Navigator.prototype.userAgentData;
547
+ } catch {}
548
+ try {
549
+ if (navigator.hasOwnProperty('userAgentData')) {
550
+ delete navigator.userAgentData;
551
+ }
552
+ } catch {}
553
+
554
+ const userAgentDataInstance = {
593
555
  brands: [
594
- { brand: 'Not_A Brand', version: '8' },
595
- { brand: 'Chromium', version: '140' },
596
- { brand: 'Google Chrome', version: '140' }
556
+ { brand: 'Not_A Brand', version: '24' },
557
+ { brand: 'Chromium', version: INJECTED_MAJOR_VERSION },
558
+ { brand: 'Google Chrome', version: INJECTED_MAJOR_VERSION }
597
559
  ],
598
560
  mobile: false,
599
561
  platform: 'Windows',
@@ -601,23 +563,34 @@
601
563
  return Promise.resolve({
602
564
  architecture: 'x86',
603
565
  bitness: '64',
604
- brands: this.brands,
566
+ brands: userAgentDataInstance.brands,
605
567
  fullVersionList: [
606
- { brand: 'Not_A Brand', version: '8.0.0.0' },
607
- { brand: 'Chromium', version: '140.0.7339.81' },
608
- { brand: 'Google Chrome', version: '140.0.7339.81' }
568
+ { brand: 'Not_A Brand', version: INJECTED_CHROME_VERSION },
569
+ { brand: 'Chromium', version: INJECTED_CHROME_VERSION },
570
+ { brand: 'Google Chrome', version: INJECTED_CHROME_VERSION }
609
571
  ],
610
572
  mobile: false,
611
573
  model: '',
612
574
  platform: 'Windows',
613
575
  platformVersion: '10.0.0',
614
- uaFullVersion: '140.0.7339.81'
576
+ uaFullVersion: INJECTED_CHROME_VERSION
615
577
  });
578
+ },
579
+ toJSON: function() {
580
+ return {
581
+ brands: this.brands,
582
+ mobile: this.mobile,
583
+ platform: this.platform
584
+ };
616
585
  }
617
- }),
618
- configurable: true,
619
- enumerable: false
620
- });
586
+ };
587
+
588
+ Object.defineProperty(Navigator.prototype, 'userAgentData', {
589
+ get: () => userAgentDataInstance,
590
+ configurable: false,
591
+ enumerable: true
592
+ });
593
+ })();
621
594
 
622
595
 
623
596
  console.log('[REBROWSER-STEALTH] ✅ Ultra-fast professional stealth mode activated');
@@ -72,47 +72,6 @@ Examples:
72
72
  $ codegen
73
73
  $ codegen --target=python
74
74
  $ codegen -b webkit https://example.com`);
75
- function suggestedBrowsersToInstall() {
76
- return import_server.registry.executables().filter((e) => e.installType !== "none" && e.type !== "tool").map((e) => e.name).join(", ");
77
- }
78
- function defaultBrowsersToInstall(options) {
79
- let executables = import_server.registry.defaultExecutables();
80
- if (options.noShell)
81
- executables = executables.filter((e) => e.name !== "chromium-headless-shell");
82
- if (options.onlyShell)
83
- executables = executables.filter((e) => e.name !== "chromium");
84
- return executables;
85
- }
86
- function checkBrowsersToInstall(args, options) {
87
- if (options.noShell && options.onlyShell)
88
- throw new Error(`Only one of --no-shell and --only-shell can be specified`);
89
- const faultyArguments = [];
90
- const executables = [];
91
- const handleArgument = (arg) => {
92
- const executable = import_server.registry.findExecutable(arg);
93
- if (!executable || executable.installType === "none")
94
- faultyArguments.push(arg);
95
- else
96
- executables.push(executable);
97
- if (executable?.browserName === "chromium")
98
- executables.push(import_server.registry.findExecutable("ffmpeg"));
99
- };
100
- for (const arg of args) {
101
- if (arg === "chromium") {
102
- if (!options.onlyShell)
103
- handleArgument("chromium");
104
- if (!options.noShell)
105
- handleArgument("chromium-headless-shell");
106
- } else {
107
- handleArgument(arg);
108
- }
109
- }
110
- if (process.platform === "win32")
111
- executables.push(import_server.registry.findExecutable("winldd"));
112
- if (faultyArguments.length)
113
- throw new Error(`Invalid installation targets: ${faultyArguments.map((name) => `'${name}'`).join(", ")}. Expecting one of: ${suggestedBrowsersToInstall()}`);
114
- return executables;
115
- }
116
75
  function printInstalledBrowsers(browsers2) {
117
76
  const browserPaths = /* @__PURE__ */ new Set();
118
77
  for (const browser of browsers2)
@@ -166,8 +125,6 @@ Playwright version: ${version}`);
166
125
  }
167
126
  }
168
127
  import_utilsBundle.program.command("install [browser...]").description("ensure browsers necessary for this version of Playwright are installed").option("--with-deps", "install system dependencies for browsers").option("--dry-run", "do not execute installation, only print information").option("--list", "prints list of browsers from all playwright installations").option("--force", "force reinstall of stable browser channels").option("--only-shell", "only install headless shell when installing chromium").option("--no-shell", "do not install chromium headless shell").action(async function(args, options) {
169
- if (options.shell === false)
170
- options.noShell = true;
171
128
  if ((0, import_utils.isLikelyNpxGlobal)()) {
172
129
  console.error((0, import_ascii.wrapInASCIIBox)([
173
130
  `WARNING: It looks like you are running 'npx playwright install' without first`,
@@ -189,8 +146,10 @@ import_utilsBundle.program.command("install [browser...]").description("ensure b
189
146
  ].join("\n"), 1));
190
147
  }
191
148
  try {
192
- const hasNoArguments = !args.length;
193
- const executables = hasNoArguments ? defaultBrowsersToInstall(options) : checkBrowsersToInstall(args, options);
149
+ if (options.shell === false && options.onlyShell)
150
+ throw new Error(`Only one of --no-shell and --only-shell can be specified`);
151
+ const shell = options.shell === false ? "no" : options.onlyShell ? "only" : void 0;
152
+ const executables = import_server.registry.resolveBrowsers(args, { shell });
194
153
  if (options.withDeps)
195
154
  await import_server.registry.installDeps(executables, !!options.dryRun);
196
155
  if (options.dryRun && options.list)
@@ -212,8 +171,8 @@ import_utilsBundle.program.command("install [browser...]").description("ensure b
212
171
  const browsers2 = await import_server.registry.listInstalledBrowsers();
213
172
  printGroupedByPlaywrightVersion(browsers2);
214
173
  } else {
215
- const forceReinstall = hasNoArguments ? false : !!options.force;
216
- await import_server.registry.install(executables, forceReinstall);
174
+ const force = args.length === 0 ? false : !!options.force;
175
+ await import_server.registry.install(executables, { force });
217
176
  await import_server.registry.validateHostRequirementsForExecutablesIfNeeded(executables, process.env.PW_LANG_NAME || "javascript").catch((e) => {
218
177
  e.name = "Playwright Host validation warning";
219
178
  console.error(e);
@@ -231,7 +190,7 @@ Examples:
231
190
  Install default browsers.
232
191
 
233
192
  - $ install chrome firefox
234
- Install custom browsers, supports ${suggestedBrowsersToInstall()}.`);
193
+ Install custom browsers, supports ${import_server.registry.suggestedBrowsersToInstall()}.`);
235
194
  import_utilsBundle.program.command("uninstall").description("Removes browsers used by this installation of Playwright from the system (chromium, firefox, webkit, ffmpeg). This does not include branded channels.").option("--all", "Removes all browsers used by any Playwright installation from the system.").action(async (options) => {
236
195
  delete process.env.PLAYWRIGHT_SKIP_BROWSER_GC;
237
196
  await import_server.registry.uninstall(!!options.all).then(({ numberOfBrowsersLeft }) => {
@@ -244,10 +203,7 @@ To uninstall Playwright browsers for all installations, re-run with --all flag.`
244
203
  });
245
204
  import_utilsBundle.program.command("install-deps [browser...]").description("install dependencies necessary to run browsers (will ask for sudo permissions)").option("--dry-run", "Do not execute installation commands, only print them").action(async function(args, options) {
246
205
  try {
247
- if (!args.length)
248
- await import_server.registry.installDeps(defaultBrowsersToInstall({}), !!options.dryRun);
249
- else
250
- await import_server.registry.installDeps(checkBrowsersToInstall(args, {}), !!options.dryRun);
206
+ await import_server.registry.installDeps(import_server.registry.resolveBrowsers(args, {}), !!options.dryRun);
251
207
  } catch (e) {
252
208
  console.log(`Failed to install browser dependencies
253
209
  ${e}`);
@@ -259,7 +215,7 @@ Examples:
259
215
  Install dependencies for default browsers.
260
216
 
261
217
  - $ install-deps chrome firefox
262
- Install dependencies for specific browsers, supports ${suggestedBrowsersToInstall()}.`);
218
+ Install dependencies for specific browsers, supports ${import_server.registry.suggestedBrowsersToInstall()}.`);
263
219
  const browsers = [
264
220
  { alias: "cr", name: "Chromium", type: "chromium" },
265
221
  { alias: "ff", name: "Firefox", type: "firefox" },
@@ -304,7 +260,7 @@ Examples:
304
260
  import_utilsBundle.program.command("run-driver", { hidden: true }).action(function(options) {
305
261
  (0, import_driver.runDriver)();
306
262
  });
307
- import_utilsBundle.program.command("run-server").option("--port <port>", "Server port").option("--host <host>", "Server host").option("--path <path>", "Endpoint Path", "/").option("--max-clients <maxClients>", "Maximum clients").option("--mode <mode>", 'Server mode, either "default" or "extension"').action(function(options) {
263
+ import_utilsBundle.program.command("run-server", { hidden: true }).option("--port <port>", "Server port").option("--host <host>", "Server host").option("--path <path>", "Endpoint Path", "/").option("--max-clients <maxClients>", "Maximum clients").option("--mode <mode>", 'Server mode, either "default" or "extension"').action(function(options) {
308
264
  (0, import_driver.runServer)({
309
265
  port: options.port ? +options.port : void 0,
310
266
  host: options.host,
@@ -319,7 +275,7 @@ import_utilsBundle.program.command("print-api-json", { hidden: true }).action(fu
319
275
  import_utilsBundle.program.command("launch-server", { hidden: true }).requiredOption("--browser <browserName>", 'Browser name, one of "chromium", "firefox" or "webkit"').option("--config <path-to-config-file>", "JSON file with launchServer options").action(function(options) {
320
276
  (0, import_driver.launchBrowserServer)(options.browser, options.config);
321
277
  });
322
- import_utilsBundle.program.command("show-trace [trace...]").option("-b, --browser <browserType>", "browser to use, one of cr, chromium, ff, firefox, wk, webkit", "chromium").option("-h, --host <host>", "Host to serve trace on; specifying this option opens trace in a browser tab").option("-p, --port <port>", "Port to serve trace on, 0 for any free port; specifying this option opens trace in a browser tab").option("--stdin", "Accept trace URLs over stdin to update the viewer").description("show trace viewer").action(function(traces, options) {
278
+ import_utilsBundle.program.command("show-trace [trace]").option("-b, --browser <browserType>", "browser to use, one of cr, chromium, ff, firefox, wk, webkit", "chromium").option("-h, --host <host>", "Host to serve trace on; specifying this option opens trace in a browser tab").option("-p, --port <port>", "Port to serve trace on, 0 for any free port; specifying this option opens trace in a browser tab").option("--stdin", "Accept trace URLs over stdin to update the viewer").description("show trace viewer").action(function(trace, options) {
323
279
  if (options.browser === "cr")
324
280
  options.browser = "chromium";
325
281
  if (options.browser === "ff")
@@ -332,12 +288,13 @@ import_utilsBundle.program.command("show-trace [trace...]").option("-b, --browse
332
288
  isServer: !!options.stdin
333
289
  };
334
290
  if (options.port !== void 0 || options.host !== void 0)
335
- (0, import_traceViewer.runTraceInBrowser)(traces, openOptions).catch(logErrorAndExit);
291
+ (0, import_traceViewer.runTraceInBrowser)(trace, openOptions).catch(logErrorAndExit);
336
292
  else
337
- (0, import_traceViewer.runTraceViewerApp)(traces, options.browser, openOptions, true).catch(logErrorAndExit);
293
+ (0, import_traceViewer.runTraceViewerApp)(trace, options.browser, openOptions, true).catch(logErrorAndExit);
338
294
  }).addHelpText("afterAll", `
339
295
  Examples:
340
296
 
297
+ $ show-trace
341
298
  $ show-trace https://example.com/trace.zip`);
342
299
  async function launchContext(options, extraOptions) {
343
300
  validateOptions(options);
package/lib/client/api.js CHANGED
@@ -21,7 +21,6 @@ __export(api_exports, {
21
21
  APIRequest: () => import_fetch.APIRequest,
22
22
  APIRequestContext: () => import_fetch.APIRequestContext,
23
23
  APIResponse: () => import_fetch.APIResponse,
24
- Accessibility: () => import_accessibility.Accessibility,
25
24
  Android: () => import_android.Android,
26
25
  AndroidDevice: () => import_android.AndroidDevice,
27
26
  AndroidInput: () => import_android.AndroidInput,
@@ -62,7 +61,6 @@ __export(api_exports, {
62
61
  Worker: () => import_worker.Worker
63
62
  });
64
63
  module.exports = __toCommonJS(api_exports);
65
- var import_accessibility = require("./accessibility");
66
64
  var import_android = require("./android");
67
65
  var import_browser = require("./browser");
68
66
  var import_browserContext = require("./browserContext");
@@ -95,7 +93,6 @@ var import_webError = require("./webError");
95
93
  APIRequest,
96
94
  APIRequestContext,
97
95
  APIResponse,
98
- Accessibility,
99
96
  Android,
100
97
  AndroidDevice,
101
98
  AndroidInput,
@@ -89,11 +89,19 @@ class BrowserContext extends import_channelOwner.ChannelOwner {
89
89
  this.emit(import_events.Events.BrowserContext.ServiceWorker, serviceWorker);
90
90
  });
91
91
  this._channel.on("console", (event) => {
92
- const consoleMessage = new import_consoleMessage.ConsoleMessage(this._platform, event, import_page.Page.fromNullable(event.page));
92
+ const worker = import_worker.Worker.fromNullable(event.worker);
93
+ const page = import_page.Page.fromNullable(event.page);
94
+ const consoleMessage = new import_consoleMessage.ConsoleMessage(this._platform, event, page, worker);
95
+ worker?.emit(import_events.Events.Worker.Console, consoleMessage);
96
+ page?.emit(import_events.Events.Page.Console, consoleMessage);
97
+ if (worker && this._serviceWorkers.has(worker)) {
98
+ const scope = this._serviceWorkerScope(worker);
99
+ for (const page2 of this._pages) {
100
+ if (scope && page2.url().startsWith(scope))
101
+ page2.emit(import_events.Events.Page.Console, consoleMessage);
102
+ }
103
+ }
93
104
  this.emit(import_events.Events.BrowserContext.Console, consoleMessage);
94
- const page = consoleMessage.page();
95
- if (page)
96
- page.emit(import_events.Events.Page.Console, consoleMessage);
97
105
  });
98
106
  this._channel.on("pageError", ({ error, page }) => {
99
107
  const pageObject = import_page.Page.from(page);
@@ -230,6 +238,16 @@ class BrowserContext extends import_channelOwner.ChannelOwner {
230
238
  return;
231
239
  await bindingCall.call(func);
232
240
  }
241
+ _serviceWorkerScope(serviceWorker) {
242
+ try {
243
+ let url = new URL(".", serviceWorker.url()).href;
244
+ if (!url.endsWith("/"))
245
+ url += "/";
246
+ return url;
247
+ } catch {
248
+ return null;
249
+ }
250
+ }
233
251
  setDefaultNavigationTimeout(timeout) {
234
252
  this._timeoutSettings.setDefaultNavigationTimeout(timeout);
235
253
  }
@@ -23,12 +23,16 @@ __export(consoleMessage_exports, {
23
23
  module.exports = __toCommonJS(consoleMessage_exports);
24
24
  var import_jsHandle = require("./jsHandle");
25
25
  class ConsoleMessage {
26
- constructor(platform, event, page) {
26
+ constructor(platform, event, page, worker) {
27
27
  this._page = page;
28
+ this._worker = worker;
28
29
  this._event = event;
29
30
  if (platform.inspectCustom)
30
31
  this[platform.inspectCustom] = () => this._inspect();
31
32
  }
33
+ worker() {
34
+ return this._worker;
35
+ }
32
36
  page() {
33
37
  return this._page;
34
38
  }
@@ -66,7 +66,7 @@ class ElectronApplication extends import_channelOwner.ChannelOwner {
66
66
  this._channel.on("close", () => {
67
67
  this.emit(import_events.Events.ElectronApplication.Close);
68
68
  });
69
- this._channel.on("console", (event) => this.emit(import_events.Events.ElectronApplication.Console, new import_consoleMessage.ConsoleMessage(this._platform, event, null)));
69
+ this._channel.on("console", (event) => this.emit(import_events.Events.ElectronApplication.Console, new import_consoleMessage.ConsoleMessage(this._platform, event, null, null)));
70
70
  this._setEventToSubscriptionMapping(/* @__PURE__ */ new Map([
71
71
  [import_events.Events.ElectronApplication.Console, "console"]
72
72
  ]));
@@ -85,7 +85,8 @@ const Events = {
85
85
  FrameSent: "framesent"
86
86
  },
87
87
  Worker: {
88
- Close: "close"
88
+ Close: "close",
89
+ Console: "console"
89
90
  },
90
91
  ElectronApplication: {
91
92
  Close: "close",
@@ -167,6 +167,9 @@ class Locator {
167
167
  describe(description) {
168
168
  return new Locator(this._frame, this._selector + " >> internal:describe=" + JSON.stringify(description));
169
169
  }
170
+ description() {
171
+ return (0, import_locatorGenerators.locatorCustomDescription)(this._selector) || null;
172
+ }
170
173
  first() {
171
174
  return new Locator(this._frame, this._selector + " >> nth=0");
172
175
  }
@@ -298,7 +301,7 @@ class Locator {
298
301
  return this.toString();
299
302
  }
300
303
  toString() {
301
- return (0, import_locatorGenerators.asLocator)("javascript", this._selector);
304
+ return (0, import_locatorGenerators.asLocatorDescription)("javascript", this._selector);
302
305
  }
303
306
  }
304
307
  class FrameLocator {
@@ -22,7 +22,6 @@ __export(page_exports, {
22
22
  Page: () => Page
23
23
  });
24
24
  module.exports = __toCommonJS(page_exports);
25
- var import_accessibility = require("./accessibility");
26
25
  var import_artifact = require("./artifact");
27
26
  var import_channelOwner = require("./channelOwner");
28
27
  var import_clientHelper = require("./clientHelper");
@@ -65,7 +64,6 @@ class Page extends import_channelOwner.ChannelOwner {
65
64
  this._locatorHandlers = /* @__PURE__ */ new Map();
66
65
  this._browserContext = parent;
67
66
  this._timeoutSettings = new import_timeoutSettings.TimeoutSettings(this._platform, this._browserContext._timeoutSettings);
68
- this.accessibility = new import_accessibility.Accessibility(this._channel);
69
67
  this.keyboard = new import_input.Keyboard(this);
70
68
  this.mouse = new import_input.Mouse(this);
71
69
  this.request = this._browserContext.request;
@@ -536,7 +534,7 @@ class Page extends import_channelOwner.ChannelOwner {
536
534
  }
537
535
  async consoleMessages() {
538
536
  const { messages } = await this._channel.consoleMessages();
539
- return messages.map((message) => new import_consoleMessage.ConsoleMessage(this._platform, message, this));
537
+ return messages.map((message) => new import_consoleMessage.ConsoleMessage(this._platform, message, this, null));
540
538
  }
541
539
  async pageErrors() {
542
540
  const { errors } = await this._channel.pageErrors();
@@ -676,8 +674,7 @@ class Page extends import_channelOwner.ChannelOwner {
676
674
  return result.pdf;
677
675
  }
678
676
  async _snapshotForAI(options = {}) {
679
- const result = await this._channel.snapshotForAI({ timeout: this._timeoutSettings.timeout(options) });
680
- return result.snapshot;
677
+ return await this._channel.snapshotForAI({ timeout: this._timeoutSettings.timeout(options), track: options.track });
681
678
  }
682
679
  }
683
680
  class BindingCall extends import_channelOwner.ChannelOwner {
@@ -43,10 +43,6 @@ class Playwright extends import_channelOwner.ChannelOwner {
43
43
  this._android._playwright = this;
44
44
  this._electron = import_electron.Electron.from(initializer.electron);
45
45
  this._electron._playwright = this;
46
- this._bidiChromium = import_browserType.BrowserType.from(initializer._bidiChromium);
47
- this._bidiChromium._playwright = this;
48
- this._bidiFirefox = import_browserType.BrowserType.from(initializer._bidiFirefox);
49
- this._bidiFirefox._playwright = this;
50
46
  this.devices = this._connection.localUtils()?.devices ?? {};
51
47
  this.selectors = new import_selectors.Selectors(this._connection._platform);
52
48
  this.errors = { TimeoutError: import_errors.TimeoutError };
@@ -55,7 +51,7 @@ class Playwright extends import_channelOwner.ChannelOwner {
55
51
  return channel._object;
56
52
  }
57
53
  _browserTypes() {
58
- return [this.chromium, this.firefox, this.webkit, this._bidiChromium, this._bidiFirefox];
54
+ return [this.chromium, this.firefox, this.webkit];
59
55
  }
60
56
  _preLaunchedBrowser() {
61
57
  const browser = import_browser.Browser.from(this._initializer.preLaunchedBrowser);
@@ -27,6 +27,7 @@ class Tracing extends import_channelOwner.ChannelOwner {
27
27
  constructor(parent, type, guid, initializer) {
28
28
  super(parent, type, guid, initializer);
29
29
  this._includeSources = false;
30
+ this._isLive = false;
30
31
  this._isTracing = false;
31
32
  }
32
33
  static from(channel) {
@@ -35,6 +36,7 @@ class Tracing extends import_channelOwner.ChannelOwner {
35
36
  async start(options = {}) {
36
37
  await this._wrapApiCall(async () => {
37
38
  this._includeSources = !!options.sources;
39
+ this._isLive = !!options._live;
38
40
  await this._channel.tracingStart({
39
41
  name: options.name,
40
42
  snapshots: options.snapshots,
@@ -42,13 +44,13 @@ class Tracing extends import_channelOwner.ChannelOwner {
42
44
  live: options._live
43
45
  });
44
46
  const { traceName } = await this._channel.tracingStartChunk({ name: options.name, title: options.title });
45
- await this._startCollectingStacks(traceName);
47
+ await this._startCollectingStacks(traceName, this._isLive);
46
48
  });
47
49
  }
48
50
  async startChunk(options = {}) {
49
51
  await this._wrapApiCall(async () => {
50
52
  const { traceName } = await this._channel.tracingStartChunk(options);
51
- await this._startCollectingStacks(traceName);
53
+ await this._startCollectingStacks(traceName, this._isLive);
52
54
  });
53
55
  }
54
56
  async group(name, options = {}) {
@@ -57,12 +59,12 @@ class Tracing extends import_channelOwner.ChannelOwner {
57
59
  async groupEnd() {
58
60
  await this._channel.tracingGroupEnd();
59
61
  }
60
- async _startCollectingStacks(traceName) {
62
+ async _startCollectingStacks(traceName, live) {
61
63
  if (!this._isTracing) {
62
64
  this._isTracing = true;
63
65
  this._connection.setIsTracing(true);
64
66
  }
65
- const result = await this._connection.localUtils()?.tracingStarted({ tracesDir: this._tracesDir, traceName });
67
+ const result = await this._connection.localUtils()?.tracingStarted({ tracesDir: this._tracesDir, traceName, live });
66
68
  this._stacksId = result?.stacksId;
67
69
  }
68
70
  async stopChunk(options = {}) {
@@ -26,11 +26,16 @@ var import_errors = require("./errors");
26
26
  var import_events = require("./events");
27
27
  var import_jsHandle = require("./jsHandle");
28
28
  var import_manualPromise = require("../utils/isomorphic/manualPromise");
29
+ var import_timeoutSettings = require("./timeoutSettings");
30
+ var import_waiter = require("./waiter");
29
31
  class Worker extends import_channelOwner.ChannelOwner {
30
32
  constructor(parent, type, guid, initializer) {
31
33
  super(parent, type, guid, initializer);
32
34
  // Set for service workers.
33
35
  this._closedScope = new import_manualPromise.LongStandingScope();
36
+ this._setEventToSubscriptionMapping(/* @__PURE__ */ new Map([
37
+ [import_events.Events.Worker.Console, "console"]
38
+ ]));
34
39
  this._channel.on("close", () => {
35
40
  if (this._page)
36
41
  this._page._workers.delete(this);
@@ -40,6 +45,9 @@ class Worker extends import_channelOwner.ChannelOwner {
40
45
  });
41
46
  this.once(import_events.Events.Worker.Close, () => this._closedScope.close(this._page?._closeErrorWithReason() || new import_errors.TargetClosedError()));
42
47
  }
48
+ static fromNullable(worker) {
49
+ return worker ? Worker.from(worker) : null;
50
+ }
43
51
  static from(worker) {
44
52
  return worker._object;
45
53
  }
@@ -56,6 +64,20 @@ class Worker extends import_channelOwner.ChannelOwner {
56
64
  const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === "function", arg: (0, import_jsHandle.serializeArgument)(arg) });
57
65
  return import_jsHandle.JSHandle.from(result.handle);
58
66
  }
67
+ async waitForEvent(event, optionsOrPredicate = {}) {
68
+ return await this._wrapApiCall(async () => {
69
+ const timeoutSettings = this._page?._timeoutSettings ?? this._context?._timeoutSettings ?? new import_timeoutSettings.TimeoutSettings(this._platform);
70
+ const timeout = timeoutSettings.timeout(typeof optionsOrPredicate === "function" ? {} : optionsOrPredicate);
71
+ const predicate = typeof optionsOrPredicate === "function" ? optionsOrPredicate : optionsOrPredicate.predicate;
72
+ const waiter = import_waiter.Waiter.createForEvent(this, event);
73
+ waiter.rejectOnTimeout(timeout, `Timeout ${timeout}ms exceeded while waiting for event "${event}"`);
74
+ if (event !== import_events.Events.Worker.Close)
75
+ waiter.rejectOnEvent(this, import_events.Events.Worker.Close, () => new import_errors.TargetClosedError());
76
+ const result = await waiter.waitForEvent(this, event, predicate);
77
+ waiter.dispose();
78
+ return result;
79
+ });
80
+ }
59
81
  }
60
82
  // Annotate the CommonJS export names for ESM import in node:
61
83
  0 && (module.exports = {