mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
chore: implement removeExposedFunction
(#11984)
This commit is contained in:
parent
9ddfa5314c
commit
627bd00399
@ -29,6 +29,17 @@ type CallbackChannel<Args, Ret> = (
|
|||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export class ExposeableFunction<Args extends unknown[], Ret> {
|
export class ExposeableFunction<Args extends unknown[], Ret> {
|
||||||
|
static async from<Args extends unknown[], Ret>(
|
||||||
|
frame: BidiFrame,
|
||||||
|
name: string,
|
||||||
|
apply: (...args: Args) => Awaitable<Ret>,
|
||||||
|
isolate = false
|
||||||
|
): Promise<ExposeableFunction<Args, Ret>> {
|
||||||
|
const func = new ExposeableFunction(frame, name, apply, isolate);
|
||||||
|
await func.#initialize();
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
readonly #frame;
|
readonly #frame;
|
||||||
|
|
||||||
readonly name;
|
readonly name;
|
||||||
@ -54,7 +65,7 @@ export class ExposeableFunction<Args extends unknown[], Ret> {
|
|||||||
this.#channel = `__puppeteer__${this.#frame._id}_page_exposeFunction_${this.name}`;
|
this.#channel = `__puppeteer__${this.#frame._id}_page_exposeFunction_${this.name}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async expose(): Promise<void> {
|
async #initialize() {
|
||||||
const connection = this.#connection;
|
const connection = this.#connection;
|
||||||
const channel = {
|
const channel = {
|
||||||
type: 'channel' as const,
|
type: 'channel' as const,
|
||||||
@ -98,23 +109,16 @@ export class ExposeableFunction<Args extends unknown[], Ret> {
|
|||||||
frames.map(async frame => {
|
frames.map(async frame => {
|
||||||
const realm = this.#isolate ? frame.isolatedRealm() : frame.mainRealm();
|
const realm = this.#isolate ? frame.isolatedRealm() : frame.mainRealm();
|
||||||
try {
|
try {
|
||||||
this.#scripts.push([
|
const [script] = await Promise.all([
|
||||||
frame,
|
frame.browsingContext.addPreloadScript(functionDeclaration, {
|
||||||
await frame.browsingContext.addPreloadScript(functionDeclaration, {
|
|
||||||
arguments: [channel],
|
arguments: [channel],
|
||||||
sandbox: realm.sandbox,
|
sandbox: realm.sandbox,
|
||||||
}),
|
}),
|
||||||
]);
|
realm.realm.callFunction(functionDeclaration, false, {
|
||||||
} catch (error) {
|
|
||||||
// If it errors, the frame probably doesn't support adding preload
|
|
||||||
// scripts. We fail gracefully.
|
|
||||||
debugError(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await realm.realm.callFunction(functionDeclaration, false, {
|
|
||||||
arguments: [channel],
|
arguments: [channel],
|
||||||
});
|
}),
|
||||||
|
]);
|
||||||
|
this.#scripts.push([frame, script]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// If it errors, the frame probably doesn't support call function. We
|
// If it errors, the frame probably doesn't support call function. We
|
||||||
// fail gracefully.
|
// fail gracefully.
|
||||||
@ -233,7 +237,17 @@ export class ExposeableFunction<Args extends unknown[], Ret> {
|
|||||||
this.#disposables.dispose();
|
this.#disposables.dispose();
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
this.#scripts.map(async ([frame, script]) => {
|
this.#scripts.map(async ([frame, script]) => {
|
||||||
await frame.browsingContext.removePreloadScript(script);
|
const realm = this.#isolate ? frame.isolatedRealm() : frame.mainRealm();
|
||||||
|
try {
|
||||||
|
await Promise.all([
|
||||||
|
realm.evaluate(name => {
|
||||||
|
delete (globalThis as any)[name];
|
||||||
|
}, this.name),
|
||||||
|
frame.browsingContext.removePreloadScript(script),
|
||||||
|
]);
|
||||||
|
} catch (error) {
|
||||||
|
debugError(error);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -408,14 +408,20 @@ export class BidiFrame extends Frame {
|
|||||||
`Failed to add page binding with name ${name}: globalThis['${name}'] already exists!`
|
`Failed to add page binding with name ${name}: globalThis['${name}'] already exists!`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const exposeable = new ExposeableFunction(this, name, apply);
|
const exposeable = await ExposeableFunction.from(this, name, apply);
|
||||||
this.#exposedFunctions.set(name, exposeable);
|
this.#exposedFunctions.set(name, exposeable);
|
||||||
try {
|
|
||||||
await exposeable.expose();
|
|
||||||
} catch (error) {
|
|
||||||
this.#exposedFunctions.delete(name);
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async removeExposedFunction(name: string): Promise<void> {
|
||||||
|
const exposedFunction = this.#exposedFunctions.get(name);
|
||||||
|
if (!exposedFunction) {
|
||||||
|
throw new Error(
|
||||||
|
`Failed to remove page binding with name ${name}: window['${name}'] does not exists!`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#exposedFunctions.delete(name);
|
||||||
|
await exposedFunction[Symbol.asyncDispose]();
|
||||||
}
|
}
|
||||||
|
|
||||||
override waitForSelector<Selector extends string>(
|
override waitForSelector<Selector extends string>(
|
||||||
|
@ -577,9 +577,8 @@ export class BidiPage extends Page {
|
|||||||
throw new UnsupportedOperation();
|
throw new UnsupportedOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
override removeExposedFunction(): never {
|
override async removeExposedFunction(name: string): Promise<void> {
|
||||||
// TODO: Quick win?
|
await this.#frame.removeExposedFunction(name);
|
||||||
throw new UnsupportedOperation();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override authenticate(): never {
|
override authenticate(): never {
|
||||||
|
@ -674,12 +674,6 @@
|
|||||||
"parameters": ["firefox"],
|
"parameters": ["firefox"],
|
||||||
"expectations": ["SKIP"]
|
"expectations": ["SKIP"]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"testIdPattern": "[page.spec] Page Page.removeExposedFunction should work",
|
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
|
||||||
"parameters": ["webDriverBiDi"],
|
|
||||||
"expectations": ["SKIP"]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"testIdPattern": "[page.spec] Page Page.setBypassCSP *",
|
"testIdPattern": "[page.spec] Page Page.setBypassCSP *",
|
||||||
"platforms": ["darwin", "linux", "win32"],
|
"platforms": ["darwin", "linux", "win32"],
|
||||||
|
Loading…
Reference in New Issue
Block a user