diff --git a/docs/api.md b/docs/api.md index 6159c0ab1596b..df2239efaf66a 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1875,7 +1875,7 @@ await page.evaluateOnNewDocument(preloadFile); #### page.exposeFunction(name, puppeteerFunction) - `name` <[string]> Name of the function on the window object -- `puppeteerFunction` <[function]> Callback function which will be called in Puppeteer's context. +- `puppeteerFunction` <[function]> Callback function which will be called in Puppeteer's context. Can also be a module with a default export. - returns: <[Promise]> The method adds a function called `name` on the page's `window` object. diff --git a/src/common/Page.ts b/src/common/Page.ts index a315840bdec33..0ba3c21bce1c6 100644 --- a/src/common/Page.ts +++ b/src/common/Page.ts @@ -1364,13 +1364,25 @@ export class Page extends EventEmitter { */ async exposeFunction( name: string, - puppeteerFunction: Function + puppeteerFunction: Function | { default: Function } ): Promise { if (this._pageBindings.has(name)) throw new Error( `Failed to add page binding with name ${name}: window['${name}'] already exists!` ); - this._pageBindings.set(name, puppeteerFunction); + + let exposedFunction: Function; + if (typeof puppeteerFunction === 'function') { + exposedFunction = puppeteerFunction; + } else if (typeof puppeteerFunction.default === 'function') { + exposedFunction = puppeteerFunction.default; + } else { + throw new Error( + `Failed to add page binding with name ${name}: ${puppeteerFunction} is not a function or a module with a default export.` + ); + } + + this._pageBindings.set(name, exposedFunction); const expression = helper.pageBindingInitString('exposedFun', name); await this._client.send('Runtime.addBinding', { name: name }); diff --git a/test/page.spec.ts b/test/page.spec.ts index 495ce94e6955c..bd65a07f3c599 100644 --- a/test/page.spec.ts +++ b/test/page.spec.ts @@ -1029,6 +1029,20 @@ describe('Page', function () { ); expect(result.x).toBe(7); }); + it('should fallback to default export when passed a module object', async () => { + const { page, server } = getTestState(); + const moduleObject = { + default: function (a, b) { + return a * b; + }, + }; + await page.goto(server.EMPTY_PAGE); + await page.exposeFunction('compute', moduleObject); + const result = await page.evaluate(async function () { + return await globalThis.compute(9, 4); + }); + expect(result).toBe(36); + }); }); describeFailsFirefox('Page.Events.PageError', function () {