diff --git a/package.json b/package.json index 435ee48571..fb180ddd41 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "main": "index.js", "playwright": { "chromium_revision": "724623", - "firefox_revision": "1012", + "firefox_revision": "1013", "webkit_revision": "1092" }, "scripts": { diff --git a/src/chromium/crPage.ts b/src/chromium/crPage.ts index 776809c9cd..a624e0309e 100644 --- a/src/chromium/crPage.ts +++ b/src/chromium/crPage.ts @@ -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__'; diff --git a/src/firefox/ffPage.ts b/src/firefox/ffPage.ts index 6b834d933f..ca1528d830 100644 --- a/src/firefox/ffPage.ts +++ b/src/firefox/ffPage.ts @@ -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[] = [ - 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(handle: dom.ElementHandle, to: dom.FrameExecutionContext): Promise> { - 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; } async getAccessibilityTree(needle?: dom.ElementHandle) { diff --git a/test/click.spec.js b/test/click.spec.js index 4ae9189abf..d0bd619e83 100644 --- a/test/click.spec.js +++ b/test/click.spec.js @@ -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'); diff --git a/test/elementhandle.spec.js b/test/elementhandle.spec.js index 6374313025..0e66417bac 100644 --- a/test/elementhandle.spec.js +++ b/test/elementhandle.spec.js @@ -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'); diff --git a/test/mouse.spec.js b/test/mouse.spec.js index 4586338086..adc0542613 100644 --- a/test/mouse.spec.js +++ b/test/mouse.spec.js @@ -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'); diff --git a/test/page.spec.js b/test/page.spec.js index 5baedc88c4..ea2ae6a10d 100644 --- a/test/page.spec.js +++ b/test/page.spec.js @@ -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'); diff --git a/test/waittask.spec.js b/test/waittask.spec.js index 536581ebc6..384907e878 100644 --- a/test/waittask.spec.js +++ b/test/waittask.spec.js @@ -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(`
1
`);