feat(webkit): use webkit worlds (#194)
This commit is contained in:
parent
5ab6514633
commit
44d6f608ef
|
|
@ -10,7 +10,7 @@
|
|||
"playwright": {
|
||||
"chromium_revision": "719491",
|
||||
"firefox_revision": "1004",
|
||||
"webkit_revision": "1022"
|
||||
"webkit_revision": "1023"
|
||||
},
|
||||
"scripts": {
|
||||
"unit": "node test/test.js",
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ import { Protocol } from './protocol';
|
|||
import { Events as CommonEvents } from '../events';
|
||||
import { toConsoleMessageLocation, exceptionToError, releaseObject } from './protocolHelper';
|
||||
import * as dialog from '../dialog';
|
||||
import * as console from '../console';
|
||||
import { PageDelegate } from '../page';
|
||||
import { RawMouseImpl, RawKeyboardImpl } from './Input';
|
||||
import { CRScreenshotDelegate } from './Screenshotter';
|
||||
|
|
@ -45,6 +44,7 @@ import { Browser } from './Browser';
|
|||
import { BrowserContext } from './BrowserContext';
|
||||
import * as types from '../types';
|
||||
import * as input from '../input';
|
||||
import { ConsoleMessage } from '../console';
|
||||
|
||||
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
||||
|
||||
|
|
@ -331,7 +331,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
await this._client.send('Page.addScriptToEvaluateOnNewDocument', {
|
||||
source: `//# sourceURL=${EVALUATION_SCRIPT_URL}`,
|
||||
worldName: name,
|
||||
}),
|
||||
});
|
||||
await Promise.all(this.frames().map(frame => this._client.send('Page.createIsolatedWorld', {
|
||||
frameId: this._frameData(frame).id,
|
||||
grantUniveralAccess: true,
|
||||
|
|
@ -457,7 +457,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
if (args)
|
||||
args.map(arg => releaseObject(this._client, arg));
|
||||
if (source !== 'worker')
|
||||
this._page.emit(CommonEvents.Page.Console, new console.ConsoleMessage(level, text, [], {url, lineNumber}));
|
||||
this._page.emit(CommonEvents.Page.Console, new ConsoleMessage(level, text, [], {url, lineNumber}));
|
||||
}
|
||||
|
||||
async _onFileChooserOpened(event: Protocol.Page.fileChooserOpenedPayload) {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,6 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
|
|||
try {
|
||||
callFunctionOnPromise = this._session.send('Runtime.callFunctionOn', {
|
||||
functionDeclaration: functionText + '\n' + suffix + '\n',
|
||||
// TODO(yurys): support executionContextId in WebKit
|
||||
objectId: thisObjectId,
|
||||
arguments: serializableArgs.map((arg: any) => this._convertArgument(arg)),
|
||||
returnByValue: false,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import * as network from '../network';
|
|||
import { TargetSession, TargetSessionEvents } from './Connection';
|
||||
import { Events } from './events';
|
||||
import { Events as CommonEvents } from '../events';
|
||||
import { ExecutionContextDelegate } from './ExecutionContext';
|
||||
import { ExecutionContextDelegate, EVALUATION_SCRIPT_URL } from './ExecutionContext';
|
||||
import { NetworkManager, NetworkManagerEvents } from './NetworkManager';
|
||||
import { Page, PageDelegate } from '../page';
|
||||
import { Protocol } from './protocol';
|
||||
|
|
@ -37,6 +37,8 @@ import { WKScreenshotDelegate } from './Screenshotter';
|
|||
import * as input from '../input';
|
||||
import * as types from '../types';
|
||||
|
||||
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
||||
|
||||
export const FrameManagerEvents = {
|
||||
FrameNavigatedWithinDocument: Symbol('FrameNavigatedWithinDocument'),
|
||||
TargetSwappedOnNavigation: Symbol('TargetSwappedOnNavigation'),
|
||||
|
|
@ -98,7 +100,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
]);
|
||||
this._handleFrameTree(frameTree);
|
||||
await Promise.all([
|
||||
this._session.send('Runtime.enable'),
|
||||
this._session.send('Runtime.enable').then(() => this._ensureIsolatedWorld(UTILITY_WORLD_NAME)),
|
||||
this._session.send('Console.enable'),
|
||||
this._session.send('Dialog.enable'),
|
||||
this._session.send('Page.setInterceptFileChooserDialog', { enabled: true }),
|
||||
|
|
@ -293,8 +295,6 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
_onExecutionContextCreated(contextPayload : Protocol.Runtime.ExecutionContextDescription) {
|
||||
if (this._contextIdToContext.has(contextPayload.id))
|
||||
return;
|
||||
if (!contextPayload.isPageContext)
|
||||
return;
|
||||
const frameId = contextPayload.frameId;
|
||||
// If the frame was attached manually there is no navigation event.
|
||||
// FIXME: support frameAttached event in WebKit protocol.
|
||||
|
|
@ -304,8 +304,10 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
const context = new js.ExecutionContext(new ExecutionContextDelegate(this._session, contextPayload));
|
||||
if (frame) {
|
||||
context._domWorld = new dom.DOMWorld(context, new DOMWorldDelegate(this, frame));
|
||||
frame._contextCreated('main', context);
|
||||
frame._contextCreated('utility', context);
|
||||
if (contextPayload.isPageContext)
|
||||
frame._contextCreated('main', context);
|
||||
else if (contextPayload.name === UTILITY_WORLD_NAME)
|
||||
frame._contextCreated('utility', context);
|
||||
}
|
||||
this._contextIdToContext.set(contextPayload.id, context);
|
||||
}
|
||||
|
|
@ -413,7 +415,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
}
|
||||
|
||||
async _onFileChooserOpened(event: {frameId: Protocol.Network.FrameId, element: Protocol.Runtime.RemoteObject}) {
|
||||
const context = await this.frame(event.frameId)._utilityContext();
|
||||
const context = await this.frame(event.frameId)._mainContext();
|
||||
const handle = context._createHandle(event.element).asElement()!;
|
||||
this._page._onFileChooserOpened(handle);
|
||||
}
|
||||
|
|
@ -422,6 +424,16 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
return this._networkManager.setExtraHTTPHeaders(extraHTTPHeaders);
|
||||
}
|
||||
|
||||
async _ensureIsolatedWorld(name: string) {
|
||||
if (this._isolatedWorlds.has(name))
|
||||
return;
|
||||
this._isolatedWorlds.add(name);
|
||||
await this._session.send('Page.createIsolatedWorld', {
|
||||
name,
|
||||
source: `//# sourceURL=${EVALUATION_SCRIPT_URL}`
|
||||
});
|
||||
}
|
||||
|
||||
async setUserAgent(userAgent: string): Promise<void> {
|
||||
await this._session.send('Page.overrideUserAgent', { value: userAgent });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,12 +15,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { debugError, assert } from '../helper';
|
||||
import * as input from '../input';
|
||||
import * as dom from '../dom';
|
||||
import * as frames from '../frames';
|
||||
import { debugError } from '../helper';
|
||||
import * as input from '../input';
|
||||
import * as types from '../types';
|
||||
import { TargetSession } from './Connection';
|
||||
import { ExecutionContextDelegate } from './ExecutionContext';
|
||||
import { FrameManager } from './FrameManager';
|
||||
import { Protocol } from './protocol';
|
||||
|
||||
|
|
@ -99,8 +100,11 @@ export class DOMWorldDelegate implements dom.DOMWorldDelegate {
|
|||
}
|
||||
|
||||
async adoptElementHandle<T extends Node>(handle: dom.ElementHandle<T>, to: dom.DOMWorld): Promise<dom.ElementHandle<T>> {
|
||||
assert(false, 'Multiple isolated worlds are not implemented');
|
||||
return handle;
|
||||
const result = await this._client.send('DOM.resolveNode', {
|
||||
objectId: toRemoteObject(handle).objectId,
|
||||
executionContextId: (to.context._delegate as ExecutionContextDelegate)._contextId
|
||||
});
|
||||
return to.context._createHandle(result.object) as dom.ElementHandle<T>;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ module.exports.addTests = function({testRunner, expect, playwright, FFOX, CHROME
|
|||
await page.click('circle');
|
||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(42);
|
||||
});
|
||||
it.skip(FFOX || WEBKIT)('should click the button if window.Node is removed', async({page, server}) => {
|
||||
it.skip(FFOX)('should click the button if window.Node is removed', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.evaluate(() => delete window.Node);
|
||||
await page.click('button');
|
||||
|
|
|
|||
Loading…
Reference in a new issue