brave-real-browser 2.0.4 → 2.0.6

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.
@@ -12,6 +12,25 @@ async function pageController({ browser, page, proxy, turnstile, xvfbsession, pi
12
12
 
13
13
  let solveStatus = turnstile
14
14
 
15
+ // 🛡️ Import stealth scripts properly (Dynamic Import for compatibility)
16
+ let injectStealth = () => { };
17
+ try {
18
+ const stealthModule = require('brave-real-puppeteer-core/scripts/stealth-injector.js');
19
+ // Combine essential stealth scripts
20
+ const ultrafast = stealthModule.injectUltraFastPerformance();
21
+ const navStealth = stealthModule.injectNavigatorStealth();
22
+ injectStealth = async (page) => {
23
+ await page.evaluateOnNewDocument(ultrafast);
24
+ await page.evaluateOnNewDocument(navStealth);
25
+ };
26
+ } catch (e) {
27
+ // Fallback if module not found (shouldn't happen in monorepo)
28
+ console.error('Stealth module not found, using minimal fallback', e);
29
+ }
30
+
31
+ // Apply stealth BEFORE any other page actions
32
+ if (page) await injectStealth(page);
33
+
15
34
  page.on('close', () => {
16
35
  solveStatus = false
17
36
  });
@@ -44,6 +63,233 @@ async function pageController({ browser, page, proxy, turnstile, xvfbsession, pi
44
63
  }
45
64
  }
46
65
 
66
+ // 🛡️ COMPREHENSIVE STEALTH INJECTION - For Brotector/Datadome bypass
67
+ await page.evaluateOnNewDocument(() => {
68
+ // ============ NAVIGATOR WEBDRIVER ELIMINATION ============
69
+ Object.defineProperty(navigator, 'webdriver', {
70
+ get: () => undefined,
71
+ configurable: true
72
+ });
73
+
74
+ // Delete webdriver from Object.getOwnPropertyDescriptor
75
+ const originalGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
76
+ Object.getOwnPropertyDescriptor = function (obj, prop) {
77
+ if (obj === navigator && prop === 'webdriver') return undefined;
78
+ return originalGetOwnPropertyDescriptor.apply(this, arguments);
79
+ };
80
+
81
+ // ============ PLUGINS & MIME TYPES ============
82
+ Object.defineProperty(navigator, 'plugins', {
83
+ get: () => {
84
+ const plugins = [
85
+ { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format' },
86
+ { name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai', description: '' },
87
+ { name: 'Native Client', filename: 'internal-nacl-plugin', description: '' }
88
+ ];
89
+ plugins.length = 3;
90
+ plugins.item = i => plugins[i];
91
+ plugins.namedItem = n => plugins.find(p => p.name === n);
92
+ plugins.refresh = () => { };
93
+ return plugins;
94
+ },
95
+ configurable: true
96
+ });
97
+
98
+ Object.defineProperty(navigator, 'mimeTypes', {
99
+ get: () => {
100
+ const mimeTypes = [
101
+ { type: 'application/pdf', suffixes: 'pdf', description: 'Portable Document Format' },
102
+ { type: 'text/pdf', suffixes: 'pdf', description: '' }
103
+ ];
104
+ mimeTypes.length = 2;
105
+ mimeTypes.item = i => mimeTypes[i];
106
+ mimeTypes.namedItem = n => mimeTypes.find(m => m.type === n);
107
+ return mimeTypes;
108
+ },
109
+ configurable: true
110
+ });
111
+
112
+ // ============ LANGUAGES ============
113
+ Object.defineProperty(navigator, 'languages', {
114
+ get: () => ['en-US', 'en'],
115
+ configurable: true
116
+ });
117
+
118
+ // ============ CHROME RUNTIME REMOVAL ============
119
+ if (window.chrome) {
120
+ const originalChrome = window.chrome;
121
+ window.chrome = new Proxy(originalChrome, {
122
+ get(target, prop) {
123
+ if (prop === 'runtime') return undefined;
124
+ if (prop === 'csi') return undefined;
125
+ if (prop === 'loadTimes') return undefined;
126
+ return Reflect.get(target, prop);
127
+ }
128
+ });
129
+ }
130
+
131
+ // ============ PERMISSIONS API ============
132
+ if (navigator.permissions) {
133
+ const originalQuery = navigator.permissions.query.bind(navigator.permissions);
134
+ navigator.permissions.query = (params) => {
135
+ if (params.name === 'notifications') {
136
+ return Promise.resolve({ state: 'prompt', onchange: null });
137
+ }
138
+ return originalQuery(params);
139
+ };
140
+ }
141
+
142
+ // ============ AUTOMATION SIGNATURES REMOVAL ============
143
+ const automationProps = [
144
+ '__puppeteer__', 'puppeteer', '__playwright__', 'playwright',
145
+ '__selenium_unwrapped', '__selenium_evaluate', '__webdriver_evaluate',
146
+ '__driver_evaluate', '_phantom', '__nightmare', 'callPhantom',
147
+ '__webdriver_script_fn', '__webdriver_script_func', 'cdc_adoQpoasnfa76pfcZLmcfl_Array',
148
+ 'cdc_adoQpoasnfa76pfcZLmcfl_Promise', 'cdc_adoQpoasnfa76pfcZLmcfl_Symbol'
149
+ ];
150
+ automationProps.forEach(prop => {
151
+ try { delete window[prop]; } catch (e) { }
152
+ });
153
+
154
+ // ============ ERROR STACK SANITIZATION ============
155
+ const originalError = Error;
156
+ window.Error = function (...args) {
157
+ const error = new originalError(...args);
158
+ if (error.stack) {
159
+ error.stack = error.stack.split('\\n')
160
+ .filter(line => !line.includes('puppeteer') && !line.includes('playwright') && !line.includes('UtilityScript'))
161
+ .join('\\n');
162
+ }
163
+ return error;
164
+ };
165
+ window.Error.prototype = originalError.prototype;
166
+
167
+ // ============ HARDWARE SPOOFING ============
168
+ Object.defineProperty(navigator, 'hardwareConcurrency', { get: () => 4 });
169
+ Object.defineProperty(navigator, 'deviceMemory', { get: () => 8 });
170
+
171
+ // ============ CONNECTION API ============
172
+ if (navigator.connection) {
173
+ Object.defineProperty(navigator.connection, 'rtt', { get: () => 50 });
174
+ Object.defineProperty(navigator.connection, 'downlink', { get: () => 10 });
175
+ Object.defineProperty(navigator.connection, 'effectiveType', { get: () => '4g' });
176
+ }
177
+ });
178
+
179
+ // MouseEvent screenX/screenY fix
180
+ // 🛡️ COMPREHENSIVE STEALTH INJECTION - For Brotector/Datadome bypass
181
+ await page.evaluateOnNewDocument(() => {
182
+ // ============ NAVIGATOR WEBDRIVER ELIMINATION ============
183
+ Object.defineProperty(navigator, 'webdriver', {
184
+ get: () => undefined,
185
+ configurable: true
186
+ });
187
+
188
+ // Delete webdriver from Object.getOwnPropertyDescriptor
189
+ const originalGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
190
+ Object.getOwnPropertyDescriptor = function (obj, prop) {
191
+ if (obj === navigator && prop === 'webdriver') return undefined;
192
+ return originalGetOwnPropertyDescriptor.apply(this, arguments);
193
+ };
194
+
195
+ // ============ PLUGINS & MIME TYPES ============
196
+ Object.defineProperty(navigator, 'plugins', {
197
+ get: () => {
198
+ const plugins = [
199
+ { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format' },
200
+ { name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai', description: '' },
201
+ { name: 'Native Client', filename: 'internal-nacl-plugin', description: '' }
202
+ ];
203
+ plugins.length = 3;
204
+ plugins.item = i => plugins[i];
205
+ plugins.namedItem = n => plugins.find(p => p.name === n);
206
+ plugins.refresh = () => { };
207
+ return plugins;
208
+ },
209
+ configurable: true
210
+ });
211
+
212
+ Object.defineProperty(navigator, 'mimeTypes', {
213
+ get: () => {
214
+ const mimeTypes = [
215
+ { type: 'application/pdf', suffixes: 'pdf', description: 'Portable Document Format' },
216
+ { type: 'text/pdf', suffixes: 'pdf', description: '' }
217
+ ];
218
+ mimeTypes.length = 2;
219
+ mimeTypes.item = i => mimeTypes[i];
220
+ mimeTypes.namedItem = n => mimeTypes.find(m => m.type === n);
221
+ return mimeTypes;
222
+ },
223
+ configurable: true
224
+ });
225
+
226
+ // ============ LANGUAGES ============
227
+ Object.defineProperty(navigator, 'languages', {
228
+ get: () => ['en-US', 'en'],
229
+ configurable: true
230
+ });
231
+
232
+ // ============ CHROME RUNTIME REMOVAL ============
233
+ if (window.chrome) {
234
+ const originalChrome = window.chrome;
235
+ window.chrome = new Proxy(originalChrome, {
236
+ get(target, prop) {
237
+ if (prop === 'runtime') return undefined;
238
+ if (prop === 'csi') return undefined;
239
+ if (prop === 'loadTimes') return undefined;
240
+ return Reflect.get(target, prop);
241
+ }
242
+ });
243
+ }
244
+
245
+ // ============ PERMISSIONS API ============
246
+ if (navigator.permissions) {
247
+ const originalQuery = navigator.permissions.query.bind(navigator.permissions);
248
+ navigator.permissions.query = (params) => {
249
+ if (params.name === 'notifications') {
250
+ return Promise.resolve({ state: 'prompt', onchange: null });
251
+ }
252
+ return originalQuery(params);
253
+ };
254
+ }
255
+
256
+ // ============ AUTOMATION SIGNATURES REMOVAL ============
257
+ const automationProps = [
258
+ '__puppeteer__', 'puppeteer', '__playwright__', 'playwright',
259
+ '__selenium_unwrapped', '__selenium_evaluate', '__webdriver_evaluate',
260
+ '__driver_evaluate', '_phantom', '__nightmare', 'callPhantom',
261
+ '__webdriver_script_fn', '__webdriver_script_func', 'cdc_adoQpoasnfa76pfcZLmcfl_Array',
262
+ 'cdc_adoQpoasnfa76pfcZLmcfl_Promise', 'cdc_adoQpoasnfa76pfcZLmcfl_Symbol'
263
+ ];
264
+ automationProps.forEach(prop => {
265
+ try { delete window[prop]; } catch (e) { }
266
+ });
267
+
268
+ // ============ ERROR STACK SANITIZATION ============
269
+ const originalError = Error;
270
+ window.Error = function (...args) {
271
+ const error = new originalError(...args);
272
+ if (error.stack) {
273
+ error.stack = error.stack.split('\\n')
274
+ .filter(line => !line.includes('puppeteer') && !line.includes('playwright') && !line.includes('UtilityScript'))
275
+ .join('\\n');
276
+ }
277
+ return error;
278
+ };
279
+ window.Error.prototype = originalError.prototype;
280
+
281
+ // ============ HARDWARE SPOOFING ============
282
+ Object.defineProperty(navigator, 'hardwareConcurrency', { get: () => 4 });
283
+ Object.defineProperty(navigator, 'deviceMemory', { get: () => 8 });
284
+
285
+ // ============ CONNECTION API ============
286
+ if (navigator.connection) {
287
+ Object.defineProperty(navigator.connection, 'rtt', { get: () => 50 });
288
+ Object.defineProperty(navigator.connection, 'downlink', { get: () => 10 });
289
+ Object.defineProperty(navigator.connection, 'effectiveType', { get: () => '4g' });
290
+ }
291
+ });
292
+
47
293
  await page.evaluateOnNewDocument(() => {
48
294
  Object.defineProperty(MouseEvent.prototype, 'screenX', {
49
295
  get: function () {
@@ -12,6 +12,22 @@ export async function pageController({ browser, page, proxy, turnstile, xvfbsess
12
12
 
13
13
  let solveStatus = turnstile
14
14
 
15
+ // 🛡️ Import stealth scripts properly (Dynamic Import for compatibility)
16
+ let injectStealth = () => { };
17
+ try {
18
+ // Use dynamic import for ESM
19
+ const { injectUltraFastPerformance, injectNavigatorStealth } = await import('brave-real-puppeteer-core/scripts/stealth-injector.js');
20
+ injectStealth = async (page) => {
21
+ await page.evaluateOnNewDocument(injectUltraFastPerformance());
22
+ await page.evaluateOnNewDocument(injectNavigatorStealth());
23
+ };
24
+ } catch (e) {
25
+ console.error('Stealth module not found, using minimal fallback', e);
26
+ }
27
+
28
+ // Apply stealth BEFORE any other page actions
29
+ if (page) await injectStealth(page);
30
+
15
31
  page.on('close', () => {
16
32
  solveStatus = false
17
33
  });
@@ -44,6 +60,233 @@ export async function pageController({ browser, page, proxy, turnstile, xvfbsess
44
60
  }
45
61
  }
46
62
 
63
+ // 🛡️ COMPREHENSIVE STEALTH INJECTION - For Brotector/Datadome bypass
64
+ await page.evaluateOnNewDocument(() => {
65
+ // ============ NAVIGATOR WEBDRIVER ELIMINATION ============
66
+ Object.defineProperty(navigator, 'webdriver', {
67
+ get: () => undefined,
68
+ configurable: true
69
+ });
70
+
71
+ // Delete webdriver from Object.getOwnPropertyDescriptor
72
+ const originalGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
73
+ Object.getOwnPropertyDescriptor = function (obj, prop) {
74
+ if (obj === navigator && prop === 'webdriver') return undefined;
75
+ return originalGetOwnPropertyDescriptor.apply(this, arguments);
76
+ };
77
+
78
+ // ============ PLUGINS & MIME TYPES ============
79
+ Object.defineProperty(navigator, 'plugins', {
80
+ get: () => {
81
+ const plugins = [
82
+ { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format' },
83
+ { name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai', description: '' },
84
+ { name: 'Native Client', filename: 'internal-nacl-plugin', description: '' }
85
+ ];
86
+ plugins.length = 3;
87
+ plugins.item = i => plugins[i];
88
+ plugins.namedItem = n => plugins.find(p => p.name === n);
89
+ plugins.refresh = () => { };
90
+ return plugins;
91
+ },
92
+ configurable: true
93
+ });
94
+
95
+ Object.defineProperty(navigator, 'mimeTypes', {
96
+ get: () => {
97
+ const mimeTypes = [
98
+ { type: 'application/pdf', suffixes: 'pdf', description: 'Portable Document Format' },
99
+ { type: 'text/pdf', suffixes: 'pdf', description: '' }
100
+ ];
101
+ mimeTypes.length = 2;
102
+ mimeTypes.item = i => mimeTypes[i];
103
+ mimeTypes.namedItem = n => mimeTypes.find(m => m.type === n);
104
+ return mimeTypes;
105
+ },
106
+ configurable: true
107
+ });
108
+
109
+ // ============ LANGUAGES ============
110
+ Object.defineProperty(navigator, 'languages', {
111
+ get: () => ['en-US', 'en'],
112
+ configurable: true
113
+ });
114
+
115
+ // ============ CHROME RUNTIME REMOVAL ============
116
+ if (window.chrome) {
117
+ const originalChrome = window.chrome;
118
+ window.chrome = new Proxy(originalChrome, {
119
+ get(target, prop) {
120
+ if (prop === 'runtime') return undefined;
121
+ if (prop === 'csi') return undefined;
122
+ if (prop === 'loadTimes') return undefined;
123
+ return Reflect.get(target, prop);
124
+ }
125
+ });
126
+ }
127
+
128
+ // ============ PERMISSIONS API ============
129
+ if (navigator.permissions) {
130
+ const originalQuery = navigator.permissions.query.bind(navigator.permissions);
131
+ navigator.permissions.query = (params) => {
132
+ if (params.name === 'notifications') {
133
+ return Promise.resolve({ state: 'prompt', onchange: null });
134
+ }
135
+ return originalQuery(params);
136
+ };
137
+ }
138
+
139
+ // ============ AUTOMATION SIGNATURES REMOVAL ============
140
+ const automationProps = [
141
+ '__puppeteer__', 'puppeteer', '__playwright__', 'playwright',
142
+ '__selenium_unwrapped', '__selenium_evaluate', '__webdriver_evaluate',
143
+ '__driver_evaluate', '_phantom', '__nightmare', 'callPhantom',
144
+ '__webdriver_script_fn', '__webdriver_script_func', 'cdc_adoQpoasnfa76pfcZLmcfl_Array',
145
+ 'cdc_adoQpoasnfa76pfcZLmcfl_Promise', 'cdc_adoQpoasnfa76pfcZLmcfl_Symbol'
146
+ ];
147
+ automationProps.forEach(prop => {
148
+ try { delete window[prop]; } catch (e) { }
149
+ });
150
+
151
+ // ============ ERROR STACK SANITIZATION ============
152
+ const originalError = Error;
153
+ window.Error = function (...args) {
154
+ const error = new originalError(...args);
155
+ if (error.stack) {
156
+ error.stack = error.stack.split('\\n')
157
+ .filter(line => !line.includes('puppeteer') && !line.includes('playwright') && !line.includes('UtilityScript'))
158
+ .join('\\n');
159
+ }
160
+ return error;
161
+ };
162
+ window.Error.prototype = originalError.prototype;
163
+
164
+ // ============ HARDWARE SPOOFING ============
165
+ Object.defineProperty(navigator, 'hardwareConcurrency', { get: () => 4 });
166
+ Object.defineProperty(navigator, 'deviceMemory', { get: () => 8 });
167
+
168
+ // ============ CONNECTION API ============
169
+ if (navigator.connection) {
170
+ Object.defineProperty(navigator.connection, 'rtt', { get: () => 50 });
171
+ Object.defineProperty(navigator.connection, 'downlink', { get: () => 10 });
172
+ Object.defineProperty(navigator.connection, 'effectiveType', { get: () => '4g' });
173
+ }
174
+ });
175
+
176
+ // MouseEvent screenX/screenY fix
177
+ // 🛡️ COMPREHENSIVE STEALTH INJECTION - For Brotector/Datadome bypass
178
+ await page.evaluateOnNewDocument(() => {
179
+ // ============ NAVIGATOR WEBDRIVER ELIMINATION ============
180
+ Object.defineProperty(navigator, 'webdriver', {
181
+ get: () => undefined,
182
+ configurable: true
183
+ });
184
+
185
+ // Delete webdriver from Object.getOwnPropertyDescriptor
186
+ const originalGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
187
+ Object.getOwnPropertyDescriptor = function (obj, prop) {
188
+ if (obj === navigator && prop === 'webdriver') return undefined;
189
+ return originalGetOwnPropertyDescriptor.apply(this, arguments);
190
+ };
191
+
192
+ // ============ PLUGINS & MIME TYPES ============
193
+ Object.defineProperty(navigator, 'plugins', {
194
+ get: () => {
195
+ const plugins = [
196
+ { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format' },
197
+ { name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai', description: '' },
198
+ { name: 'Native Client', filename: 'internal-nacl-plugin', description: '' }
199
+ ];
200
+ plugins.length = 3;
201
+ plugins.item = i => plugins[i];
202
+ plugins.namedItem = n => plugins.find(p => p.name === n);
203
+ plugins.refresh = () => { };
204
+ return plugins;
205
+ },
206
+ configurable: true
207
+ });
208
+
209
+ Object.defineProperty(navigator, 'mimeTypes', {
210
+ get: () => {
211
+ const mimeTypes = [
212
+ { type: 'application/pdf', suffixes: 'pdf', description: 'Portable Document Format' },
213
+ { type: 'text/pdf', suffixes: 'pdf', description: '' }
214
+ ];
215
+ mimeTypes.length = 2;
216
+ mimeTypes.item = i => mimeTypes[i];
217
+ mimeTypes.namedItem = n => mimeTypes.find(m => m.type === n);
218
+ return mimeTypes;
219
+ },
220
+ configurable: true
221
+ });
222
+
223
+ // ============ LANGUAGES ============
224
+ Object.defineProperty(navigator, 'languages', {
225
+ get: () => ['en-US', 'en'],
226
+ configurable: true
227
+ });
228
+
229
+ // ============ CHROME RUNTIME REMOVAL ============
230
+ if (window.chrome) {
231
+ const originalChrome = window.chrome;
232
+ window.chrome = new Proxy(originalChrome, {
233
+ get(target, prop) {
234
+ if (prop === 'runtime') return undefined;
235
+ if (prop === 'csi') return undefined;
236
+ if (prop === 'loadTimes') return undefined;
237
+ return Reflect.get(target, prop);
238
+ }
239
+ });
240
+ }
241
+
242
+ // ============ PERMISSIONS API ============
243
+ if (navigator.permissions) {
244
+ const originalQuery = navigator.permissions.query.bind(navigator.permissions);
245
+ navigator.permissions.query = (params) => {
246
+ if (params.name === 'notifications') {
247
+ return Promise.resolve({ state: 'prompt', onchange: null });
248
+ }
249
+ return originalQuery(params);
250
+ };
251
+ }
252
+
253
+ // ============ AUTOMATION SIGNATURES REMOVAL ============
254
+ const automationProps = [
255
+ '__puppeteer__', 'puppeteer', '__playwright__', 'playwright',
256
+ '__selenium_unwrapped', '__selenium_evaluate', '__webdriver_evaluate',
257
+ '__driver_evaluate', '_phantom', '__nightmare', 'callPhantom',
258
+ '__webdriver_script_fn', '__webdriver_script_func', 'cdc_adoQpoasnfa76pfcZLmcfl_Array',
259
+ 'cdc_adoQpoasnfa76pfcZLmcfl_Promise', 'cdc_adoQpoasnfa76pfcZLmcfl_Symbol'
260
+ ];
261
+ automationProps.forEach(prop => {
262
+ try { delete window[prop]; } catch (e) { }
263
+ });
264
+
265
+ // ============ ERROR STACK SANITIZATION ============
266
+ const originalError = Error;
267
+ window.Error = function (...args) {
268
+ const error = new originalError(...args);
269
+ if (error.stack) {
270
+ error.stack = error.stack.split('\\n')
271
+ .filter(line => !line.includes('puppeteer') && !line.includes('playwright') && !line.includes('UtilityScript'))
272
+ .join('\\n');
273
+ }
274
+ return error;
275
+ };
276
+ window.Error.prototype = originalError.prototype;
277
+
278
+ // ============ HARDWARE SPOOFING ============
279
+ Object.defineProperty(navigator, 'hardwareConcurrency', { get: () => 4 });
280
+ Object.defineProperty(navigator, 'deviceMemory', { get: () => 8 });
281
+
282
+ // ============ CONNECTION API ============
283
+ if (navigator.connection) {
284
+ Object.defineProperty(navigator.connection, 'rtt', { get: () => 50 });
285
+ Object.defineProperty(navigator.connection, 'downlink', { get: () => 10 });
286
+ Object.defineProperty(navigator.connection, 'effectiveType', { get: () => '4g' });
287
+ }
288
+ });
289
+
47
290
  await page.evaluateOnNewDocument(() => {
48
291
  Object.defineProperty(MouseEvent.prototype, 'screenX', {
49
292
  get: function () {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brave-real-browser",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "This package is designed to bypass puppeteer's bot-detecting captchas such as Cloudflare. It acts like a real browser and can be managed with puppeteer.",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/esm/index.mjs",
@@ -36,8 +36,8 @@
36
36
  "author": "codeiva4u",
37
37
  "license": "ISC",
38
38
  "dependencies": {
39
- "brave-real-launcher": "^1.2.43",
40
- "brave-real-puppeteer-core": "^24.34.0-patch.9",
39
+ "brave-real-launcher": "^1.2.48",
40
+ "brave-real-puppeteer-core": "^24.34.0-patch.11",
41
41
  "ghost-cursor": "^1.4.1",
42
42
  "puppeteer-extra": "^3.3.6",
43
43
  "tree-kill": "^1.2.2",
@@ -0,0 +1,16 @@
1
+ const launcher = require('brave-real-launcher');
2
+
3
+ (async () => {
4
+ try {
5
+ console.log('Fetching dynamic User Agents...');
6
+ const agents = await launcher.getDynamicUserAgents();
7
+ console.log('Dynamic User Agents:', JSON.stringify(agents, null, 2));
8
+
9
+ console.log('Checking fallback/latest version...');
10
+ const version = await launcher.getLatestChromeVersion();
11
+ console.log('Version:', version);
12
+
13
+ } catch (err) {
14
+ console.error('Error:', err);
15
+ }
16
+ })();
@@ -0,0 +1,32 @@
1
+ const { connect } = require('../lib/cjs/index.js');
2
+
3
+ (async () => {
4
+ try {
5
+ console.log('Connecting to browser (HEADED)...');
6
+ const { page, browser } = await connect({
7
+ headless: false,
8
+ args: [],
9
+ customConfig: {},
10
+ turnstile: true,
11
+ connectOption: {},
12
+ disableXvfb: false,
13
+ ignoreAllFlags: false
14
+ });
15
+
16
+ console.log('Checking navigator properties...');
17
+ const ua = await page.evaluate(() => navigator.userAgent);
18
+ const appVersion = await page.evaluate(() => navigator.appVersion);
19
+ const platform = await page.evaluate(() => navigator.platform);
20
+ const uaData = await page.evaluate(() => navigator.userAgentData ? navigator.userAgentData.brands : 'Not Supported');
21
+
22
+ console.log('User Agent:', ua);
23
+ console.log('App Version:', appVersion);
24
+ console.log('Platform:', platform);
25
+ console.log('UA Data:', JSON.stringify(uaData, null, 2));
26
+
27
+ await browser.close();
28
+ console.log('Browser closed.');
29
+ } catch (err) {
30
+ console.error('Error:', err);
31
+ }
32
+ })();