Skip to content

Commit

Permalink
chore: use handle instead of globals for injection (#8946)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrandolf committed Sep 13, 2022
1 parent a4e444d commit 6fd05d9
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 42 deletions.
12 changes: 7 additions & 5 deletions src/common/Frame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ export class Frame {
this.#client = client;
this.worlds = {
[MAIN_WORLD]: new IsolatedWorld(this),
[PUPPETEER_WORLD]: new IsolatedWorld(this, true),
[PUPPETEER_WORLD]: new IsolatedWorld(this),
};
}

Expand Down Expand Up @@ -776,8 +776,8 @@ export class Frame {

return this.worlds[MAIN_WORLD].transferHandle(
await this.worlds[PUPPETEER_WORLD].evaluateHandle(
async ({url, id, type, content}) => {
const promise = InjectedUtil.createDeferredPromise<void>();
async ({createDeferredPromise}, {url, id, type, content}) => {
const promise = createDeferredPromise<void>();
const script = document.createElement('script');
script.type = type;
script.text = content;
Expand Down Expand Up @@ -809,6 +809,7 @@ export class Frame {
await promise;
return script;
},
await this.worlds[PUPPETEER_WORLD].puppeteerUtil,
{...options, type, content}
)
);
Expand Down Expand Up @@ -858,8 +859,8 @@ export class Frame {

return this.worlds[MAIN_WORLD].transferHandle(
await this.worlds[PUPPETEER_WORLD].evaluateHandle(
async ({url, content}) => {
const promise = InjectedUtil.createDeferredPromise<void>();
async ({createDeferredPromise}, {url, content}) => {
const promise = createDeferredPromise<void>();
let element: HTMLStyleElement | HTMLLinkElement;
if (!url) {
element = document.createElement('style');
Expand Down Expand Up @@ -892,6 +893,7 @@ export class Frame {
await promise;
return element;
},
await this.worlds[PUPPETEER_WORLD].puppeteerUtil,
options
)
);
Expand Down
31 changes: 25 additions & 6 deletions src/common/IsolatedWorld.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import {Protocol} from 'devtools-protocol';
import {source as injectedSource} from '../generated/injected.js';
import type PuppeteerUtil from '../injected/injected.js';
import {assert} from '../util/assert.js';
import {createDeferredPromise} from '../util/DeferredPromise.js';
import {CDPSession} from './Connection.js';
Expand Down Expand Up @@ -114,7 +115,6 @@ export interface IsolatedWorldChart {
*/
export class IsolatedWorld {
#frame: Frame;
#injected: boolean;
#document?: ElementHandle<Document>;
#context = createDeferredPromise<ExecutionContext>();
#detached = false;
Expand All @@ -125,6 +125,11 @@ export class IsolatedWorld {
// Contains mapping from functions that should be bound to Puppeteer functions.
#boundFunctions = new Map<string, Function>();
#waitTasks = new Set<WaitTask>();
#puppeteerUtil = createDeferredPromise<JSHandle<PuppeteerUtil>>();

get puppeteerUtil(): Promise<JSHandle<PuppeteerUtil>> {
return this.#puppeteerUtil;
}

get _waitTasks(): Set<WaitTask> {
return this.#waitTasks;
Expand All @@ -138,11 +143,10 @@ export class IsolatedWorld {
return `${name}_${contextId}`;
};

constructor(frame: Frame, injected = false) {
constructor(frame: Frame) {
// Keep own reference to client because it might differ from the FrameManager's
// client for OOP iframes.
this.#frame = frame;
this.#injected = injected;
this.#client.on('Runtime.bindingCalled', this.#onBindingCalled);
}

Expand All @@ -164,20 +168,35 @@ export class IsolatedWorld {

clearContext(): void {
this.#document = undefined;
this.#puppeteerUtil = createDeferredPromise();
this.#context = createDeferredPromise();
}

setContext(context: ExecutionContext): void {
if (this.#injected) {
context.evaluate(injectedSource).catch(debugError);
}
this.#injectPuppeteerUtil(context);
this.#ctxBindings.clear();
this.#context.resolve(context);
for (const waitTask of this._waitTasks) {
waitTask.rerun();
}
}

async #injectPuppeteerUtil(context: ExecutionContext): Promise<void> {
try {
this.#puppeteerUtil.resolve(
(await context.evaluateHandle(
`(() => {
const module = {};
${injectedSource}
return module.exports.default;
})()`
)) as JSHandle<PuppeteerUtil>
);
} catch (error: unknown) {
debugError(error);
}
}

hasContext(): boolean {
return this.#context.resolved();
}
Expand Down
19 changes: 8 additions & 11 deletions src/injected/injected.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import {createDeferredPromise} from '../util/DeferredPromise.js';
import * as Poller from './Poller.js';
import * as util from './util.js';

Object.assign(
self,
Object.freeze({
InjectedUtil: {
...Poller,
...util,
createDeferredPromise,
},
})
);
const PuppeteerUtil = Object.freeze({
...util,
createDeferredPromise,
});

type PuppeteerUtil = typeof PuppeteerUtil;

export default PuppeteerUtil;
16 changes: 7 additions & 9 deletions src/templates/injected.ts.tmpl
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import {createDeferredPromise} from '../util/DeferredPromise.js';

declare global {
const InjectedUtil: {
createDeferredPromise: typeof createDeferredPromise;
};
}

/** @internal */
/**
* CommonJS JavaScript code that provides the puppeteer utilities. See the
* [README](https://github.com/puppeteer/puppeteer/blob/main/src/injected/README.md)
* for injection for more information.
*
* @internal
*/
export const source = SOURCE_CODE;
3 changes: 1 addition & 2 deletions src/tsconfig.cjs.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@
"references": [
{"path": "../vendor/tsconfig.cjs.json"},
{"path": "../compat/cjs/tsconfig.json"}
],
"exclude": ["injected/injected.ts"]
]
}
3 changes: 1 addition & 2 deletions src/tsconfig.esm.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@
"references": [
{"path": "../vendor/tsconfig.esm.json"},
{"path": "../compat/esm/tsconfig.json"}
],
"exclude": ["injected/injected.ts"]
]
}
31 changes: 24 additions & 7 deletions test/src/injected.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,35 @@ import {
setupTestPageAndContextHooks,
} from './mocha-utils.js';

describe('InjectedUtil tests', function () {
describe('PuppeteerUtil tests', function () {
setupTestBrowserHooks();
setupTestPageAndContextHooks();

it('should work', async () => {
const {page} = getTestState();

const handle = await page
.mainFrame()
.worlds[PUPPETEER_WORLD].evaluate(() => {
return typeof InjectedUtil === 'object';
});
expect(handle).toBeTruthy();
const world = page.mainFrame().worlds[PUPPETEER_WORLD];
const value = await world.evaluate(PuppeteerUtil => {
return typeof PuppeteerUtil === 'object';
}, world.puppeteerUtil);
expect(value).toBeTruthy();
});

describe('createFunction tests', function () {
it('should work', async () => {
const {page} = getTestState();

const world = page.mainFrame().worlds[PUPPETEER_WORLD];
const value = await world.evaluate(
({createFunction}, fnString) => {
return createFunction(fnString)(4);
},
await world.puppeteerUtil,
(() => {
return 4;
}).toString()
);
expect(value).toBe(4);
});
});
});

0 comments on commit 6fd05d9

Please sign in to comment.