feat(webkit): implement page.exposeFunction (#195)
This commit is contained in:
parent
5ffb710d7d
commit
8c548ed9e9
|
|
@ -16,7 +16,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import * as console from './console';
|
|
||||||
import * as dom from './dom';
|
import * as dom from './dom';
|
||||||
import * as frames from './frames';
|
import * as frames from './frames';
|
||||||
import { assert, debugError, helper } from './helper';
|
import { assert, debugError, helper } from './helper';
|
||||||
|
|
@ -28,6 +27,7 @@ import { TimeoutSettings } from './TimeoutSettings';
|
||||||
import * as types from './types';
|
import * as types from './types';
|
||||||
import { Events } from './events';
|
import { Events } from './events';
|
||||||
import { BrowserContext } from './browserContext';
|
import { BrowserContext } from './browserContext';
|
||||||
|
import { ConsoleMessage, ConsoleMessageLocation } from './console';
|
||||||
|
|
||||||
export interface PageDelegate {
|
export interface PageDelegate {
|
||||||
readonly rawMouse: input.RawMouse;
|
readonly rawMouse: input.RawMouse;
|
||||||
|
|
@ -272,12 +272,12 @@ export class Page<Browser> extends EventEmitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_addConsoleMessage(type: string, args: js.JSHandle[], location: console.ConsoleMessageLocation, text?: string) {
|
_addConsoleMessage(type: string, args: js.JSHandle[], location: ConsoleMessageLocation, text?: string) {
|
||||||
if (!this.listenerCount(Events.Page.Console)) {
|
if (!this.listenerCount(Events.Page.Console)) {
|
||||||
args.forEach(arg => arg.dispose());
|
args.forEach(arg => arg.dispose());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.emit(Events.Page.Console, new console.ConsoleMessage(type, text, args, location));
|
this.emit(Events.Page.Console, new ConsoleMessage(type, text, args, location));
|
||||||
}
|
}
|
||||||
|
|
||||||
url(): string {
|
url(): string {
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ import * as input from '../input';
|
||||||
import * as types from '../types';
|
import * as types from '../types';
|
||||||
|
|
||||||
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
||||||
|
const BINDING_CALL_MESSAGE = '__playwright_binding_call__';
|
||||||
|
|
||||||
export const FrameManagerEvents = {
|
export const FrameManagerEvents = {
|
||||||
FrameNavigatedWithinDocument: Symbol('FrameNavigatedWithinDocument'),
|
FrameNavigatedWithinDocument: Symbol('FrameNavigatedWithinDocument'),
|
||||||
|
|
@ -391,11 +392,18 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
||||||
|
|
||||||
async _onConsoleMessage(event: Protocol.Console.messageAddedPayload) {
|
async _onConsoleMessage(event: Protocol.Console.messageAddedPayload) {
|
||||||
const { type, level, text, parameters, url, line: lineNumber, column: columnNumber } = event.message;
|
const { type, level, text, parameters, url, line: lineNumber, column: columnNumber } = event.message;
|
||||||
|
if (level === 'debug' && parameters && parameters[0].value === BINDING_CALL_MESSAGE) {
|
||||||
|
const parsedObjectId = JSON.parse(parameters[1].objectId);
|
||||||
|
const context = this._contextIdToContext.get(parsedObjectId.injectedScriptId);
|
||||||
|
this._page._onBindingCalled(parameters[2].value, context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
let derivedType: string = type;
|
let derivedType: string = type;
|
||||||
if (type === 'log')
|
if (type === 'log')
|
||||||
derivedType = level;
|
derivedType = level;
|
||||||
else if (type === 'timing')
|
else if (type === 'timing')
|
||||||
derivedType = 'timeEnd';
|
derivedType = 'timeEnd';
|
||||||
|
|
||||||
const mainFrameContext = await this.mainFrame().executionContext();
|
const mainFrameContext = await this.mainFrame().executionContext();
|
||||||
const handles = (parameters || []).map(p => {
|
const handles = (parameters || []).map(p => {
|
||||||
let context: js.ExecutionContext | null = null;
|
let context: js.ExecutionContext | null = null;
|
||||||
|
|
@ -498,8 +506,12 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
||||||
return this._go('Page.goForward', options);
|
return this._go('Page.goForward', options);
|
||||||
}
|
}
|
||||||
|
|
||||||
exposeBinding(name: string, bindingFunction: string): Promise<void> {
|
async exposeBinding(name: string, bindingFunction: string): Promise<void> {
|
||||||
throw new Error('Not implemented');
|
const script = `self.${name} = (param) => console.debug('${BINDING_CALL_MESSAGE}', {}, param); ${bindingFunction}`;
|
||||||
|
this._bootstrapScripts.unshift(script);
|
||||||
|
const source = this._bootstrapScripts.join(';');
|
||||||
|
await this._session.send('Page.setBootstrapScript', { source });
|
||||||
|
await Promise.all(this.frames().map(frame => frame.evaluate(script).catch(debugError)));
|
||||||
}
|
}
|
||||||
|
|
||||||
async evaluateOnNewDocument(script: string): Promise<void> {
|
async evaluateOnNewDocument(script: string): Promise<void> {
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
expect(await frameEvaluation).toBe(42);
|
expect(await frameEvaluation).toBe(42);
|
||||||
});
|
});
|
||||||
it.skip(WEBKIT)('should work from-inside an exposed function', async({page, server}) => {
|
it('should work from-inside an exposed function', async({page, server}) => {
|
||||||
// Setup inpage callback, which calls Page.evaluate
|
// Setup inpage callback, which calls Page.evaluate
|
||||||
await page.exposeFunction('callController', async function(a, b) {
|
await page.exposeFunction('callController', async function(a, b) {
|
||||||
return await page.evaluate((a, b) => a * b, a, b);
|
return await page.evaluate((a, b) => a * b, a, b);
|
||||||
|
|
|
||||||
|
|
@ -396,7 +396,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Page.exposeFunction', function() {
|
describe('Page.exposeFunction', function() {
|
||||||
it.skip(WEBKIT)('should work', async({page, server}) => {
|
it('should work', async({page, server}) => {
|
||||||
await page.exposeFunction('compute', function(a, b) {
|
await page.exposeFunction('compute', function(a, b) {
|
||||||
return a * b;
|
return a * b;
|
||||||
});
|
});
|
||||||
|
|
@ -405,7 +405,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
});
|
});
|
||||||
expect(result).toBe(36);
|
expect(result).toBe(36);
|
||||||
});
|
});
|
||||||
it.skip(WEBKIT)('should throw exception in page context', async({page, server}) => {
|
it('should throw exception in page context', async({page, server}) => {
|
||||||
await page.exposeFunction('woof', function() {
|
await page.exposeFunction('woof', function() {
|
||||||
throw new Error('WOOF WOOF');
|
throw new Error('WOOF WOOF');
|
||||||
});
|
});
|
||||||
|
|
@ -419,7 +419,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
expect(message).toBe('WOOF WOOF');
|
expect(message).toBe('WOOF WOOF');
|
||||||
expect(stack).toContain(__filename);
|
expect(stack).toContain(__filename);
|
||||||
});
|
});
|
||||||
it.skip(WEBKIT)('should support throwing "null"', async({page, server}) => {
|
it('should support throwing "null"', async({page, server}) => {
|
||||||
await page.exposeFunction('woof', function() {
|
await page.exposeFunction('woof', function() {
|
||||||
throw null;
|
throw null;
|
||||||
});
|
});
|
||||||
|
|
@ -432,7 +432,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
});
|
});
|
||||||
expect(thrown).toBe(null);
|
expect(thrown).toBe(null);
|
||||||
});
|
});
|
||||||
it.skip(WEBKIT)('should be callable from-inside evaluateOnNewDocument', async({page, server}) => {
|
it('should be callable from-inside evaluateOnNewDocument', async({page, server}) => {
|
||||||
let called = false;
|
let called = false;
|
||||||
await page.exposeFunction('woof', function() {
|
await page.exposeFunction('woof', function() {
|
||||||
called = true;
|
called = true;
|
||||||
|
|
@ -441,7 +441,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
await page.reload();
|
await page.reload();
|
||||||
expect(called).toBe(true);
|
expect(called).toBe(true);
|
||||||
});
|
});
|
||||||
it.skip(WEBKIT)('should survive navigation', async({page, server}) => {
|
it('should survive navigation', async({page, server}) => {
|
||||||
await page.exposeFunction('compute', function(a, b) {
|
await page.exposeFunction('compute', function(a, b) {
|
||||||
return a * b;
|
return a * b;
|
||||||
});
|
});
|
||||||
|
|
@ -452,7 +452,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
});
|
});
|
||||||
expect(result).toBe(36);
|
expect(result).toBe(36);
|
||||||
});
|
});
|
||||||
it.skip(WEBKIT)('should await returned promise', async({page, server}) => {
|
it('should await returned promise', async({page, server}) => {
|
||||||
await page.exposeFunction('compute', function(a, b) {
|
await page.exposeFunction('compute', function(a, b) {
|
||||||
return Promise.resolve(a * b);
|
return Promise.resolve(a * b);
|
||||||
});
|
});
|
||||||
|
|
@ -462,7 +462,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
});
|
});
|
||||||
expect(result).toBe(15);
|
expect(result).toBe(15);
|
||||||
});
|
});
|
||||||
it.skip(WEBKIT)('should work on frames', async({page, server}) => {
|
it('should work on frames', async({page, server}) => {
|
||||||
await page.exposeFunction('compute', function(a, b) {
|
await page.exposeFunction('compute', function(a, b) {
|
||||||
return Promise.resolve(a * b);
|
return Promise.resolve(a * b);
|
||||||
});
|
});
|
||||||
|
|
@ -474,7 +474,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
});
|
});
|
||||||
expect(result).toBe(15);
|
expect(result).toBe(15);
|
||||||
});
|
});
|
||||||
it.skip(WEBKIT)('should work on frames before navigation', async({page, server}) => {
|
it('should work on frames before navigation', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/frames/nested-frames.html');
|
await page.goto(server.PREFIX + '/frames/nested-frames.html');
|
||||||
await page.exposeFunction('compute', function(a, b) {
|
await page.exposeFunction('compute', function(a, b) {
|
||||||
return Promise.resolve(a * b);
|
return Promise.resolve(a * b);
|
||||||
|
|
@ -486,7 +486,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
});
|
});
|
||||||
expect(result).toBe(15);
|
expect(result).toBe(15);
|
||||||
});
|
});
|
||||||
it.skip(WEBKIT)('should work with complex objects', async({page, server}) => {
|
it('should work with complex objects', async({page, server}) => {
|
||||||
await page.exposeFunction('complexObject', function(a, b) {
|
await page.exposeFunction('complexObject', function(a, b) {
|
||||||
return {x: a.x + b.x};
|
return {x: a.x + b.x};
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue