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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/README.md +5 -5
  2. package/advanced-stealth.js +46 -59
  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 +45 -58
  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.2
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.2
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.2',
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: '143.0.7499.193',
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];
@@ -497,15 +492,15 @@
497
492
  let bulletproofUserAgent;
498
493
  if (isBraveOptimized) {
499
494
  // 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';
495
+ bulletproofUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.7559.59 Safari/537.36';
501
496
  console.log('[🦁 BRAVE-STEALTH] Brave browser optimizations active - maximum stealth mode');
502
497
  } else if (isChromeOptimized) {
503
498
  // 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';
499
+ bulletproofUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.7559.59 Safari/537.36';
505
500
  console.log('[🔵 CHROME-STEALTH] Chrome browser optimizations active');
506
501
  } else {
507
502
  // 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';
503
+ bulletproofUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.7559.59 Safari/537.36';
509
504
  console.log('[⚙️ DEFAULT-STEALTH] Using default browser stealth mode');
510
505
  }
511
506
 
@@ -518,42 +513,13 @@
518
513
 
519
514
  // COMPLETELY override appVersion
520
515
  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',
516
+ get: () => '5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.7559.59 Safari/537.36',
522
517
  configurable: false,
523
518
  enumerable: true
524
519
  });
525
520
 
526
- // BULLETPROOF webdriver property elimination
527
- if ('webdriver' in navigator) {
528
- delete navigator.webdriver;
529
- }
530
521
 
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
- };
522
+ // BULLETPROOF platform detection
557
523
 
558
524
  // BULLETPROOF platform detection
559
525
  Object.defineProperty(navigator, 'platform', {
@@ -587,13 +553,23 @@
587
553
  });
588
554
  })();
589
555
 
590
- // Enhanced userAgentData with getHighEntropyValues method
591
- Object.defineProperty(navigator, 'userAgentData', {
592
- get: () => ({
556
+ // Enhanced userAgentData with getHighEntropyValues method - Singleton & Prototype
557
+ (function() {
558
+ // Aggressively delete existing userAgentData
559
+ try {
560
+ delete Navigator.prototype.userAgentData;
561
+ } catch {}
562
+ try {
563
+ if (navigator.hasOwnProperty('userAgentData')) {
564
+ delete navigator.userAgentData;
565
+ }
566
+ } catch {}
567
+
568
+ const userAgentDataInstance = {
593
569
  brands: [
594
- { brand: 'Not_A Brand', version: '8' },
595
- { brand: 'Chromium', version: '140' },
596
- { brand: 'Google Chrome', version: '140' }
570
+ { brand: 'Not_A Brand', version: '24' },
571
+ { brand: 'Chromium', version: '131' },
572
+ { brand: 'Google Chrome', version: '131' }
597
573
  ],
598
574
  mobile: false,
599
575
  platform: 'Windows',
@@ -601,23 +577,34 @@
601
577
  return Promise.resolve({
602
578
  architecture: 'x86',
603
579
  bitness: '64',
604
- brands: this.brands,
580
+ brands: userAgentDataInstance.brands,
605
581
  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' }
582
+ { brand: 'Not_A Brand', version: '143.0.7499.193' },
583
+ { brand: 'Chromium', version: '143.0.7499.193' },
584
+ { brand: 'Google Chrome', version: '143.0.7499.193' }
609
585
  ],
610
586
  mobile: false,
611
587
  model: '',
612
588
  platform: 'Windows',
613
589
  platformVersion: '10.0.0',
614
- uaFullVersion: '140.0.7339.81'
590
+ uaFullVersion: '143.0.7499.193'
615
591
  });
592
+ },
593
+ toJSON: function() {
594
+ return {
595
+ brands: this.brands,
596
+ mobile: this.mobile,
597
+ platform: this.platform
598
+ };
616
599
  }
617
- }),
618
- configurable: true,
619
- enumerable: false
620
- });
600
+ };
601
+
602
+ Object.defineProperty(Navigator.prototype, 'userAgentData', {
603
+ get: () => userAgentDataInstance,
604
+ configurable: false,
605
+ enumerable: true
606
+ });
607
+ })();
621
608
 
622
609
 
623
610
  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 = {