Skip to content

Commit ea833da

Browse files
chore: fix internal binding (#4598)
1 parent 1e754a4 commit ea833da

File tree

4 files changed

+36
-5
lines changed

4 files changed

+36
-5
lines changed

src/server/chromium/crPage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ export class CRPage implements PageDelegate {
128128

129129
async exposeBinding(binding: PageBinding) {
130130
await this._forAllFrameSessions(frame => frame._initBinding(binding));
131-
await Promise.all(this._page.frames().map(frame => frame._evaluateExpression(binding.source, false, {}).catch(e => {})));
131+
await Promise.all(this._page.frames().map(frame => frame._evaluateExpression(binding.source, false, {}, binding.world).catch(e => {})));
132132
}
133133

134134
async updateExtraHTTPHeaders(): Promise<void> {

src/server/dom.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,7 @@ export function waitForSelectorTask(selector: SelectorInfo, state: 'attached' |
879879

880880
export function dispatchEventTask(selector: SelectorInfo, type: string, eventInit: Object): SchedulableTask<undefined> {
881881
return injectedScript => injectedScript.evaluateHandle((injected, { parsed, type, eventInit }) => {
882-
return injected.pollRaf((progress, continuePolling) => {
882+
return injected.pollRaf<undefined>((progress, continuePolling) => {
883883
const element = injected.querySelector(parsed, document);
884884
if (!element)
885885
return continuePolling;

src/server/page.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,13 +257,13 @@ export class Page extends EventEmitter {
257257
this._timeoutSettings.setDefaultTimeout(timeout);
258258
}
259259

260-
async exposeBinding(name: string, needsHandle: boolean, playwrightBinding: frames.FunctionWithSource) {
261-
const identifier = PageBinding.identifier(name, 'main');
260+
async exposeBinding(name: string, needsHandle: boolean, playwrightBinding: frames.FunctionWithSource, world: types.World = 'main') {
261+
const identifier = PageBinding.identifier(name, world);
262262
if (this._pageBindings.has(identifier))
263263
throw new Error(`Function "${name}" has been already registered`);
264264
if (this._browserContext._pageBindings.has(identifier))
265265
throw new Error(`Function "${name}" has been already registered in the browser context`);
266-
const binding = new PageBinding(name, playwrightBinding, needsHandle, 'main');
266+
const binding = new PageBinding(name, playwrightBinding, needsHandle, world);
267267
this._pageBindings.set(identifier, binding);
268268
await this._delegate.exposeBinding(binding);
269269
}

test/page-expose-function.spec.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717

1818
import { it, expect } from './fixtures';
19+
import { attachFrame } from './utils';
1920

2021
it('exposeBinding should work', async ({browser}) => {
2122
const context = await browser.newContext();
@@ -236,3 +237,33 @@ it('should not result in unhandled rejection', async ({page}) => {
236237
// Make a round-trip to be sure we did not throw immediately after closing.
237238
expect(await page.evaluate('1 + 1').catch(e => e)).toBeInstanceOf(Error);
238239
});
240+
241+
it('should work with internal bindings', (test, { mode, browserName }) => {
242+
test.skip(mode !== 'default');
243+
test.skip(browserName !== 'chromium');
244+
}, async ({page, toImpl, server}) => {
245+
const implPage: import('../src/server/page').Page = toImpl(page);
246+
let foo;
247+
await implPage.exposeBinding('foo', false, ({}, arg) => {
248+
foo = arg;
249+
}, 'utility');
250+
expect(await page.evaluate('!!window.foo')).toBe(false);
251+
expect(await implPage.mainFrame()._evaluateExpression('!!window.foo', false, {}, 'utility')).toBe(true);
252+
expect(foo).toBe(undefined);
253+
await implPage.mainFrame()._evaluateExpression('window.foo(123)', false, {}, 'utility');
254+
expect(foo).toBe(123);
255+
256+
// should work after reload
257+
await page.goto(server.EMPTY_PAGE);
258+
expect(await page.evaluate('!!window.foo')).toBe(false);
259+
await implPage.mainFrame()._evaluateExpression('window.foo(456)', false, {}, 'utility');
260+
expect(foo).toBe(456);
261+
262+
// should work inside frames
263+
const frame = await attachFrame(page, 'myframe', server.CROSS_PROCESS_PREFIX + '/empty.html');
264+
expect(await frame.evaluate('!!window.foo')).toBe(false);
265+
const implFrame: import('../src/server/frames').Frame = toImpl(frame);
266+
await implFrame._evaluateExpression('window.foo(789)', false, {}, 'utility');
267+
expect(foo).toBe(789);
268+
});
269+

0 commit comments

Comments
 (0)