Skip to content

Commit 574dbe3

Browse files
committed
New patches: change sourceURL, change utility world name, expose browser's CDP session.
1 parent 6500910 commit 574dbe3

File tree

5 files changed

+174
-22
lines changed

5 files changed

+174
-22
lines changed

README.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,35 @@ REBROWSER_PATCHES_RUNTIME_FIX_MODE=alwaysIsolated node app.js
5252
|--------| --- |
5353
| ![before](https://github.com/user-attachments/assets/daf4fee7-538c-49aa-946a-f9e939fe8fe5) | ![after](https://github.com/user-attachments/assets/0680a6f1-2fd9-4a49-ad7f-ae32758715ec) |
5454

55+
### Change sourceURL to generic script name
56+
By default, Puppeteer adds `//# sourceURL=pptr:...` to every script in `page.evaluate()`. A remote website can detect this behavior and raise red flags.
57+
This patch changes it to `//# sourceURL=app.js`. You can also adjust it via environment variable:
58+
```shell
59+
# use any generic filename
60+
process.env.REBROWSER_PATCHES_SOURCE_URL = "jquery.min.js"
61+
# use 0 to completely disable this patch
62+
process.env.REBROWSER_PATCHES_SOURCE_URL = "0"
63+
```
64+
65+
### Method to access browser CDP connection
66+
Sometimes, it could be very useful to access a CDP session at a browser level. For example, when you want to implement some custom CDP command. There is a method `page._client()` that returns CDP session for the current page instance, but there is no such method for browser instance.
67+
This patch adds a new method `_connection()` to Browser class, so you can use it like this:
68+
```js
69+
browser._connection().on('Rebrowser.addRunEvent', (params) => { ... })
70+
```
71+
*Note: it's not detectable by external website scripts, it's just for your convenience.*
72+
73+
### Change default utility world name
74+
The default utility world name is `'__puppeteer_utility_world__' + packageVersion`. Sometimes you might want to change it to something else. This patch changes it to `util` and allows you to customize it via env variable:
75+
```shell
76+
REBROWSER_PATCHES_UTILITY_WORLD_NAME = "customUtilityWorld"
77+
# use 0 to completely disable this patch
78+
REBROWSER_PATCHES_UTILITY_WORLD_NAME = "0"
79+
```
80+
*This env variable cannot be changed on the fly, you have to set it before running your script because it's used at the moment when the module is getting imported.*
81+
82+
*Note: it's not detectable by external website scripts, but Google might use this information in their proprietary Chrome; we never know.*
83+
5584
## Usage
5685
This package is designed to be run against an installed library. Install the Puppeteer library, then call the patcher, and it's ready to go.
5786

@@ -76,7 +105,7 @@ You can see all command-line options by running `npx rebrowser-patches@latest --
76105
⚠️ Be aware that after running `npm install` or `yarn install` in your project folder, it might override all the changes from the patches. You'll need to run the patcher again to keep the patches in place.
77106

78107
## How to update the patches?
79-
If you already have your package patched and want to update to the latest version of rebrowser-patches, the easiest way would be to delete `node_modules/puppeteer-core`, then run `npm install`, and then run `npx rebrowser-patches@latest patch`.
108+
If you already have your package patched and want to update to the latest version of rebrowser-patches, the easiest way would be to delete `node_modules/puppeteer-core`, then run `npm install` or `yarn install --check-files`, and then run `npx rebrowser-patches@latest patch`.
80109

81110
## Supported versions
82111

package.json

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,5 @@
5454
},
5555
"dependencies": {
5656
"yargs": "^17.7.2"
57-
},
58-
"devDependencies": {
59-
"eslint": "^8.51.0",
60-
"eslint-plugin-import": "^2.28.1",
61-
"eslint-plugin-simple-import-sort": "^10.0.0",
62-
"eslint-plugin-unused-imports": "^3.0.0"
6357
}
6458
}

patches/puppeteer-core/22.13.x/fixRuntimeLeak.patch renamed to patches/puppeteer-core/22.13.x.patch

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
--- a/src/cdp/Browser.ts
2+
+++ b/src/cdp/Browser.ts
3+
@@ -338,6 +338,11 @@
4+
return await this.#defaultContext.newPage();
5+
}
6+
7+
+ // rebrowser-patches: expose browser CDP session
8+
+ _connection(): Connection {
9+
+ return this.#connection;
10+
+ }
11+
+
12+
async _createPageInContext(contextId?: string): Promise<Page> {
13+
const {targetId} = await this.#connection.send('Target.createTarget', {
14+
url: 'about:blank',
15+
116
--- a/src/cdp/ExecutionContext.ts
217
+++ b/src/cdp/ExecutionContext.ts
318
@@ -78,6 +78,7 @@
@@ -290,6 +305,56 @@
290305

291306
mainRealm(): Realm {
292307

308+
--- a/src/common/util.ts
309+
+++ b/src/common/util.ts
310+
@@ -328,7 +328,9 @@
311+
* @internal
312+
*/
313+
export const UTILITY_WORLD_NAME =
314+
- '__puppeteer_utility_world__' + packageVersion;
315+
+ // rebrowser-patches: change utility world name
316+
+ process.env['REBROWSER_PATCHES_UTILITY_WORLD_NAME'] !== '0' ? (process.env['REBROWSER_PATCHES_UTILITY_WORLD_NAME'] || 'util') :
317+
+ '__puppeteer_utility_world__' + packageVersion;
318+
319+
/**
320+
* @internal
321+
@@ -338,6 +340,10 @@
322+
* @internal
323+
*/
324+
export function getSourceUrlComment(url: string): string {
325+
+ // rebrowser-patches: change sourceUrl to generic script name
326+
+ if (process.env['REBROWSER_PATCHES_SOURCE_URL'] !== '0') {
327+
+ url = process.env['REBROWSER_PATCHES_SOURCE_URL'] || 'app.js'
328+
+ }
329+
return `//# sourceURL=${url}`;
330+
}
331+
332+
333+
--- a/lib/cjs/puppeteer/cdp/Browser.d.ts
334+
+++ b/lib/cjs/puppeteer/cdp/Browser.d.ts
335+
@@ -32,6 +32,7 @@
336+
_disposeContext(contextId?: string): Promise<void>;
337+
wsEndpoint(): string;
338+
newPage(): Promise<Page>;
339+
+ _connection(): Connection;
340+
_createPageInContext(contextId?: string): Promise<Page>;
341+
targets(): CdpTarget[];
342+
target(): CdpTarget;
343+
344+
--- a/lib/cjs/puppeteer/cdp/Browser.js
345+
+++ b/lib/cjs/puppeteer/cdp/Browser.js
346+
@@ -176,6 +176,10 @@
347+
async newPage() {
348+
return await this.#defaultContext.newPage();
349+
}
350+
+ // rebrowser-patches: expose browser CDP session
351+
+ _connection() {
352+
+ return this.#connection;
353+
+ }
354+
async _createPageInContext(contextId) {
355+
const { targetId } = await this.#connection.send('Target.createTarget', {
356+
url: 'about:blank',
357+
293358
--- a/lib/cjs/puppeteer/cdp/ExecutionContext.d.ts
294359
+++ b/lib/cjs/puppeteer/cdp/ExecutionContext.d.ts
295360
@@ -22,6 +22,7 @@
@@ -585,6 +650,57 @@
585650
mainRealm() {
586651
return this.#world;
587652

653+
--- a/lib/cjs/puppeteer/common/util.js
654+
+++ b/lib/cjs/puppeteer/common/util.js
655+
@@ -294,7 +294,10 @@
656+
/**
657+
* @internal
658+
*/
659+
-exports.UTILITY_WORLD_NAME = '__puppeteer_utility_world__' + version_js_1.packageVersion;
660+
+exports.UTILITY_WORLD_NAME =
661+
+// rebrowser-patches: change utility world name
662+
+process.env['REBROWSER_PATCHES_UTILITY_WORLD_NAME'] !== '0' ? (process.env['REBROWSER_PATCHES_UTILITY_WORLD_NAME'] || 'util') :
663+
+ '__puppeteer_utility_world__' + version_js_1.packageVersion;
664+
/**
665+
* @internal
666+
*/
667+
@@ -303,6 +306,10 @@
668+
* @internal
669+
*/
670+
function getSourceUrlComment(url) {
671+
+ // rebrowser-patches: change sourceUrl to generic script name
672+
+ if (process.env['REBROWSER_PATCHES_SOURCE_URL'] !== '0') {
673+
+ url = process.env['REBROWSER_PATCHES_SOURCE_URL'] || 'app.js';
674+
+ }
675+
return `//# sourceURL=${url}`;
676+
}
677+
exports.getSourceUrlComment = getSourceUrlComment;
678+
679+
--- a/lib/esm/puppeteer/cdp/Browser.d.ts
680+
+++ b/lib/esm/puppeteer/cdp/Browser.d.ts
681+
@@ -32,6 +32,7 @@
682+
_disposeContext(contextId?: string): Promise<void>;
683+
wsEndpoint(): string;
684+
newPage(): Promise<Page>;
685+
+ _connection(): Connection;
686+
_createPageInContext(contextId?: string): Promise<Page>;
687+
targets(): CdpTarget[];
688+
target(): CdpTarget;
689+
690+
--- a/lib/esm/puppeteer/cdp/Browser.js
691+
+++ b/lib/esm/puppeteer/cdp/Browser.js
692+
@@ -173,6 +173,10 @@
693+
async newPage() {
694+
return await this.#defaultContext.newPage();
695+
}
696+
+ // rebrowser-patches: expose browser CDP session
697+
+ _connection() {
698+
+ return this.#connection;
699+
+ }
700+
async _createPageInContext(contextId) {
701+
const { targetId } = await this.#connection.send('Target.createTarget', {
702+
url: 'about:blank',
703+
588704
--- a/lib/esm/puppeteer/cdp/ExecutionContext.d.ts
589705
+++ b/lib/esm/puppeteer/cdp/ExecutionContext.d.ts
590706
@@ -22,6 +22,7 @@
@@ -879,3 +995,29 @@
879995
}
880996
mainRealm() {
881997
return this.#world;
998+
999+
--- a/lib/esm/puppeteer/common/util.js
1000+
+++ b/lib/esm/puppeteer/common/util.js
1001+
@@ -254,7 +254,10 @@
1002+
/**
1003+
* @internal
1004+
*/
1005+
-export const UTILITY_WORLD_NAME = '__puppeteer_utility_world__' + packageVersion;
1006+
+export const UTILITY_WORLD_NAME =
1007+
+// rebrowser-patches: change utility world name
1008+
+process.env['REBROWSER_PATCHES_UTILITY_WORLD_NAME'] !== '0' ? (process.env['REBROWSER_PATCHES_UTILITY_WORLD_NAME'] || 'util') :
1009+
+ '__puppeteer_utility_world__' + packageVersion;
1010+
/**
1011+
* @internal
1012+
*/
1013+
@@ -263,6 +266,10 @@
1014+
* @internal
1015+
*/
1016+
export function getSourceUrlComment(url) {
1017+
+ // rebrowser-patches: change sourceUrl to generic script name
1018+
+ if (process.env['REBROWSER_PATCHES_SOURCE_URL'] !== '0') {
1019+
+ url = process.env['REBROWSER_PATCHES_SOURCE_URL'] || 'app.js';
1020+
+ }
1021+
return `//# sourceURL=${url}`;
1022+
}
1023+
/**

scripts/patcher.js

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,13 @@ import { hideBin } from 'yargs/helpers'
99
import {
1010
exec,
1111
fatalError,
12-
getAvailablePatchesNames,
1312
getPatchBaseCmd,
1413
getPatcherPackagePath,
1514
log,
1615
} from './utils/index.js';
1716

1817
(async () => {
1918
// config and preparations
20-
const patchesNames = await getAvailablePatchesNames()
2119
const cliArgs = yargs(hideBin(process.argv))
2220
.usage('Usage: <command> [options]')
2321
.command('patch', 'Apply patch')
@@ -26,18 +24,14 @@ import {
2624
.describe('packageName', 'Target package name: puppeteer-core, playwright')
2725
.default('packageName', 'puppeteer-core')
2826
.describe('packagePath', 'Path to the target package')
29-
.describe('patchName', `Patch name: ${patchesNames.join(', ')}`)
30-
.default('patchName', 'fixRuntimeLeak')
3127
.boolean('debug')
3228
.describe('debug', 'Enable debugging mode')
33-
.demandOption(['patchName', 'packageName'])
3429
.demandCommand(1, 1, 'Error: choose a command (patch, unpatch, check)')
3530
.parse()
3631

3732
let {
3833
packageName,
3934
packagePath,
40-
patchName,
4135
debug,
4236
} = cliArgs
4337

@@ -56,10 +50,10 @@ import {
5650
fatalError(`Unknown command: ${command}`)
5751
}
5852

59-
const patchFilePath = resolve(getPatcherPackagePath(), `./patches/${packageName}/22.13.x/fixRuntimeLeak.patch`)
53+
const patchFilePath = resolve(getPatcherPackagePath(), `./patches/${packageName}/22.13.x.patch`)
6054

6155
log('Config:')
62-
log(`command = ${command}, packageName = ${packageName}, patchName = ${patchName}`)
56+
log(`command = ${command}, packageName = ${packageName}`)
6357
log(`packagePath = ${packagePath}`)
6458
log(`patchFilePath = ${patchFilePath}`)
6559
log('------')

scripts/utils/index.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,6 @@ export const getPatcherPackagePath = () => {
2525
return resolve(dirname(fileURLToPath(import.meta.url)), '../..')
2626
}
2727

28-
export const getAvailablePatchesNames = async () => {
29-
const pptrBaseDir = resolve(getPatcherPackagePath(), './patches/puppeteer-core/')
30-
const pptrVersions = await readdir(pptrBaseDir)
31-
const latestVersionPatches = await readdir(resolve(pptrBaseDir, pptrVersions[0]))
32-
return latestVersionPatches.map(p => p.split('.')[0])
33-
}
34-
3528
export const fatalError = (...args) => {
3629
console.error('❌ FATAL ERROR:', ...args)
3730
process.exit(1)

0 commit comments

Comments
 (0)