feat: add page.removeExposedFunction (#10297)

This commit is contained in:
Nikolay Vitkov 2023-06-02 14:08:36 +02:00 committed by GitHub
parent 4764b9a079
commit 4d0dbbc517
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 104 additions and 4 deletions

View File

@ -126,6 +126,7 @@ page.off('request', logRequest);
| [pdf(options)](./puppeteer.page.pdf.md) | | Generates a PDF of the page with the <code>print</code> CSS media type. |
| [queryObjects(prototypeHandle)](./puppeteer.page.queryobjects.md) | | This method iterates the JavaScript heap and finds all objects with the given prototype. |
| [reload(options)](./puppeteer.page.reload.md) | | |
| [removeExposedFunction(name)](./puppeteer.page.removeexposedfunction.md) | | The method removes a previously added function via $[Page.exposeFunction()](./puppeteer.page.exposefunction.md) called <code>name</code> from the page's <code>window</code> object. |
| [removeScriptToEvaluateOnNewDocument(identifier)](./puppeteer.page.removescripttoevaluateonnewdocument.md) | | Removes script that injected into page by Page.evaluateOnNewDocument. |
| [screenshot(options)](./puppeteer.page.screenshot.md) | | Captures screenshot of the current page. |
| [screenshot(options)](./puppeteer.page.screenshot_1.md) | | |

View File

@ -0,0 +1,25 @@
---
sidebar_label: Page.removeExposedFunction
---
# Page.removeExposedFunction() method
The method removes a previously added function via $[Page.exposeFunction()](./puppeteer.page.exposefunction.md) called `name` from the page's `window` object.
#### Signature:
```typescript
class Page {
removeExposedFunction(name: string): Promise<void>;
}
```
## Parameters
| Parameter | Type | Description |
| --------- | ------ | ----------- |
| name | string | |
**Returns:**
Promise&lt;void&gt;

View File

@ -1279,6 +1279,15 @@ export class Page extends EventEmitter {
throw new Error('Not implemented');
}
/**
* The method removes a previously added function via ${@link Page.exposeFunction}
* called `name` from the page's `window` object.
*/
async removeExposedFunction(name: string): Promise<void>;
async removeExposedFunction(): Promise<void> {
throw new Error('Not implemented');
}
/**
* Provide credentials for `HTTP authentication`.
*

View File

@ -147,6 +147,7 @@ export class CDPPage extends Page {
#emulationManager: EmulationManager;
#tracing: Tracing;
#bindings = new Map<string, Binding>();
#exposedFunctions = new Map<string, string>();
#coverage: Coverage;
#javascriptEnabled = true;
#viewport: Viewport | null;
@ -705,10 +706,16 @@ export class CDPPage extends Page {
this.#bindings.set(name, binding);
const expression = pageBindingInitString('exposedFun', name);
await this.#client.send('Runtime.addBinding', {name: name});
await this.#client.send('Page.addScriptToEvaluateOnNewDocument', {
await this.#client.send('Runtime.addBinding', {name});
const {identifier} = await this.#client.send(
'Page.addScriptToEvaluateOnNewDocument',
{
source: expression,
});
}
);
this.#exposedFunctions.set(name, identifier);
await Promise.all(
this.frames().map(frame => {
return frame.evaluate(expression).catch(debugError);
@ -716,6 +723,33 @@ export class CDPPage extends Page {
);
}
override async removeExposedFunction(name: string): Promise<void> {
const exposedFun = this.#exposedFunctions.get(name);
if (!exposedFun) {
throw new Error(
`Failed to remove page binding with name ${name}: window['${name}'] does not exists!`
);
}
await this.#client.send('Runtime.removeBinding', {name});
await this.removeScriptToEvaluateOnNewDocument(exposedFun);
await Promise.all(
this.frames().map(frame => {
return frame
.evaluate(name => {
// Removes the dangling Puppeteer binding wrapper.
// @ts-expect-error: In a different context.
globalThis[name] = undefined;
}, name)
.catch(debugError);
})
);
this.#exposedFunctions.delete(name);
this.#bindings.delete(name);
}
override async authenticate(credentials: Credentials): Promise<void> {
return this.#frameManager.networkManager.authenticate(credentials);
}

View File

@ -2039,6 +2039,12 @@
"parameters": ["cdp", "firefox"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[page.spec] Page Page.removeExposedFunction should work",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[page.spec] Page Page.select should work when re-defining top-level Event class",
"platforms": ["darwin", "linux", "win32"],

View File

@ -1331,6 +1331,31 @@ describe('Page', function () {
});
});
describe('Page.removeExposedFunction', function () {
it('should work', async () => {
const {page} = getTestState();
await page.exposeFunction('compute', function (a: number, b: number) {
return a * b;
});
const result = await page.evaluate(async function () {
return await (globalThis as any).compute(9, 4);
});
expect(result).toBe(36);
await page.removeExposedFunction('compute');
let error: Error | null = null;
await page
.evaluate(async function () {
return (globalThis as any).compute(9, 4);
})
.catch(_error => {
return (error = _error);
});
expect(error).toBeTruthy();
});
});
describe('Page.Events.PageError', function () {
it('should fire', async () => {
const {page, server} = getTestState();