mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
feat(firefox): support isolated worlds (#507)
This commit is contained in:
parent
6b0b7500bd
commit
21510a5b06
@ -9,7 +9,7 @@
|
||||
"main": "index.js",
|
||||
"playwright": {
|
||||
"chromium_revision": "724623",
|
||||
"firefox_revision": "1012",
|
||||
"firefox_revision": "1013",
|
||||
"webkit_revision": "1092"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@ -38,7 +38,6 @@ import { CRBrowser } from './crBrowser';
|
||||
import { BrowserContext } from '../browserContext';
|
||||
import * as types from '../types';
|
||||
import { ConsoleMessage } from '../console';
|
||||
import * as accessibility from '../accessibility';
|
||||
import * as platform from '../platform';
|
||||
|
||||
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import * as frames from '../frames';
|
||||
import { assert, helper, RegisteredListener, debugError } from '../helper';
|
||||
import { helper, RegisteredListener, debugError } from '../helper';
|
||||
import * as dom from '../dom';
|
||||
import { FFSession } from './ffConnection';
|
||||
import { FFExecutionContext } from './ffExecutionContext';
|
||||
@ -30,10 +30,11 @@ import { BrowserContext } from '../browserContext';
|
||||
import { getAccessibilityTree } from './ffAccessibility';
|
||||
import * as network from '../network';
|
||||
import * as types from '../types';
|
||||
import * as accessibility from '../accessibility';
|
||||
import * as platform from '../platform';
|
||||
import { kScreenshotDuringNavigationError } from '../screenshotter';
|
||||
|
||||
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
||||
|
||||
export class FFPage implements PageDelegate {
|
||||
readonly rawMouse: RawMouseImpl;
|
||||
readonly rawKeyboard: RawKeyboardImpl;
|
||||
@ -70,7 +71,7 @@ export class FFPage implements PageDelegate {
|
||||
|
||||
async _initialize() {
|
||||
const promises: Promise<any>[] = [
|
||||
this._session.send('Runtime.enable'),
|
||||
this._session.send('Runtime.enable').then(() => this._ensureIsolatedWorld(UTILITY_WORLD_NAME)),
|
||||
this._session.send('Network.enable'),
|
||||
this._session.send('Page.enable'),
|
||||
this._session.send('Page.setInterceptFileChooserDialog', { enabled: true })
|
||||
@ -87,6 +88,13 @@ export class FFPage implements PageDelegate {
|
||||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
async _ensureIsolatedWorld(name: string) {
|
||||
await this._session.send('Page.addScriptToEvaluateOnNewDocument', {
|
||||
script: '',
|
||||
worldName: name,
|
||||
});
|
||||
}
|
||||
|
||||
_onExecutionContextCreated(payload: Protocol.Runtime.executionContextCreatedPayload) {
|
||||
const {executionContextId, auxData} = payload;
|
||||
const frame = this._page._frameManager.frame(auxData ? auxData.frameId : null);
|
||||
@ -94,8 +102,10 @@ export class FFPage implements PageDelegate {
|
||||
return;
|
||||
const delegate = new FFExecutionContext(this._session, executionContextId);
|
||||
const context = new dom.FrameExecutionContext(delegate, frame);
|
||||
frame._contextCreated('main', context);
|
||||
frame._contextCreated('utility', context);
|
||||
if (auxData.name === UTILITY_WORLD_NAME)
|
||||
frame._contextCreated('utility', context);
|
||||
else if (!auxData.name)
|
||||
frame._contextCreated('main', context);
|
||||
this._contextIdToContext.set(executionContextId, context);
|
||||
}
|
||||
|
||||
@ -351,8 +361,12 @@ export class FFPage implements PageDelegate {
|
||||
}
|
||||
|
||||
async adoptElementHandle<T extends Node>(handle: dom.ElementHandle<T>, to: dom.FrameExecutionContext): Promise<dom.ElementHandle<T>> {
|
||||
assert(false, 'Multiple isolated worlds are not implemented');
|
||||
return handle;
|
||||
const result = await this._session.send('Page.adoptNode', {
|
||||
frameId: handle._context.frame._id,
|
||||
objectId: toRemoteObject(handle).objectId!,
|
||||
executionContextId: (to._delegate as FFExecutionContext)._executionContextId
|
||||
});
|
||||
return to._createHandle(result.remoteObject) as dom.ElementHandle<T>;
|
||||
}
|
||||
|
||||
async getAccessibilityTree(needle?: dom.ElementHandle) {
|
||||
|
||||
@ -37,7 +37,7 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
|
||||
await page.click('circle');
|
||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(42);
|
||||
});
|
||||
it.skip(FFOX)('should click the button if window.Node is removed', async({page, server}) => {
|
||||
it('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');
|
||||
|
||||
@ -182,7 +182,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||
await button.click();
|
||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
||||
});
|
||||
it.skip(FFOX)('should work with Node removed', async({page, server}) => {
|
||||
it('should work with Node removed', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.evaluate(() => delete window['Node']);
|
||||
const button = await page.$('button');
|
||||
@ -239,7 +239,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||
await button.hover();
|
||||
expect(await page.evaluate(() => document.querySelector('button:hover').id)).toBe('button-6');
|
||||
});
|
||||
it.skip(FFOX)('should work when Node is removed', async({page, server}) => {
|
||||
it('should work when Node is removed', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/scrollable.html');
|
||||
await page.evaluate(() => delete window['Node']);
|
||||
const button = await page.$('#button-6');
|
||||
@ -257,7 +257,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||
expect(Math.round(ratio * 10)).toBe(10 - i);
|
||||
}
|
||||
});
|
||||
it.skip(FFOX)('should work when Node is removed', async({page, server}) => {
|
||||
it('should work when Node is removed', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/offscreenbuttons.html');
|
||||
await page.evaluate(() => delete window['Node']);
|
||||
for (let i = 0; i < 11; ++i) {
|
||||
@ -290,7 +290,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||
await handle.fill('some value');
|
||||
expect(await page.evaluate(() => result)).toBe('some value');
|
||||
});
|
||||
it.skip(FFOX)('should fill input when Node is removed', async({page, server}) => {
|
||||
it('should fill input when Node is removed', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
await page.evaluate(() => delete window['Node']);
|
||||
const handle = await page.$('input');
|
||||
|
||||
@ -98,7 +98,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT,
|
||||
await page.hover('#button-91');
|
||||
expect(await page.evaluate(() => document.querySelector('button:hover').id)).toBe('button-91');
|
||||
});
|
||||
it.skip(FFOX)('should trigger hover state with removed window.Node', async({page, server}) => {
|
||||
it('should trigger hover state with removed window.Node', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/scrollable.html');
|
||||
await page.evaluate(() => delete window.Node);
|
||||
await page.hover('#button-6');
|
||||
|
||||
@ -960,7 +960,7 @@ module.exports.describe = function({testRunner, expect, headless, playwright, FF
|
||||
expect(error.message).toContain('Indices must be numbers');
|
||||
});
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/3327
|
||||
it.skip(FFOX)('should work when re-defining top-level Event class', async({page, server}) => {
|
||||
it('should work when re-defining top-level Event class', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.evaluate(() => window.Event = null);
|
||||
await page.select('select', 'blue');
|
||||
|
||||
@ -246,7 +246,7 @@ module.exports.describe = function({testRunner, expect, product, playwright, FFO
|
||||
await frame.waitForSelector('div');
|
||||
});
|
||||
|
||||
it.skip(FFOX)('should work with removed MutationObserver', async({page, server}) => {
|
||||
it('should work with removed MutationObserver', async({page, server}) => {
|
||||
await page.evaluate(() => delete window.MutationObserver);
|
||||
const [handle] = await Promise.all([
|
||||
page.waitForSelector('.zombo'),
|
||||
@ -318,7 +318,7 @@ module.exports.describe = function({testRunner, expect, product, playwright, FFO
|
||||
await waitForSelector;
|
||||
expect(boxFound).toBe(true);
|
||||
});
|
||||
it.skip(FFOX)('should wait for visible', async({page, server}) => {
|
||||
it('should wait for visible', async({page, server}) => {
|
||||
let divFound = false;
|
||||
const waitForSelector = page.waitForSelector('div').then(() => divFound = true);
|
||||
await page.setContent(`<div style='display: none; visibility: hidden;'>1</div>`);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user