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
|
||||
*/
|
||||
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 name;
|
||||
@ -54,7 +65,7 @@ export class ExposeableFunction<Args extends unknown[], Ret> {
|
||||
this.#channel = `__puppeteer__${this.#frame._id}_page_exposeFunction_${this.name}`;
|
||||
}
|
||||
|
||||
async expose(): Promise<void> {
|
||||
async #initialize() {
|
||||
const connection = this.#connection;
|
||||
const channel = {
|
||||
type: 'channel' as const,
|
||||
@ -98,23 +109,16 @@ export class ExposeableFunction<Args extends unknown[], Ret> {
|
||||
frames.map(async frame => {
|
||||
const realm = this.#isolate ? frame.isolatedRealm() : frame.mainRealm();
|
||||
try {
|
||||
this.#scripts.push([
|
||||
frame,
|
||||
await frame.browsingContext.addPreloadScript(functionDeclaration, {
|
||||
const [script] = await Promise.all([
|
||||
frame.browsingContext.addPreloadScript(functionDeclaration, {
|
||||
arguments: [channel],
|
||||
sandbox: realm.sandbox,
|
||||
}),
|
||||
realm.realm.callFunction(functionDeclaration, false, {
|
||||
arguments: [channel],
|
||||
}),
|
||||
]);
|
||||
} 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],
|
||||
});
|
||||
this.#scripts.push([frame, script]);
|
||||
} catch (error) {
|
||||
// If it errors, the frame probably doesn't support call function. We
|
||||
// fail gracefully.
|
||||
@ -233,7 +237,17 @@ export class ExposeableFunction<Args extends unknown[], Ret> {
|
||||
this.#disposables.dispose();
|
||||
await Promise.all(
|
||||
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!`
|
||||
);
|
||||
}
|
||||
const exposeable = new ExposeableFunction(this, name, apply);
|
||||
const exposeable = await ExposeableFunction.from(this, name, apply);
|
||||
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>(
|
||||
|
@ -577,9 +577,8 @@ export class BidiPage extends Page {
|
||||
throw new UnsupportedOperation();
|
||||
}
|
||||
|
||||
override removeExposedFunction(): never {
|
||||
// TODO: Quick win?
|
||||
throw new UnsupportedOperation();
|
||||
override async removeExposedFunction(name: string): Promise<void> {
|
||||
await this.#frame.removeExposedFunction(name);
|
||||
}
|
||||
|
||||
override authenticate(): never {
|
||||
|
@ -674,12 +674,6 @@
|
||||
"parameters": ["firefox"],
|
||||
"expectations": ["SKIP"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[page.spec] Page Page.removeExposedFunction should work",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["webDriverBiDi"],
|
||||
"expectations": ["SKIP"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[page.spec] Page Page.setBypassCSP *",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
|
Loading…
Reference in New Issue
Block a user