brave-real-browser 1.5.106 β 2.0.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.
- package/README.md +22 -54
- package/lib/cjs/index.js +13 -40
- package/lib/cjs/module/pageController.js +35 -142
- package/lib/esm/index.mjs +12 -35
- package/lib/esm/module/pageController.mjs +34 -144
- package/lib/esm/module/turnstile.mjs +3 -4
- package/package.json +8 -15
- package/test/cjs/test.js +49 -57
- package/test/esm/test.js +48 -58
- package/AUTO_UPDATE_GUIDE.md +0 -197
- package/FEATURES.md +0 -265
- package/FIXES_NEEDED.md +0 -131
- package/lib/cjs/errors.js +0 -299
- package/renovate.json +0 -59
- package/scripts/auto-update.js +0 -119
package/README.md
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
<br/>
|
|
5
5
|
<p align="center">
|
|
6
|
-
<a href="https://github.com/
|
|
6
|
+
<a href="https://github.com/codeiva4u/Brave-Real-Browser">
|
|
7
7
|
<img src="https://github.com/zfcsoftware/puppeteer-real-browser/assets/123484092/cc8b5fb9-504a-4fd3-97f6-a51990bb4303" alt="Logo" width="80" height="80">
|
|
8
8
|
</a>
|
|
9
9
|
|
|
10
|
-
<h3 align="center">
|
|
10
|
+
<h3 align="center">Brave Real Browser</h3>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
13
13
|
This package prevents Puppeteer from being detected as a bot in services like Cloudflare and allows you to pass captchas without any problems. It behaves like a real browser.
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
</p>
|
|
23
23
|
|
|
24
24
|
<p align="center">
|
|
25
|
-
<img src="https://img.shields.io/github/contributors/
|
|
26
|
-
<img src="https://img.shields.io/github/forks/
|
|
27
|
-
<img src="https://img.shields.io/github/stars/
|
|
28
|
-
<img src="https://img.shields.io/github/issues/
|
|
29
|
-
<img src="https://img.shields.io/github/license/
|
|
25
|
+
<img src="https://img.shields.io/github/contributors/codeiva4u/Brave-Real-Browser?color=dark-green" alt="Contributors" />
|
|
26
|
+
<img src="https://img.shields.io/github/forks/codeiva4u/Brave-Real-Browser?style=social" alt="Forks" />
|
|
27
|
+
<img src="https://img.shields.io/github/stars/codeiva4u/Brave-Real-Browser?style=social" alt="Stargazers" />
|
|
28
|
+
<img src="https://img.shields.io/github/issues/codeiva4u/Brave-Real-Browser" alt="Issues" />
|
|
29
|
+
<img src="https://img.shields.io/github/license/codeiva4u/Brave-Real-Browser" alt="License" />
|
|
30
30
|
</p>
|
|
31
31
|
|
|
32
32
|
## Sponsor
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
If you are using a Linux operating system, xvfb must be installed for the library to work correctly.
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
npm i
|
|
41
|
+
npm i brave-real-browser
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
if you are using linux:
|
|
@@ -47,44 +47,12 @@ if you are using linux:
|
|
|
47
47
|
sudo apt-get install xvfb
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
### π Auto-Update Feature
|
|
51
|
-
|
|
52
|
-
This package **automatically updates all dependencies to their latest versions** whenever you run `npm install`. This ensures you always have the most recent bug fixes and security patches.
|
|
53
|
-
|
|
54
|
-
**How it works:**
|
|
55
|
-
- β
Automatically checks for outdated dependencies on every `npm install`
|
|
56
|
-
- β
Updates only the core dependencies (brave-real-launcher, brave-real-puppeteer-core, etc.)
|
|
57
|
-
- β
Works in CI/CD environments (GitHub Actions, etc.)
|
|
58
|
-
- β
Can be disabled if needed
|
|
59
|
-
|
|
60
|
-
**To disable auto-update:**
|
|
61
|
-
```bash
|
|
62
|
-
# Temporarily disable for one install
|
|
63
|
-
SKIP_AUTO_UPDATE=true npm install
|
|
64
|
-
|
|
65
|
-
# Or set environment variable
|
|
66
|
-
export SKIP_AUTO_UPDATE=true
|
|
67
|
-
npm install
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
**Manual update commands:**
|
|
71
|
-
```bash
|
|
72
|
-
# Check for outdated dependencies
|
|
73
|
-
npm run check-updates
|
|
74
|
-
|
|
75
|
-
# Update all dependencies manually
|
|
76
|
-
npm run update-deps
|
|
77
|
-
|
|
78
|
-
# Or use the convenient command
|
|
79
|
-
npm run upgrade-all
|
|
80
|
-
```
|
|
81
|
-
|
|
82
50
|
## Include
|
|
83
51
|
|
|
84
52
|
### CommonJS
|
|
85
53
|
|
|
86
54
|
```js
|
|
87
|
-
const { connect } = require("
|
|
55
|
+
const { connect } = require("brave-real-browser");
|
|
88
56
|
|
|
89
57
|
const start = async () => {
|
|
90
58
|
const { page, browser } = await connect();
|
|
@@ -94,7 +62,7 @@ const start = async () => {
|
|
|
94
62
|
### Module
|
|
95
63
|
|
|
96
64
|
```js
|
|
97
|
-
import { connect } from "
|
|
65
|
+
import { connect } from "brave-real-browser";
|
|
98
66
|
|
|
99
67
|
const { page, browser } = await connect();
|
|
100
68
|
```
|
|
@@ -102,7 +70,7 @@ const { page, browser } = await connect();
|
|
|
102
70
|
## Usage
|
|
103
71
|
|
|
104
72
|
```js
|
|
105
|
-
const { connect } = require("
|
|
73
|
+
const { connect } = require("brave-real-browser");
|
|
106
74
|
|
|
107
75
|
async function test() {
|
|
108
76
|
const { browser, page } = await connect({
|
|
@@ -134,9 +102,9 @@ test();
|
|
|
134
102
|
**headless**: The default value is false. Values such as βnewβ, true, βshellβ can also be sent, but it works most stable when false is used.
|
|
135
103
|
|
|
136
104
|
**args:** If there is an additional flag you want to add when starting Chromium, you can send it with this string.
|
|
137
|
-
Supported flags: https://github.com/
|
|
105
|
+
Supported flags: https://github.com/AaronRai123/brave-real-launcher
|
|
138
106
|
|
|
139
|
-
**customConfig:** https://github.com/
|
|
107
|
+
**customConfig:** https://github.com/AaronRai123/brave-real-launcher The browser is initialized with this library. What you send with this object is added as a direct initialization argument. You should use the initialization values in this repo. You should set the userDataDir option here and if you want to specify a custom Brave path, you should set it with the bravePath value.
|
|
140
108
|
|
|
141
109
|
**turnstile:** Cloudflare Turnstile automatically clicks on Captchas if set to true
|
|
142
110
|
|
|
@@ -159,7 +127,7 @@ npm i puppeteer-extra-plugin-click-and-wait
|
|
|
159
127
|
```js
|
|
160
128
|
const test = require("node:test");
|
|
161
129
|
const assert = require("node:assert");
|
|
162
|
-
const { connect } = require("
|
|
130
|
+
const { connect } = require("brave-real-browser");
|
|
163
131
|
|
|
164
132
|
test("Puppeteer Extra Plugin", async () => {
|
|
165
133
|
const { page, browser } = await connect({
|
|
@@ -186,31 +154,31 @@ You can use the Dockerfile file in the main directory to use this library with d
|
|
|
186
154
|
To run a test, you can follow these steps
|
|
187
155
|
|
|
188
156
|
```bash
|
|
189
|
-
git clone https://github.com/
|
|
157
|
+
git clone https://github.com/codeiva4u/Brave-Real-Browser.git
|
|
190
158
|
```
|
|
191
159
|
|
|
192
160
|
```bash
|
|
193
|
-
cd
|
|
161
|
+
cd brave-real-browser
|
|
194
162
|
```
|
|
195
163
|
|
|
196
164
|
```bash
|
|
197
|
-
docker build -t
|
|
165
|
+
docker build -t brave-real-browser-project .
|
|
198
166
|
```
|
|
199
167
|
|
|
200
168
|
```bash
|
|
201
|
-
docker run
|
|
169
|
+
docker run brave-real-browser-project
|
|
202
170
|
```
|
|
203
171
|
|
|
204
172
|
## Support Us
|
|
205
173
|
|
|
206
|
-
This library is completely open source and is constantly being updated. Please star this repo to support this project. Starring and supporting the project will ensure that it receives updates. If you want to support it further, you can consider sponsoring me (https://github.com/sponsors/
|
|
174
|
+
This library is completely open source and is constantly being updated. Please star this repo to support this project. Starring and supporting the project will ensure that it receives updates. If you want to support it further, you can consider sponsoring me (https://github.com/sponsors/codeiva4u)
|
|
207
175
|
|
|
208
176
|
## Quick Questions and Answers
|
|
209
177
|
|
|
210
178
|
### I Cannot Access Functions in Window Object What Should I Do?
|
|
211
179
|
|
|
212
180
|
This problem is probably caused by the runtime being closed by the rebrowser used.
|
|
213
|
-
https://github.com/
|
|
181
|
+
https://github.com/codeiva4u/Brave-Real-Browser/tree/access-window
|
|
214
182
|
I created a branch for this. You can access the value you want by adding javascript to the page source with puppeteer-intercept-and-modify-requests as done in success.js. If you know about the Chrome plugin, you can also use it.
|
|
215
183
|
|
|
216
184
|
### page.setViewport method is not working, what should I do?
|
|
@@ -221,7 +189,7 @@ As with the initialization arguments in the test module, you can set the default
|
|
|
221
189
|
|
|
222
190
|
using puppeteer-core patched with rebrowser. Tested with the challenging sites in the test file in headless false mode and passed with flying colors. The only known issue is that the mouse screeenX does not match the mouse position. This has been patched in the library.
|
|
223
191
|
|
|
224
|
-
The ghost-cursor is included in the library. (https://github.com/
|
|
192
|
+
The ghost-cursor is included in the library. (https://github.com/codeiva4u/Brave-Real-Browser/blob/2a5fba37a85c15625fb3c8d1f7cf8dcb109b9492/lib/cjs/module/pageController.js#L54) You can use ghost-cursor with page.realCursor. page.click It is recommended to use page.realClick instead of page.click.
|
|
225
193
|
|
|
226
194
|
### What Makes This Library Special?
|
|
227
195
|
|
|
@@ -237,7 +205,7 @@ Please see the answers in the link above. When there is no Google session, no ma
|
|
|
237
205
|
|
|
238
206
|
## License
|
|
239
207
|
|
|
240
|
-
Distributed under the MIT License. See [LICENSE](https://github.com/
|
|
208
|
+
Distributed under the MIT License. See [LICENSE](https://github.com/codeiva4u/Brave-Real-Browser/blob/main/LICENSE.md) for more information.
|
|
241
209
|
|
|
242
210
|
## Thank You
|
|
243
211
|
|
package/lib/cjs/index.js
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
let puppeteer = require("brave-real-puppeteer-core");
|
|
2
2
|
const { pageController } = require("./module/pageController.js");
|
|
3
|
-
|
|
4
|
-
try {
|
|
5
|
-
Xvfb = require("xvfb");
|
|
6
|
-
} catch {
|
|
7
|
-
// ignore
|
|
8
|
-
}
|
|
3
|
+
|
|
9
4
|
|
|
10
5
|
async function connect({
|
|
11
6
|
args = [],
|
|
@@ -18,29 +13,13 @@ async function connect({
|
|
|
18
13
|
plugins = [],
|
|
19
14
|
ignoreAllFlags = false,
|
|
20
15
|
} = {}) {
|
|
21
|
-
const { launch, DEFAULT_FLAGS } = await import("brave-real-launcher");
|
|
16
|
+
const { launch, BraveLauncher, DEFAULT_FLAGS } = await import("brave-real-launcher");
|
|
22
17
|
|
|
23
|
-
let xvfbsession = null;
|
|
24
|
-
if (headless == "auto") headless = false;
|
|
25
18
|
|
|
26
|
-
if (process.platform === "linux" && disableXvfb === false) {
|
|
27
|
-
try {
|
|
28
|
-
xvfbsession = new Xvfb({
|
|
29
|
-
silent: true,
|
|
30
|
-
xvfb_args: ["-screen", "0", "1920x1080x24", "-ac"],
|
|
31
|
-
});
|
|
32
|
-
xvfbsession.startSync();
|
|
33
|
-
} catch (err) {
|
|
34
|
-
console.log(
|
|
35
|
-
"You are running on a Linux platform but do not have xvfb installed. The browser can be captured. Please install it with the following command\n\nsudo apt-get install xvfb\n\n" +
|
|
36
|
-
err.message
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
19
|
|
|
41
|
-
let
|
|
20
|
+
let braveFlags;
|
|
42
21
|
if (ignoreAllFlags === true) {
|
|
43
|
-
|
|
22
|
+
braveFlags = [
|
|
44
23
|
...args,
|
|
45
24
|
...(headless !== false ? [`--headless=${headless}`] : []),
|
|
46
25
|
...(proxy && proxy.host && proxy.port
|
|
@@ -48,28 +27,20 @@ async function connect({
|
|
|
48
27
|
: []),
|
|
49
28
|
];
|
|
50
29
|
} else {
|
|
51
|
-
//
|
|
30
|
+
// Use DEFAULT_FLAGS from brave-real-launcher
|
|
52
31
|
const flags = [...DEFAULT_FLAGS];
|
|
53
|
-
|
|
54
|
-
const indexDisableFeatures = flags.findIndex((flag) => flag.startsWith('--disable-features'));
|
|
55
|
-
flags[indexDisableFeatures] = `${flags[indexDisableFeatures]},AutomationControlled`;
|
|
56
|
-
// Remove "disable-component-update" flag
|
|
57
|
-
const indexComponentUpdateFlag = flags.findIndex((flag) => flag.startsWith('--disable-component-update'));
|
|
58
|
-
flags.splice(indexComponentUpdateFlag, 1);
|
|
59
|
-
chromeFlags = [
|
|
32
|
+
braveFlags = [
|
|
60
33
|
...flags,
|
|
61
34
|
...args,
|
|
62
35
|
...(headless !== false ? [`--headless=${headless}`] : []),
|
|
63
36
|
...(proxy && proxy.host && proxy.port
|
|
64
37
|
? [`--proxy-server=${proxy.host}:${proxy.port}`]
|
|
65
38
|
: []),
|
|
66
|
-
"--no-sandbox",
|
|
67
|
-
"--disable-dev-shm-usage",
|
|
68
39
|
];
|
|
69
40
|
}
|
|
70
|
-
const
|
|
41
|
+
const brave = await launch({
|
|
71
42
|
ignoreDefaultFlags: true,
|
|
72
|
-
|
|
43
|
+
braveFlags,
|
|
73
44
|
...customConfig,
|
|
74
45
|
});
|
|
75
46
|
|
|
@@ -84,26 +55,28 @@ async function connect({
|
|
|
84
55
|
}
|
|
85
56
|
|
|
86
57
|
const browser = await puppeteer.connect({
|
|
87
|
-
browserURL: `http://127.0.0.1:${
|
|
58
|
+
browserURL: `http://127.0.0.1:${brave.port}`,
|
|
59
|
+
defaultViewport: null, // Full window content - no viewport restriction
|
|
88
60
|
...connectOption,
|
|
89
61
|
});
|
|
90
62
|
|
|
91
63
|
let [page] = await browser.pages();
|
|
92
64
|
|
|
65
|
+
let xvfbsession = null;
|
|
93
66
|
let pageControllerConfig = {
|
|
94
67
|
browser,
|
|
95
68
|
page,
|
|
96
69
|
proxy,
|
|
97
70
|
turnstile,
|
|
98
71
|
xvfbsession,
|
|
99
|
-
pid:
|
|
72
|
+
pid: brave.pid,
|
|
100
73
|
plugins,
|
|
101
74
|
};
|
|
102
75
|
|
|
103
76
|
page = await pageController({
|
|
104
77
|
...pageControllerConfig,
|
|
105
78
|
killProcess: true,
|
|
106
|
-
|
|
79
|
+
brave,
|
|
107
80
|
});
|
|
108
81
|
|
|
109
82
|
browser.on("targetcreated", async (target) => {
|
|
@@ -2,175 +2,68 @@ const { createCursor } = require('ghost-cursor');
|
|
|
2
2
|
const { checkTurnstile } = require('./turnstile.js');
|
|
3
3
|
const kill = require('tree-kill');
|
|
4
4
|
|
|
5
|
-
// Configuration constants
|
|
6
|
-
const TURNSTILE_CHECK_INTERVAL = 1000; // 1 second
|
|
7
|
-
const TURNSTILE_MAX_ATTEMPTS = 300; // 5 minutes max (300 attempts * 1 second)
|
|
8
|
-
const TURNSTILE_TIMEOUT = 300000; // 5 minutes in milliseconds
|
|
9
|
-
|
|
10
5
|
function getRandomInt(min, max) {
|
|
11
6
|
min = Math.ceil(min);
|
|
12
7
|
max = Math.floor(max);
|
|
13
8
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
14
9
|
}
|
|
15
10
|
|
|
16
|
-
async function pageController({ browser, page, proxy, turnstile, xvfbsession, pid, plugins, killProcess = false,
|
|
17
|
-
|
|
18
|
-
let solveStatus = turnstile;
|
|
19
|
-
let turnstileSolverRunning = false;
|
|
11
|
+
async function pageController({ browser, page, proxy, turnstile, xvfbsession, pid, plugins, killProcess = false, brave }) {
|
|
20
12
|
|
|
21
|
-
|
|
22
|
-
const cleanup = async () => {
|
|
23
|
-
solveStatus = false;
|
|
24
|
-
if (killProcess === true) {
|
|
25
|
-
if (xvfbsession) {
|
|
26
|
-
try {
|
|
27
|
-
xvfbsession.stopSync();
|
|
28
|
-
} catch (err) {
|
|
29
|
-
console.error('Error stopping Xvfb session:', err.message);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
if (chrome) {
|
|
33
|
-
try {
|
|
34
|
-
chrome.kill();
|
|
35
|
-
} catch (err) {
|
|
36
|
-
console.error('Error killing Chrome process:', err.message);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
if (pid) {
|
|
40
|
-
try {
|
|
41
|
-
kill(pid, 'SIGKILL', (err) => {
|
|
42
|
-
if (err) console.error('Error killing process:', err.message);
|
|
43
|
-
});
|
|
44
|
-
} catch (err) {
|
|
45
|
-
console.error('Error in kill command:', err.message);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
};
|
|
13
|
+
let solveStatus = turnstile
|
|
50
14
|
|
|
51
15
|
page.on('close', () => {
|
|
52
|
-
solveStatus = false
|
|
16
|
+
solveStatus = false
|
|
53
17
|
});
|
|
54
18
|
|
|
19
|
+
|
|
55
20
|
browser.on('disconnected', async () => {
|
|
56
|
-
|
|
21
|
+
solveStatus = false
|
|
22
|
+
if (killProcess === true) {
|
|
23
|
+
if (xvfbsession) try { xvfbsession.stopSync() } catch (err) { }
|
|
24
|
+
if (brave) try { brave.kill() } catch (err) { console.log(err); }
|
|
25
|
+
if (pid) try { kill(pid, 'SIGKILL', () => { }) } catch (err) { }
|
|
26
|
+
}
|
|
57
27
|
});
|
|
58
28
|
|
|
59
|
-
// Enhanced turnstile solver with timeout and max attempts protection
|
|
60
29
|
async function turnstileSolver() {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
turnstileSolverRunning = true;
|
|
67
|
-
const startTime = Date.now();
|
|
68
|
-
let attempts = 0;
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
while (solveStatus && attempts < TURNSTILE_MAX_ATTEMPTS) {
|
|
72
|
-
// Check timeout
|
|
73
|
-
if (Date.now() - startTime > TURNSTILE_TIMEOUT) {
|
|
74
|
-
console.warn('Turnstile solver timeout reached after', attempts, 'attempts');
|
|
75
|
-
break;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Check if page is still valid
|
|
79
|
-
if (page.isClosed()) {
|
|
80
|
-
console.log('Page closed, stopping turnstile solver');
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
attempts++;
|
|
85
|
-
|
|
86
|
-
try {
|
|
87
|
-
await checkTurnstile({ page });
|
|
88
|
-
} catch (err) {
|
|
89
|
-
// Silent fail for individual checks, log only if debug enabled
|
|
90
|
-
if (process.env.DEBUG === 'true') {
|
|
91
|
-
console.debug('Turnstile check failed:', err.message);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Wait before next check
|
|
96
|
-
await new Promise(r => setTimeout(r, TURNSTILE_CHECK_INTERVAL));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (attempts >= TURNSTILE_MAX_ATTEMPTS) {
|
|
100
|
-
console.warn('Turnstile solver stopped: max attempts reached');
|
|
101
|
-
}
|
|
102
|
-
} catch (err) {
|
|
103
|
-
console.error('Error in turnstile solver:', err.message);
|
|
104
|
-
} finally {
|
|
105
|
-
turnstileSolverRunning = false;
|
|
30
|
+
while (solveStatus) {
|
|
31
|
+
await checkTurnstile({ page }).catch(() => { });
|
|
32
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
106
33
|
}
|
|
34
|
+
return
|
|
107
35
|
}
|
|
108
36
|
|
|
109
|
-
|
|
110
|
-
if (turnstile) {
|
|
111
|
-
turnstileSolver().catch(err => {
|
|
112
|
-
console.error('Failed to start turnstile solver:', err.message);
|
|
113
|
-
});
|
|
114
|
-
}
|
|
37
|
+
turnstileSolver()
|
|
115
38
|
|
|
116
|
-
|
|
117
|
-
if (proxy && proxy.username && proxy.password) {
|
|
118
|
-
try {
|
|
119
|
-
await page.authenticate({
|
|
120
|
-
username: proxy.username,
|
|
121
|
-
password: proxy.password
|
|
122
|
-
});
|
|
123
|
-
} catch (err) {
|
|
124
|
-
console.error('Proxy authentication failed:', err.message);
|
|
125
|
-
throw new Error(`Failed to authenticate proxy: ${err.message}`);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
39
|
+
if (proxy.username && proxy.password) await page.authenticate({ username: proxy.username, password: proxy.password });
|
|
128
40
|
|
|
129
|
-
|
|
130
|
-
if (plugins && plugins.length > 0) {
|
|
41
|
+
if (plugins.length > 0) {
|
|
131
42
|
for (const plugin of plugins) {
|
|
132
|
-
|
|
133
|
-
if (plugin && typeof plugin.onPageCreated === 'function') {
|
|
134
|
-
await plugin.onPageCreated(page);
|
|
135
|
-
}
|
|
136
|
-
} catch (err) {
|
|
137
|
-
console.error('Plugin initialization failed:', err.message);
|
|
138
|
-
// Continue with other plugins even if one fails
|
|
139
|
-
}
|
|
43
|
+
plugin.onPageCreated(page)
|
|
140
44
|
}
|
|
141
45
|
}
|
|
142
46
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return this.clientX + window.screenX;
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
Object.defineProperty(MouseEvent.prototype, 'screenY', {
|
|
153
|
-
get: function () {
|
|
154
|
-
return this.clientY + window.screenY;
|
|
155
|
-
}
|
|
156
|
-
});
|
|
47
|
+
await page.evaluateOnNewDocument(() => {
|
|
48
|
+
Object.defineProperty(MouseEvent.prototype, 'screenX', {
|
|
49
|
+
get: function () {
|
|
50
|
+
return this.clientX + window.screenX;
|
|
51
|
+
}
|
|
157
52
|
});
|
|
158
|
-
} catch (err) {
|
|
159
|
-
console.error('Failed to setup mouse event handlers:', err.message);
|
|
160
|
-
// Non-critical, continue anyway
|
|
161
|
-
}
|
|
162
53
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
54
|
+
Object.defineProperty(MouseEvent.prototype, 'screenY', {
|
|
55
|
+
get: function () {
|
|
56
|
+
return this.clientY + window.screenY;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const cursor = createCursor(page);
|
|
63
|
+
page.realCursor = cursor
|
|
64
|
+
page.realClick = cursor.click
|
|
172
65
|
|
|
173
|
-
return page
|
|
66
|
+
return page
|
|
174
67
|
}
|
|
175
68
|
|
|
176
69
|
module.exports = { pageController }
|
package/lib/esm/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { launch, DEFAULT_FLAGS } from "brave-real-launcher";
|
|
1
|
+
import { launch, BraveLauncher, DEFAULT_FLAGS } from "brave-real-launcher";
|
|
2
2
|
import puppeteer from "brave-real-puppeteer-core";
|
|
3
3
|
import { pageController } from "./module/pageController.mjs";
|
|
4
4
|
|
|
@@ -14,28 +14,11 @@ export async function connect({
|
|
|
14
14
|
plugins = [],
|
|
15
15
|
ignoreAllFlags = false,
|
|
16
16
|
} = {}) {
|
|
17
|
-
let xvfbsession = null;
|
|
18
|
-
if (headless == "auto") headless = false;
|
|
19
17
|
|
|
20
|
-
if (process.platform === "linux" && disableXvfb === false) {
|
|
21
|
-
try {
|
|
22
|
-
const { default: Xvfb } = await import("xvfb");
|
|
23
|
-
xvfbsession = new Xvfb({
|
|
24
|
-
silent: true,
|
|
25
|
-
xvfb_args: ["-screen", "0", "1920x1080x24", "-ac"],
|
|
26
|
-
});
|
|
27
|
-
xvfbsession.startSync();
|
|
28
|
-
} catch (err) {
|
|
29
|
-
console.log(
|
|
30
|
-
"You are running on a Linux platform but do not have xvfb installed. The browser can be captured. Please install it with the following command\n\nsudo apt-get install xvfb\n\n" +
|
|
31
|
-
err.message
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
18
|
|
|
36
|
-
let
|
|
19
|
+
let braveFlags;
|
|
37
20
|
if (ignoreAllFlags === true) {
|
|
38
|
-
|
|
21
|
+
braveFlags = [
|
|
39
22
|
...args,
|
|
40
23
|
...(headless !== false ? [`--headless=${headless}`] : []),
|
|
41
24
|
...(proxy && proxy.host && proxy.port
|
|
@@ -43,28 +26,20 @@ export async function connect({
|
|
|
43
26
|
: []),
|
|
44
27
|
];
|
|
45
28
|
} else {
|
|
46
|
-
//
|
|
29
|
+
// Use DEFAULT_FLAGS from brave-real-launcher
|
|
47
30
|
const flags = [...DEFAULT_FLAGS];
|
|
48
|
-
|
|
49
|
-
const indexDisableFeatures = flags.findIndex((flag) => flag.startsWith('--disable-features'));
|
|
50
|
-
flags[indexDisableFeatures] = `${flags[indexDisableFeatures]},AutomationControlled`;
|
|
51
|
-
// Remove "disable-component-update" flag
|
|
52
|
-
const indexComponentUpdateFlag = flags.findIndex((flag) => flag.startsWith('--disable-component-update'));
|
|
53
|
-
flags.splice(indexComponentUpdateFlag, 1);
|
|
54
|
-
chromeFlags = [
|
|
31
|
+
braveFlags = [
|
|
55
32
|
...flags,
|
|
56
33
|
...args,
|
|
57
34
|
...(headless !== false ? [`--headless=${headless}`] : []),
|
|
58
35
|
...(proxy && proxy.host && proxy.port
|
|
59
36
|
? [`--proxy-server=${proxy.host}:${proxy.port}`]
|
|
60
37
|
: []),
|
|
61
|
-
"--no-sandbox",
|
|
62
|
-
"--disable-dev-shm-usage",
|
|
63
38
|
];
|
|
64
39
|
}
|
|
65
|
-
const
|
|
40
|
+
const brave = await launch({
|
|
66
41
|
ignoreDefaultFlags: true,
|
|
67
|
-
|
|
42
|
+
braveFlags,
|
|
68
43
|
...customConfig,
|
|
69
44
|
});
|
|
70
45
|
let pextra = null;
|
|
@@ -79,25 +54,27 @@ export async function connect({
|
|
|
79
54
|
}
|
|
80
55
|
|
|
81
56
|
const browser = await (pextra ? pextra : puppeteer).connect({
|
|
82
|
-
browserURL: `http://127.0.0.1:${
|
|
57
|
+
browserURL: `http://127.0.0.1:${brave.port}`,
|
|
58
|
+
defaultViewport: null, // Full window content - no viewport restriction
|
|
83
59
|
...connectOption,
|
|
84
60
|
});
|
|
85
61
|
|
|
86
62
|
let [page] = await browser.pages();
|
|
87
63
|
|
|
64
|
+
let xvfbsession = null;
|
|
88
65
|
let pageControllerConfig = {
|
|
89
66
|
browser,
|
|
90
67
|
page,
|
|
91
68
|
proxy,
|
|
92
69
|
turnstile,
|
|
93
70
|
xvfbsession,
|
|
94
|
-
pid:
|
|
71
|
+
pid: brave.pid,
|
|
95
72
|
plugins,
|
|
96
73
|
};
|
|
97
74
|
|
|
98
75
|
page = await pageController({
|
|
99
76
|
...pageControllerConfig,
|
|
100
|
-
|
|
77
|
+
brave,
|
|
101
78
|
killProcess: true,
|
|
102
79
|
});
|
|
103
80
|
|