mirror of
https://github.com/CloakHQ/CloakBrowser.git
synced 2026-06-23 11:41:46 +02:00
release: v0.3.5 — persistent context, Windows zip fix, community PRs
- Add launch_persistent_context() Python + JS with examples - Document persistent context API in both READMEs - Bump version to 0.3.5 - Credit @evelaa123 and @yahooguntu in CHANGELOG
This commit is contained in:
@@ -6,6 +6,12 @@ Changes are tagged: **[wrapper]** for Python/JS wrapper, **[binary]** for Chromi
|
||||
|
||||
---
|
||||
|
||||
## [0.3.5] — 2026-03-04
|
||||
|
||||
- **[wrapper]** Add `launch_persistent_context()` and `launch_persistent_context_async()` (Python) — persistent browser profiles with cookie/localStorage persistence across sessions, avoids incognito detection (thanks [@evelaa123](https://github.com/evelaa123), [@yahooguntu](https://github.com/yahooguntu) — PRs #22, #17)
|
||||
- **[wrapper]** Add `launchPersistentContext()` (JS/TS) — same feature for JavaScript with full type support
|
||||
- **[wrapper]** Fix Windows zip extraction failure when primary download server is down — file handle leak caused `ERROR_SHARING_VIOLATION` on fallback download (thanks [@evelaa123](https://github.com/evelaa123) — PR #23)
|
||||
|
||||
## [0.3.4] — 2026-03-04
|
||||
|
||||
Binary v14: auto-spoof restored with seed, wrapper simplified to match.
|
||||
|
||||
@@ -239,7 +239,7 @@ asyncio.run(main())
|
||||
|
||||
### `launch_context()`
|
||||
|
||||
Convenience function that creates browser + context with common options:
|
||||
Convenience function that creates browser + context in one call with user agent, viewport, locale, and timezone:
|
||||
|
||||
```python
|
||||
from cloakbrowser import launch_context
|
||||
@@ -251,8 +251,31 @@ context = launch_context(
|
||||
timezone_id="America/New_York",
|
||||
)
|
||||
page = context.new_page()
|
||||
page.goto("https://protected-site.com")
|
||||
context.close()
|
||||
```
|
||||
|
||||
### `launch_persistent_context()`
|
||||
|
||||
Same as `launch_context()`, but with a persistent user profile. Cookies, localStorage, and cache persist across sessions. Also avoids incognito detection by services like BrowserScan.
|
||||
|
||||
```python
|
||||
from cloakbrowser import launch_persistent_context
|
||||
|
||||
# First run — creates the profile
|
||||
ctx = launch_persistent_context("./my-profile", headless=False)
|
||||
page = ctx.new_page()
|
||||
page.goto("https://protected-site.com")
|
||||
ctx.close() # profile saved
|
||||
|
||||
# Next run — cookies, localStorage restored automatically
|
||||
ctx = launch_persistent_context("./my-profile", headless=False)
|
||||
```
|
||||
|
||||
Supports all the same options as `launch_context()`: `proxy`, `user_agent`, `viewport`, `locale`, `timezone_id`, `color_scheme`, `geoip`.
|
||||
|
||||
Async version: `launch_persistent_context_async()`.
|
||||
|
||||
### Utility Functions
|
||||
|
||||
```python
|
||||
@@ -276,7 +299,7 @@ CloakBrowser ships a TypeScript package with full type definitions. Choose Playw
|
||||
### Playwright (default)
|
||||
|
||||
```javascript
|
||||
import { launch, launchContext } from 'cloakbrowser';
|
||||
import { launch, launchContext, launchPersistentContext } from 'cloakbrowser';
|
||||
|
||||
// Basic
|
||||
const browser = await launch();
|
||||
@@ -298,6 +321,13 @@ const context = await launchContext({
|
||||
timezoneId: 'America/New_York',
|
||||
});
|
||||
const page = await context.newPage();
|
||||
|
||||
// Persistent profile — cookies/localStorage survive restarts, avoids incognito detection
|
||||
const ctx = await launchPersistentContext({
|
||||
userDataDir: './chrome-profile',
|
||||
headless: false,
|
||||
proxy: 'http://user:pass@proxy:8080',
|
||||
});
|
||||
```
|
||||
|
||||
> **Note:** Each example above is standalone — not meant to run as one block.
|
||||
@@ -452,12 +482,14 @@ The wrapper auto-downloads the correct binary for your platform.
|
||||
|
||||
**Python** — see [`examples/`](examples/):
|
||||
- [`basic.py`](examples/basic.py) — Launch and load a page
|
||||
- [`persistent_context.py`](examples/persistent_context.py) — Persistent profile with cookie/localStorage persistence
|
||||
- [`recaptcha_score.py`](examples/recaptcha_score.py) — Check your reCAPTCHA v3 score
|
||||
- [`stealth_test.py`](examples/stealth_test.py) — Run against all detection services
|
||||
- [`fingerprint_scan_test.py`](examples/fingerprint_scan_test.py) — Test against fingerprint-scan.com and CreepJS
|
||||
|
||||
**JavaScript** — see [`js/examples/`](js/examples/):
|
||||
- [`basic-playwright.ts`](js/examples/basic-playwright.ts) — Playwright launch and load
|
||||
- [`persistent-context.ts`](js/examples/persistent-context.ts) — Persistent profile with cookie/localStorage persistence
|
||||
- [`basic-puppeteer.ts`](js/examples/basic-puppeteer.ts) — Puppeteer launch and load
|
||||
- [`stealth-test.ts`](js/examples/stealth-test.ts) — Full 6-site detection test suite
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "0.3.4"
|
||||
__version__ = "0.3.5"
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
"""Persistent context example: cookies and localStorage survive across sessions."""
|
||||
|
||||
from cloakbrowser import launch_persistent_context
|
||||
|
||||
PROFILE_DIR = "./my-profile"
|
||||
|
||||
# Session 1 — set some state
|
||||
print("=== Session 1: Setting state ===")
|
||||
ctx = launch_persistent_context(PROFILE_DIR, headless=False)
|
||||
page = ctx.new_page()
|
||||
page.goto("https://example.com")
|
||||
page.evaluate("document.cookie = 'session=abc123; path=/; max-age=3600'")
|
||||
page.evaluate("localStorage.setItem('user', 'returning')")
|
||||
print(f"Cookie: {page.evaluate('document.cookie')}")
|
||||
ls_val = page.evaluate("localStorage.getItem('user')")
|
||||
print(f"localStorage: {ls_val}")
|
||||
ctx.close()
|
||||
|
||||
# Session 2 — state is restored
|
||||
print("\n=== Session 2: Verifying persistence ===")
|
||||
ctx = launch_persistent_context(PROFILE_DIR, headless=False)
|
||||
page = ctx.new_page()
|
||||
page.goto("https://example.com")
|
||||
print(f"Cookie: {page.evaluate('document.cookie')}")
|
||||
ls_val = page.evaluate("localStorage.getItem('user')")
|
||||
print(f"localStorage: {ls_val}")
|
||||
ctx.close()
|
||||
|
||||
print("\nDone!")
|
||||
+11
-1
@@ -60,7 +60,7 @@ await browser.close();
|
||||
### Options
|
||||
|
||||
```javascript
|
||||
import { launch, launchContext } from 'cloakbrowser';
|
||||
import { launch, launchContext, launchPersistentContext } from 'cloakbrowser';
|
||||
|
||||
// With proxy
|
||||
const browser = await launch({
|
||||
@@ -94,6 +94,16 @@ const context = await launchContext({
|
||||
locale: 'en-US',
|
||||
timezoneId: 'America/New_York',
|
||||
});
|
||||
|
||||
// Persistent profile — cookies/localStorage survive restarts, avoids incognito detection
|
||||
const ctx = await launchPersistentContext({
|
||||
userDataDir: './chrome-profile',
|
||||
headless: false,
|
||||
proxy: 'http://user:pass@proxy:8080',
|
||||
});
|
||||
const page = ctx.pages()[0] || await ctx.newPage();
|
||||
await page.goto('https://example.com');
|
||||
await ctx.close(); // profile saved — reuse same path to restore state
|
||||
```
|
||||
|
||||
### Auto Timezone/Locale from Proxy IP
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Persistent context example: cookies and localStorage survive across sessions.
|
||||
*
|
||||
* Usage:
|
||||
* CLOAKBROWSER_BINARY_PATH=/path/to/chrome npx tsx examples/persistent-context.ts
|
||||
*/
|
||||
|
||||
import { launchPersistentContext } from "../src/index.js";
|
||||
|
||||
const PROFILE_DIR = "./my-profile";
|
||||
|
||||
// Session 1 — set some state
|
||||
console.log("=== Session 1: Setting state ===");
|
||||
let ctx = await launchPersistentContext({
|
||||
userDataDir: PROFILE_DIR,
|
||||
headless: false,
|
||||
});
|
||||
let page = ctx.pages()[0] || (await ctx.newPage());
|
||||
await page.goto("https://example.com");
|
||||
await page.evaluate(() => {
|
||||
document.cookie = "session=abc123; path=/; max-age=3600";
|
||||
localStorage.setItem("user", "returning");
|
||||
});
|
||||
console.log(`Cookie: ${await page.evaluate(() => document.cookie)}`);
|
||||
console.log(`localStorage: ${await page.evaluate(() => localStorage.getItem("user"))}`);
|
||||
await ctx.close();
|
||||
|
||||
// Session 2 — state is restored
|
||||
console.log("\n=== Session 2: Verifying persistence ===");
|
||||
ctx = await launchPersistentContext({
|
||||
userDataDir: PROFILE_DIR,
|
||||
headless: false,
|
||||
});
|
||||
page = ctx.pages()[0] || (await ctx.newPage());
|
||||
await page.goto("https://example.com");
|
||||
console.log(`Cookie: ${await page.evaluate(() => document.cookie)}`);
|
||||
console.log(`localStorage: ${await page.evaluate(() => localStorage.getItem("user"))}`);
|
||||
await ctx.close();
|
||||
|
||||
console.log("\nDone!");
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cloakbrowser",
|
||||
"version": "0.3.4",
|
||||
"version": "0.3.5",
|
||||
"description": "Stealth Chromium that passes every bot detection test. Drop-in Playwright/Puppeteer replacement with source-level fingerprint patches.",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
|
||||
Reference in New Issue
Block a user