real-browser-mcp-server 1.2.0 → 1.2.1
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 +82 -9
- package/dist/lib/cjs/index.d.ts +2 -0
- package/dist/lib/cjs/index.d.ts.map +1 -0
- package/dist/lib/cjs/index.js +385 -0
- package/dist/lib/cjs/index.js.map +1 -0
- package/dist/lib/cjs/module/pageController.d.ts +2 -0
- package/dist/lib/cjs/module/pageController.d.ts.map +1 -0
- package/{lib → dist/lib}/cjs/module/pageController.js +28 -29
- package/dist/lib/cjs/module/pageController.js.map +1 -0
- package/dist/lib/cjs/module/turnstile.d.ts +2 -0
- package/dist/lib/cjs/module/turnstile.d.ts.map +1 -0
- package/{lib → dist/lib}/cjs/module/turnstile.js +24 -12
- package/dist/lib/cjs/module/turnstile.js.map +1 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +118 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/mcp/handlers/browser.d.ts +30 -0
- package/dist/src/mcp/handlers/browser.d.ts.map +1 -0
- package/dist/src/mcp/handlers/browser.js +231 -0
- package/dist/src/mcp/handlers/browser.js.map +1 -0
- package/dist/src/mcp/handlers/dom.d.ts +134 -0
- package/dist/src/mcp/handlers/dom.d.ts.map +1 -0
- package/dist/src/mcp/handlers/dom.js +551 -0
- package/dist/src/mcp/handlers/dom.js.map +1 -0
- package/dist/src/mcp/handlers/extract.d.ts +59 -0
- package/dist/src/mcp/handlers/extract.d.ts.map +1 -0
- package/dist/src/mcp/handlers/extract.js +455 -0
- package/dist/src/mcp/handlers/extract.js.map +1 -0
- package/dist/src/mcp/handlers/form-handlers.d.ts +9 -0
- package/dist/src/mcp/handlers/form-handlers.d.ts.map +1 -0
- package/dist/src/mcp/handlers/form-handlers.js +56 -0
- package/dist/src/mcp/handlers/form-handlers.js.map +1 -0
- package/dist/src/mcp/handlers/helpers.d.ts +47 -0
- package/dist/src/mcp/handlers/helpers.d.ts.map +1 -0
- package/dist/src/mcp/handlers/helpers.js +515 -0
- package/dist/src/mcp/handlers/helpers.js.map +1 -0
- package/dist/src/mcp/handlers/index.d.ts +6 -0
- package/dist/src/mcp/handlers/index.d.ts.map +1 -0
- package/dist/src/mcp/handlers/index.js +61 -0
- package/dist/src/mcp/handlers/index.js.map +1 -0
- package/dist/src/mcp/handlers/media-handlers.d.ts +10 -0
- package/dist/src/mcp/handlers/media-handlers.d.ts.map +1 -0
- package/dist/src/mcp/handlers/media-handlers.js +535 -0
- package/dist/src/mcp/handlers/media-handlers.js.map +1 -0
- package/dist/src/mcp/handlers/network.d.ts +147 -0
- package/dist/src/mcp/handlers/network.d.ts.map +1 -0
- package/dist/src/mcp/handlers/network.js +1135 -0
- package/dist/src/mcp/handlers/network.js.map +1 -0
- package/dist/src/mcp/handlers/state.d.ts +34 -0
- package/dist/src/mcp/handlers/state.d.ts.map +1 -0
- package/dist/src/mcp/handlers/state.js +225 -0
- package/dist/src/mcp/handlers/state.js.map +1 -0
- package/dist/src/mcp/handlers/utility-handlers.d.ts +167 -0
- package/dist/src/mcp/handlers/utility-handlers.d.ts.map +1 -0
- package/dist/src/mcp/handlers/utility-handlers.js +280 -0
- package/dist/src/mcp/handlers/utility-handlers.js.map +1 -0
- package/dist/src/mcp/handlers/vision.d.ts +127 -0
- package/dist/src/mcp/handlers/vision.d.ts.map +1 -0
- package/dist/src/mcp/handlers/vision.js +483 -0
- package/dist/src/mcp/handlers/vision.js.map +1 -0
- package/dist/src/mcp/index.d.ts +3 -0
- package/dist/src/mcp/index.d.ts.map +1 -0
- package/dist/src/mcp/index.js +166 -0
- package/dist/src/mcp/index.js.map +1 -0
- package/dist/src/mcp/server.d.ts +2 -0
- package/dist/src/mcp/server.d.ts.map +1 -0
- package/dist/src/mcp/server.js +117 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/mcp/tools.d.ts +8 -0
- package/dist/src/mcp/tools.d.ts.map +1 -0
- package/{src → dist/src}/mcp/tools.js +12 -11
- package/dist/src/mcp/tools.js.map +1 -0
- package/dist/src/shared/cache-manager.d.ts +80 -0
- package/dist/src/shared/cache-manager.d.ts.map +1 -0
- package/dist/src/shared/cache-manager.js +221 -0
- package/dist/src/shared/cache-manager.js.map +1 -0
- package/dist/src/shared/tools.d.ts +2 -0
- package/dist/src/shared/tools.d.ts.map +1 -0
- package/dist/src/shared/tools.js +599 -0
- package/dist/src/shared/tools.js.map +1 -0
- package/dist/src/types.d.ts +365 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +9 -0
- package/dist/src/types.js.map +1 -0
- package/dist/test/cjs/test.d.ts +11 -0
- package/dist/test/cjs/test.d.ts.map +1 -0
- package/dist/test/cjs/test.js +289 -0
- package/dist/test/cjs/test.js.map +1 -0
- package/dist/test/mcp/smoke-test.d.ts +29 -0
- package/dist/test/mcp/smoke-test.d.ts.map +1 -0
- package/dist/test/mcp/smoke-test.js +132 -0
- package/dist/test/mcp/smoke-test.js.map +1 -0
- package/lib/esm/index.mjs +232 -79
- package/lib/esm/module/pageController.mjs +21 -18
- package/lib/esm/module/turnstile.mjs +7 -0
- package/package.json +25 -15
- package/typings.d.ts +12 -6
- package/.github/ISSUE_TEMPLATE/general_issue.yaml +0 -58
- package/.github/SETUP.md +0 -111
- package/.github/workflows/publish.yml +0 -135
- package/Dockerfile +0 -79
- package/lib/cjs/adblocker.bin +0 -0
- package/lib/cjs/index.js +0 -249
- package/src/ai/action-parser.js +0 -274
- package/src/ai/core.js +0 -378
- package/src/ai/element-finder.js +0 -466
- package/src/ai/index.js +0 -82
- package/src/ai/page-analyzer.js +0 -304
- package/src/ai/selector-healer.js +0 -236
- package/src/index.js +0 -121
- package/src/mcp/handlers.js +0 -5071
- package/src/mcp/index.js +0 -190
- package/src/mcp/server.js +0 -144
- package/src/shared/tools.js +0 -618
- package/test/cjs/test.js +0 -259
- package/test/esm/package.json +0 -13
- package/test/esm/test.js +0 -226
- package/test/esm/test_option2.js +0 -46
- package/test/esm/test_playwright_ghost.js +0 -30
package/README.md
CHANGED
|
@@ -11,13 +11,35 @@ This server is **100% compatible with all major AI IDEs** (Cursor, VS Code, Clin
|
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
+
## ⚙️ Installation & Setup
|
|
15
|
+
|
|
16
|
+
To install and run the server locally, clone the repository, install NPM dependencies, and configure the undetected browser binary using **Patchright**:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# 1. Clone the repository
|
|
20
|
+
git clone https://github.com/codeiva4u/Real-Browser-Mcp-Server.git
|
|
21
|
+
|
|
22
|
+
# 2. Navigate to the project directory
|
|
23
|
+
cd Real-Browser-Mcp-Server
|
|
24
|
+
|
|
25
|
+
# 3. Install dependencies
|
|
26
|
+
npm install
|
|
27
|
+
|
|
28
|
+
# 4. Install Chromium-Driver for Patchright (Undetected Browser binary)
|
|
29
|
+
npx patchright install chromium
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
14
34
|
## 🚀 Key Evasion & Stealth Features
|
|
15
35
|
|
|
16
36
|
* **Undetected Browser Engine**: Powered by **Patchright Chromium**, bypassing modern fingerprinting checks (does not expose automation indicators or Webdriver/BiDi flags).
|
|
17
37
|
* **Integrated Ad & Tracker Blocker**: Utilizes `@ghostery/adblocker-playwright` with asynchronous pre-compiled filter caching to `adblocker.bin`, blocking ads and speed-bumps completely offline.
|
|
18
|
-
* **Human-like Interactions**: Integrates **
|
|
38
|
+
* **Human-like Interactions**: Integrates **ghost-cursor-patchright** (Bézier curves) to transparently simulate human mouse movements, velocity, and natural hover-before-click behaviors. Features **Physics-based Smooth Scrolling** (`page.realScroll`) utilizing real mouse-wheel events and Cubic Ease-Out deceleration to perfectly mimic manual trackpad/mouse flicks, bypassing advanced behavioral detectors.
|
|
19
39
|
* **Turnstile Auto-Solver**: Seamlessly detects and bypasses Cloudflare Turnstile widgets.
|
|
20
40
|
* **Anti-Race Condition Guards**: Robust state-guards ensure popup blockers, shims, and adblockers attach exactly once per page, preventing context destruction.
|
|
41
|
+
* **100% Type-Safe**: Entire codebase is written in Strict Mode TypeScript (`strict: true`) ensuring maximum stability and zero runtime casting errors.
|
|
42
|
+
* **Global Persistent Cache**: Internal `CacheManager` saves browser state and extracted data persistently across server restarts to `.cache/browser_state.json`.
|
|
21
43
|
|
|
22
44
|
---
|
|
23
45
|
|
|
@@ -60,14 +82,17 @@ Add the server entry to your global MCP settings file (typically found at `%APPD
|
|
|
60
82
|
{
|
|
61
83
|
"mcpServers": {
|
|
62
84
|
"real-browser-mcp-server": {
|
|
63
|
-
"
|
|
85
|
+
"type": "stdio",
|
|
86
|
+
"command": "C:/Program Files/nodejs/node.exe",
|
|
64
87
|
"args": [
|
|
65
88
|
"c:/Users/Admin/Desktop/Software/Real-Browser-Mcp-Server/src/index.js"
|
|
66
89
|
],
|
|
67
90
|
"env": {
|
|
68
91
|
"HEADLESS": "false"
|
|
69
92
|
},
|
|
70
|
-
"disabled": false
|
|
93
|
+
"disabled": false,
|
|
94
|
+
"autoApprove": [],
|
|
95
|
+
"timeout": 120
|
|
71
96
|
}
|
|
72
97
|
}
|
|
73
98
|
}
|
|
@@ -116,9 +141,9 @@ Configure the server in your `opencode.jsonc` or standard MCP settings configura
|
|
|
116
141
|
|
|
117
142
|
---
|
|
118
143
|
|
|
119
|
-
## 🌐 Complete MCP Tool Reference (
|
|
144
|
+
## 🌐 Complete MCP Tool Reference (23 Tools)
|
|
120
145
|
|
|
121
|
-
The server exposes
|
|
146
|
+
The server exposes 23 highly optimized tools categorized into functional units:
|
|
122
147
|
|
|
123
148
|
### 🌐 Browser & Session
|
|
124
149
|
| Tool Name | Description | Parameters |
|
|
@@ -135,10 +160,10 @@ The server exposes 22 highly optimized tools categorized into functional units:
|
|
|
135
160
|
### 👆 Human-like Interaction
|
|
136
161
|
| Tool Name | Description | Parameters |
|
|
137
162
|
|:---|:---|:---|
|
|
138
|
-
| `click` | Human-like click using
|
|
163
|
+
| `click` | Human-like click using ghost cursor and iframe support. | `selector` (string), `hoverFirst` (boolean) |
|
|
139
164
|
| `type` | Type text with human speed variation, smart clearing, and iframe support. | `selector` (string), `text` (string) |
|
|
140
165
|
| `solve_captcha` | Auto-solve CAPTCHAs (Turnstile, reCAPTCHA, hCaptcha, OCR). | `selector` (string) |
|
|
141
|
-
| `random_scroll` | Simulated human scrolling with natural patterns and lazy-load triggers. | `direction` (string), `amount` (number) |
|
|
166
|
+
| `random_scroll` | Simulated human scrolling with natural patterns and lazy-load triggers. | `direction` (string), `amount` (number), `smooth` (boolean) |
|
|
142
167
|
| `press_key` | Press keyboard keys with modifier key support (Ctrl/Shift/Alt). | `key` (string), `modifiers` (array) |
|
|
143
168
|
| `execute_js` | Run custom asynchronous/synchronous JavaScript inside a page or iframe. | `code` (string), `iframeIndex` (number) |
|
|
144
169
|
|
|
@@ -146,7 +171,7 @@ The server exposes 22 highly optimized tools categorized into functional units:
|
|
|
146
171
|
| Tool Name | Description | Parameters |
|
|
147
172
|
|:---|:---|:---|
|
|
148
173
|
| `get_content` | Retrieve page content in `html`, `text`, `markdown`, or direct `rawHttp` modes. | `format` (string) |
|
|
149
|
-
| `find_element` | Locate elements via CSS selectors, XPath, or exact text
|
|
174
|
+
| `find_element` | Locate elements via CSS selectors, XPath, or exact text. | `selector` (string), `strategy` (string) |
|
|
150
175
|
| `save_content_as_markdown` | Export current page content as clean, readable Markdown, stripping ads. | `filename` (string) |
|
|
151
176
|
| `extract_data` | Advanced 8-mode extractor (Regex, JSON, Meta tags, JS Deobfuscator, Cryptography). | `mode` (string), `target` (string) |
|
|
152
177
|
| `link_harvester` | Scrapes all visible, hidden, iframe-nested, or encoded links on a page. | None |
|
|
@@ -162,6 +187,13 @@ The server exposes 22 highly optimized tools categorized into functional units:
|
|
|
162
187
|
| `wait` | Smart delay with AI prediction or static timeout. | `duration` (number) |
|
|
163
188
|
| `progress_tracker` | Track running automation progress with AI-estimated remaining times. | `step` (string), `percentage` (number) |
|
|
164
189
|
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
### 👁️ AI Vision (Eyes)
|
|
193
|
+
| Tool Name | Description | Parameters |
|
|
194
|
+
|:---|:---|:---|
|
|
195
|
+
| `see_page` | Lets the AI **visually SEE** the page like human eyes: returns the actual screenshot image to the agent **plus** a "visual map" of every visible interactive element (button/link/input) with its on-screen position, text label, and a click-ready selector. Use it to look before deciding where to click/type. | `fullPage` (boolean), `format` (png/jpeg), `includeElements` (boolean), `maxElements` (number) |
|
|
196
|
+
|
|
165
197
|
---
|
|
166
198
|
|
|
167
199
|
## 📈 Evasion Performance & Test Coverage
|
|
@@ -180,6 +212,39 @@ Our test suites run headless/headed simulations against all major fingerprinting
|
|
|
180
212
|
| **CreepJS Fingerprinting** | Advanced trust rating and fingerprint check | ✅ Pass |
|
|
181
213
|
| **Pixelscan Fingerprint** | Masque & Canvas fingerprint masking check | ✅ Pass (No Masking Detected) |
|
|
182
214
|
|
|
215
|
+
### 🧪 Local Test Suite Execution Status
|
|
216
|
+
|
|
217
|
+
Both the CommonJS and ES Module test suites execute and pass successfully under Node.js:
|
|
218
|
+
|
|
219
|
+
| Test Suite / Environment | Test Case | Status |
|
|
220
|
+
|:---|:---|:---|
|
|
221
|
+
| **CommonJS (`cjs_test`)** | DrissionPage Detector | ✅ Passed |
|
|
222
|
+
| **CommonJS (`cjs_test`)** | Sannysoft WebDriver Detector | ✅ Passed |
|
|
223
|
+
| **CommonJS (`cjs_test`)** | Cloudflare WAF | ✅ Passed |
|
|
224
|
+
| **CommonJS (`cjs_test`)** | Cloudflare Turnstile | ✅ Passed |
|
|
225
|
+
| **CommonJS (`cjs_test`)** | Fingerprint JS Bot Detector | ✅ Passed |
|
|
226
|
+
| **CommonJS (`cjs_test`)** | Recaptcha V3 Score | ✅ Passed |
|
|
227
|
+
| **CommonJS (`cjs_test`)** | Pixelscan Fingerprint Check | ✅ Passed |
|
|
228
|
+
| **CommonJS (`cjs_test`)** | Human-like Move & Click | ✅ Passed |
|
|
229
|
+
| **CommonJS (`cjs_test`)** | Human-like Typing | ✅ Passed |
|
|
230
|
+
| **CommonJS (`cjs_test`)** | Human-like Scrolling | ✅ Passed |
|
|
231
|
+
| **CommonJS (`cjs_test`)** | Form Automation Demonstration | ✅ Passed |
|
|
232
|
+
| **CommonJS (`cjs_test`)** | Content Strategy Demonstration | ✅ Passed |
|
|
233
|
+
| **ES Module (`esm_test`)** | DrissionPage Detector | ✅ Passed |
|
|
234
|
+
| **ES Module (`esm_test`)** | Sannysoft WebDriver Detector | ✅ Passed |
|
|
235
|
+
| **ES Module (`esm_test`)** | Cloudflare WAF | ✅ Passed |
|
|
236
|
+
| **ES Module (`esm_test`)** | Cloudflare Turnstile | ✅ Passed |
|
|
237
|
+
| **ES Module (`esm_test`)** | Fingerprint JS Bot Detector | ✅ Passed |
|
|
238
|
+
| **ES Module (`esm_test`)** | Recaptcha V3 Score | ✅ Passed |
|
|
239
|
+
| **ES Module (`esm_test`)** | Pixelscan Fingerprint Check | ✅ Passed |
|
|
240
|
+
| **ES Module (`esm_test`)** | Human-like Move & Click | ✅ Passed |
|
|
241
|
+
| **ES Module (`esm_test`)** | Human-like Typing | ✅ Passed |
|
|
242
|
+
| **ES Module (`esm_test`)** | Human-like Scrolling | ✅ Passed |
|
|
243
|
+
| **ES Module (`esm_test`)** | Form Automation Demonstration | ✅ Passed |
|
|
244
|
+
| **ES Module (`esm_test`)** | Content Strategy Demonstration | ✅ Passed |
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
183
248
|
---
|
|
184
249
|
|
|
185
250
|
## 💻 Programmatic Usage (Node.js SDK)
|
|
@@ -201,6 +266,9 @@ const { connect } = require('real-browser-mcp-server');
|
|
|
201
266
|
// Real mouse movement and click
|
|
202
267
|
await page.realClick('#my-button');
|
|
203
268
|
|
|
269
|
+
// Real human-like smooth scrolling (60FPS Cubic Ease-Out physics)
|
|
270
|
+
await page.realScroll(400); // scrolls down 400px smoothly
|
|
271
|
+
|
|
204
272
|
await browser.close();
|
|
205
273
|
})();
|
|
206
274
|
```
|
|
@@ -216,6 +284,10 @@ const { browser, page } = await connect({
|
|
|
216
284
|
|
|
217
285
|
await page.goto('https://example.com');
|
|
218
286
|
await page.realClick('#my-button');
|
|
287
|
+
|
|
288
|
+
// Real human-like smooth scrolling (60FPS Cubic Ease-Out physics)
|
|
289
|
+
await page.realScroll(400); // scrolls down 400px smoothly
|
|
290
|
+
|
|
219
291
|
await browser.close();
|
|
220
292
|
```
|
|
221
293
|
|
|
@@ -231,11 +303,12 @@ Run these scripts from the project root directory:
|
|
|
231
303
|
| `npm run dev` | Alias to start the MCP server. |
|
|
232
304
|
| `npm run mcp` | Start the MCP server. |
|
|
233
305
|
| `npm run mcp:verbose` | Start the MCP server with verbose logging on `stderr`. |
|
|
234
|
-
| `npm run list` | Clean list of all
|
|
306
|
+
| `npm run list` | Clean list of all 23 tools with emojis and categories. |
|
|
235
307
|
| `npm run build` | Validate workspace structure and confirm library status. |
|
|
236
308
|
| `npm test` | Execute the full test suite (CJS & ESM). |
|
|
237
309
|
| `npm run cjs_test` | Run CommonJS test scripts. |
|
|
238
310
|
| `npm run esm_test` | Run ECMAScript Module test scripts. |
|
|
311
|
+
| `npm run mcp_test` | Fast, network-independent MCP smoke test (handshake + tool registry validation). |
|
|
239
312
|
|
|
240
313
|
---
|
|
241
314
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/cjs/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const { chromium } = require("patchright");
|
|
4
|
+
const { createCursor } = require("ghost-cursor-patchright");
|
|
5
|
+
const { PlaywrightBlocker } = require("@ghostery/adblocker-playwright");
|
|
6
|
+
const { pageController } = require("./module/pageController.js");
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
let adBlockerInstance = null;
|
|
10
|
+
let adBlockerPromise = null;
|
|
11
|
+
function getAdBlocker() {
|
|
12
|
+
if (!adBlockerPromise) {
|
|
13
|
+
const cachePath = path.join(__dirname, 'adblocker.bin');
|
|
14
|
+
adBlockerPromise = PlaywrightBlocker.fromPrebuiltAdsAndTracking(fetch, {
|
|
15
|
+
path: cachePath,
|
|
16
|
+
read: fs.promises.readFile,
|
|
17
|
+
write: fs.promises.writeFile,
|
|
18
|
+
}).then(blocker => {
|
|
19
|
+
adBlockerInstance = blocker;
|
|
20
|
+
return blocker;
|
|
21
|
+
}).catch(err => {
|
|
22
|
+
console.error('[adblocker] Failed to initialize adblocker:', err.message);
|
|
23
|
+
return null;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return adBlockerPromise;
|
|
27
|
+
}
|
|
28
|
+
function loadEnvFile() {
|
|
29
|
+
const envPaths = [
|
|
30
|
+
path.join(process.cwd(), '.env'),
|
|
31
|
+
];
|
|
32
|
+
let currentDir = process.cwd();
|
|
33
|
+
for (let i = 0; i < 5; i++) {
|
|
34
|
+
const envPath = path.join(currentDir, '.env');
|
|
35
|
+
if (fs.existsSync(envPath) && !envPaths.includes(envPath)) {
|
|
36
|
+
envPaths.push(envPath);
|
|
37
|
+
}
|
|
38
|
+
const parentDir = path.dirname(currentDir);
|
|
39
|
+
if (parentDir === currentDir)
|
|
40
|
+
break;
|
|
41
|
+
currentDir = parentDir;
|
|
42
|
+
}
|
|
43
|
+
for (const envPath of envPaths) {
|
|
44
|
+
try {
|
|
45
|
+
if (fs.existsSync(envPath)) {
|
|
46
|
+
const envContent = fs.readFileSync(envPath, 'utf-8');
|
|
47
|
+
envContent.split('\n').forEach(line => {
|
|
48
|
+
const trimmed = line.trim();
|
|
49
|
+
if (trimmed && !trimmed.startsWith('#')) {
|
|
50
|
+
const [key, ...valueParts] = trimmed.split('=');
|
|
51
|
+
const value = valueParts.join('=').replace(/^["']|["']$/g, '');
|
|
52
|
+
if (key && !process.env[key]) {
|
|
53
|
+
process.env[key] = value;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
// Silently ignore .env loading errors
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
loadEnvFile();
|
|
66
|
+
function getDefaultHeadless() {
|
|
67
|
+
const envHeadless = process.env.HEADLESS;
|
|
68
|
+
if (envHeadless !== undefined && envHeadless !== null && envHeadless !== '') {
|
|
69
|
+
const value = envHeadless.toLowerCase().trim();
|
|
70
|
+
return value === 'true' || value === '1' || value === 'yes';
|
|
71
|
+
}
|
|
72
|
+
// Auto-detect CI environments
|
|
73
|
+
if (process.env.CI || process.env.GITHUB_ACTIONS || process.env.TRAVIS || process.env.CIRCLECI) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
// Auto-detect headless Linux environments without X11 or Wayland
|
|
77
|
+
if (process.platform === 'linux') {
|
|
78
|
+
const hasDisplay = process.env.DISPLAY || process.env.WAYLAND_DISPLAY;
|
|
79
|
+
if (!hasDisplay) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
function setupRealPage(browser, page) {
|
|
86
|
+
if (page._setupApplied)
|
|
87
|
+
return page;
|
|
88
|
+
page._setupApplied = true;
|
|
89
|
+
// Enable ad blocker
|
|
90
|
+
if (adBlockerInstance) {
|
|
91
|
+
adBlockerInstance.enableBlockingInPage(page).catch(() => { });
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
getAdBlocker().then(blocker => {
|
|
95
|
+
if (blocker) {
|
|
96
|
+
blocker.enableBlockingInPage(page).catch(() => { });
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
// Human-like smooth scrolling with 60FPS Cubic Ease-Out physics
|
|
101
|
+
page.realScroll = async (deltaY, duration = 600) => {
|
|
102
|
+
try {
|
|
103
|
+
const stepDelay = 15; // ~60 FPS
|
|
104
|
+
const steps = Math.max(10, Math.floor(duration / stepDelay));
|
|
105
|
+
const easeOutCubic = (t) => 1 - Math.pow(1 - t, 3);
|
|
106
|
+
let currentScroll = 0;
|
|
107
|
+
for (let i = 1; i <= steps; i++) {
|
|
108
|
+
const t = i / steps;
|
|
109
|
+
const targetScroll = deltaY * easeOutCubic(t);
|
|
110
|
+
const diff = targetScroll - currentScroll;
|
|
111
|
+
await page.mouse.wheel(0, diff);
|
|
112
|
+
currentScroll = targetScroll;
|
|
113
|
+
await new Promise(r => setTimeout(r, stepDelay));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
// Fallback to native window scroll in case of wheel errors
|
|
118
|
+
try {
|
|
119
|
+
await page.evaluate((y) => window.scrollBy({ top: y, behavior: 'smooth' }), deltaY);
|
|
120
|
+
}
|
|
121
|
+
catch (_) { }
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
// Ghost Cursor integration - Bézier curve human-like mouse movement
|
|
125
|
+
try {
|
|
126
|
+
const cursor = createCursor(page);
|
|
127
|
+
page.realCursor = {
|
|
128
|
+
move: async (selector, options = {}) => {
|
|
129
|
+
try {
|
|
130
|
+
await cursor.actions.move(selector, options);
|
|
131
|
+
}
|
|
132
|
+
catch (e) {
|
|
133
|
+
// Fallback to native hover if ghost-cursor fails
|
|
134
|
+
try {
|
|
135
|
+
await page.hover(selector);
|
|
136
|
+
}
|
|
137
|
+
catch (_) { }
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
page.realClick = async (selector, options = {}) => {
|
|
142
|
+
try {
|
|
143
|
+
await cursor.actions.click({ target: selector, ...options });
|
|
144
|
+
}
|
|
145
|
+
catch (e) {
|
|
146
|
+
// Fallback to native click if ghost-cursor fails
|
|
147
|
+
await page.click(selector, options);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
catch (e) {
|
|
152
|
+
// Fallback if ghost-cursor-patchright fails to initialize
|
|
153
|
+
if (!page.realClick) {
|
|
154
|
+
page.realClick = async (selector, options) => {
|
|
155
|
+
await page.click(selector, options);
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
if (!page.realCursor) {
|
|
159
|
+
page.realCursor = {
|
|
160
|
+
move: async (selector) => {
|
|
161
|
+
try {
|
|
162
|
+
await page.hover(selector);
|
|
163
|
+
}
|
|
164
|
+
catch (_) { }
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return page;
|
|
170
|
+
}
|
|
171
|
+
function getBraveExecutablePath() {
|
|
172
|
+
if (process.env.BRAVE_PATH && fs.existsSync(process.env.BRAVE_PATH)) {
|
|
173
|
+
return process.env.BRAVE_PATH;
|
|
174
|
+
}
|
|
175
|
+
const platform = process.platform;
|
|
176
|
+
const { execSync } = require('child_process');
|
|
177
|
+
// Try automatic scanning via CLI / registry query
|
|
178
|
+
if (platform === 'win32') {
|
|
179
|
+
const regQueries = [
|
|
180
|
+
'reg query "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\brave.exe" /ve',
|
|
181
|
+
'reg query "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\brave.exe" /ve',
|
|
182
|
+
'reg query "HKEY_LOCAL_MACHINE\\SOFTWARE\\Clients\\StartMenuInternet\\Brave-Browser\\shell\\open\\command" /ve'
|
|
183
|
+
];
|
|
184
|
+
for (const cmd of regQueries) {
|
|
185
|
+
try {
|
|
186
|
+
const output = execSync(cmd, { stdio: ['ignore', 'pipe', 'ignore'] }).toString();
|
|
187
|
+
const match = output.match(/REG_SZ\s+(.*)/);
|
|
188
|
+
if (match && match[1]) {
|
|
189
|
+
let p = match[1].trim().replace(/^"|"$/g, '');
|
|
190
|
+
if (!p.toLowerCase().endsWith('.exe')) {
|
|
191
|
+
const exeIndex = p.toLowerCase().indexOf('.exe');
|
|
192
|
+
if (exeIndex !== -1) {
|
|
193
|
+
p = p.substring(0, exeIndex + 4).replace(/^"|"$/g, '');
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (fs.existsSync(p))
|
|
197
|
+
return p;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch (e) { }
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
const output = execSync('where brave.exe', { stdio: ['ignore', 'pipe', 'ignore'] }).toString().trim().split('\r\n')[0];
|
|
204
|
+
if (output && fs.existsSync(output))
|
|
205
|
+
return output;
|
|
206
|
+
}
|
|
207
|
+
catch (e) { }
|
|
208
|
+
}
|
|
209
|
+
else if (platform === 'darwin') {
|
|
210
|
+
try {
|
|
211
|
+
const output = execSync('mdfind "kMDItemCFBundleIdentifier == \'com.brave.Browser\'"', { stdio: ['ignore', 'pipe', 'ignore'] }).toString().trim().split('\n')[0];
|
|
212
|
+
if (output) {
|
|
213
|
+
const p = path.join(output, 'Contents', 'MacOS', 'Brave Browser');
|
|
214
|
+
if (fs.existsSync(p))
|
|
215
|
+
return p;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch (e) { }
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
try {
|
|
222
|
+
const output = execSync('which brave-browser || which brave', { stdio: ['ignore', 'pipe', 'ignore'] }).toString().trim();
|
|
223
|
+
if (output && fs.existsSync(output))
|
|
224
|
+
return output;
|
|
225
|
+
}
|
|
226
|
+
catch (e) { }
|
|
227
|
+
}
|
|
228
|
+
// Fallback to hardcoded common paths
|
|
229
|
+
let paths = [];
|
|
230
|
+
if (platform === 'win32') {
|
|
231
|
+
paths = [
|
|
232
|
+
path.join(process.env.PROGRAMFILES || 'C:\\Program Files', 'BraveSoftware', 'Brave-Browser', 'Application', 'brave.exe'),
|
|
233
|
+
path.join(process.env['PROGRAMFILES(X86)'] || 'C:\\Program Files (x86)', 'BraveSoftware', 'Brave-Browser', 'Application', 'brave.exe'),
|
|
234
|
+
path.join(process.env.LOCALAPPDATA || '', 'BraveSoftware', 'Brave-Browser', 'Application', 'brave.exe')
|
|
235
|
+
].filter(p => p);
|
|
236
|
+
}
|
|
237
|
+
else if (platform === 'darwin') {
|
|
238
|
+
paths = [
|
|
239
|
+
'/Applications/Brave Browser.app/Contents/MacOS/Brave Browser'
|
|
240
|
+
];
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
paths = [
|
|
244
|
+
'/usr/bin/brave-browser',
|
|
245
|
+
'/usr/bin/brave',
|
|
246
|
+
'/usr/bin/brave-browser-stable',
|
|
247
|
+
'/usr/bin/brave-browser-beta',
|
|
248
|
+
'/usr/bin/brave-browser-nightly',
|
|
249
|
+
'/usr/local/bin/brave-browser',
|
|
250
|
+
'/usr/local/bin/brave'
|
|
251
|
+
];
|
|
252
|
+
}
|
|
253
|
+
for (const p of paths) {
|
|
254
|
+
if (p && fs.existsSync(p)) {
|
|
255
|
+
return p;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
async function applyUserAgentOverride(page, userAgent, userAgentMetadata) {
|
|
261
|
+
try {
|
|
262
|
+
const client = await page.context().newCDPSession(page);
|
|
263
|
+
await client.send('Emulation.setUserAgentOverride', {
|
|
264
|
+
userAgent: userAgent,
|
|
265
|
+
userAgentMetadata: userAgentMetadata
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
catch (e) {
|
|
269
|
+
// Ignore errors
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
async function connect({ args = [], headless = getDefaultHeadless(), proxy = {}, turnstile = false, executablePath = undefined, } = {}) {
|
|
273
|
+
let playwrightProxy = undefined;
|
|
274
|
+
if (proxy && proxy.host && proxy.port) {
|
|
275
|
+
playwrightProxy = {
|
|
276
|
+
server: `${proxy.host}:${proxy.port}`
|
|
277
|
+
};
|
|
278
|
+
if (proxy.username && proxy.password) {
|
|
279
|
+
playwrightProxy.username = proxy.username;
|
|
280
|
+
playwrightProxy.password = proxy.password;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// 1. Launch a temporary browser to retrieve the native user agent and properties
|
|
284
|
+
const tempBrowser = await chromium.launch({
|
|
285
|
+
headless: true,
|
|
286
|
+
args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
287
|
+
...(executablePath ? { executablePath } : {}),
|
|
288
|
+
});
|
|
289
|
+
const tempContext = await tempBrowser.newContext();
|
|
290
|
+
const tempPage = await tempContext.newPage();
|
|
291
|
+
let nativeUa = '';
|
|
292
|
+
let isBrave = false;
|
|
293
|
+
try {
|
|
294
|
+
nativeUa = await tempPage.evaluate(() => navigator.userAgent);
|
|
295
|
+
isBrave = await tempPage.evaluate(() => typeof navigator.brave !== 'undefined');
|
|
296
|
+
}
|
|
297
|
+
catch (e) {
|
|
298
|
+
nativeUa = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/148.0.0.0 Safari/537.36';
|
|
299
|
+
isBrave = executablePath && executablePath.toLowerCase().includes('brave');
|
|
300
|
+
}
|
|
301
|
+
await tempBrowser.close();
|
|
302
|
+
let modifiedUa = nativeUa.replace(/HeadlessChrome\//g, 'Chrome/');
|
|
303
|
+
const chromeVersionMatch = modifiedUa.match(/Chrome\/([\d.]+)/);
|
|
304
|
+
const chromeVersion = chromeVersionMatch ? chromeVersionMatch[1] : '148.0.0.0';
|
|
305
|
+
const majorVersion = chromeVersion.split('.')[0];
|
|
306
|
+
const brands = [
|
|
307
|
+
{ brand: 'Chromium', version: majorVersion },
|
|
308
|
+
{ brand: 'Not/A)Brand', version: '99' }
|
|
309
|
+
];
|
|
310
|
+
if (isBrave) {
|
|
311
|
+
brands.unshift({ brand: 'Brave', version: majorVersion });
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
brands.unshift({ brand: 'Google Chrome', version: majorVersion });
|
|
315
|
+
}
|
|
316
|
+
let platformName = 'Windows';
|
|
317
|
+
if (nativeUa.includes('Macintosh') || nativeUa.includes('Mac OS X')) {
|
|
318
|
+
platformName = 'macOS';
|
|
319
|
+
}
|
|
320
|
+
else if (nativeUa.includes('Linux')) {
|
|
321
|
+
platformName = 'Linux';
|
|
322
|
+
}
|
|
323
|
+
const userAgentMetadata = {
|
|
324
|
+
brands: brands,
|
|
325
|
+
mobile: false,
|
|
326
|
+
platform: platformName,
|
|
327
|
+
platformVersion: platformName === 'macOS' ? '14.0.0' : platformName === 'Linux' ? '6.0.0' : '10.0.0',
|
|
328
|
+
architecture: 'x86',
|
|
329
|
+
model: '',
|
|
330
|
+
bitness: '64',
|
|
331
|
+
wow64: false
|
|
332
|
+
};
|
|
333
|
+
const chromiumArgs = [
|
|
334
|
+
`--user-agent=${modifiedUa}`,
|
|
335
|
+
'--disable-blink-features=AutomationControlled',
|
|
336
|
+
'--no-sandbox',
|
|
337
|
+
'--disable-setuid-sandbox',
|
|
338
|
+
...args
|
|
339
|
+
];
|
|
340
|
+
// If headless is true, we run with headless: false but pass '--headless=new' to args.
|
|
341
|
+
// This triggers Chromium's modern undetected headless mode instead of Playwright's default old headless shell.
|
|
342
|
+
let launchHeadless = headless;
|
|
343
|
+
if (headless === true) {
|
|
344
|
+
launchHeadless = false;
|
|
345
|
+
if (!chromiumArgs.includes('--headless=new')) {
|
|
346
|
+
chromiumArgs.push('--headless=new');
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
const browser = await chromium.launch({
|
|
350
|
+
headless: launchHeadless,
|
|
351
|
+
args: chromiumArgs,
|
|
352
|
+
proxy: playwrightProxy,
|
|
353
|
+
...(executablePath ? { executablePath } : {}),
|
|
354
|
+
});
|
|
355
|
+
// Ensure ad blocker is ready
|
|
356
|
+
await getAdBlocker();
|
|
357
|
+
const context = await browser.newContext({
|
|
358
|
+
viewport: null,
|
|
359
|
+
});
|
|
360
|
+
let page = await context.newPage();
|
|
361
|
+
await applyUserAgentOverride(page, modifiedUa, userAgentMetadata);
|
|
362
|
+
setupRealPage(browser, page);
|
|
363
|
+
page = await pageController({
|
|
364
|
+
browser,
|
|
365
|
+
page,
|
|
366
|
+
proxy,
|
|
367
|
+
turnstile,
|
|
368
|
+
});
|
|
369
|
+
context.on('page', async (newPage) => {
|
|
370
|
+
await applyUserAgentOverride(newPage, modifiedUa, userAgentMetadata);
|
|
371
|
+
setupRealPage(browser, newPage);
|
|
372
|
+
await pageController({
|
|
373
|
+
browser,
|
|
374
|
+
page: newPage,
|
|
375
|
+
proxy,
|
|
376
|
+
turnstile,
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
return {
|
|
380
|
+
browser,
|
|
381
|
+
page,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
module.exports = { connect };
|
|
385
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../lib/cjs/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pageController.d.ts","sourceRoot":"","sources":["../../../../lib/cjs/module/pageController.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC"}
|