diff --git a/src/webkit/Browser.ts b/src/webkit/Browser.ts index bbd7a12472..c3df18b6d0 100644 --- a/src/webkit/Browser.ts +++ b/src/webkit/Browser.ts @@ -24,6 +24,7 @@ import { Page } from '../page'; import { Target } from './Target'; import { Protocol } from './protocol'; import * as types from '../types'; +import { Events } from '../events'; export class Browser extends EventEmitter { readonly _defaultViewport: types.Viewport; @@ -125,7 +126,7 @@ export class Browser extends EventEmitter { const existingTarget = this.targets().find(predicate); if (existingTarget) return existingTarget; - let resolve; + let resolve : (a: Target) => void; const targetPromise = new Promise(x => resolve = x); this._privateEvents.on(BrowserEvents.TargetCreated, check); try { @@ -169,6 +170,16 @@ export class Browser extends EventEmitter { oldTarget._initializeSession(session); } this._privateEvents.emit(BrowserEvents.TargetCreated, target); + if (!targetInfo.oldTargetId && targetInfo.openerId) { + const opener = this._targets.get(targetInfo.openerId); + if (!opener) + return; + const openerPage = opener._page; + if (!openerPage || !openerPage.listenerCount(Events.Page.Popup)) + return; + const page = await target.page(); + openerPage.emit(Events.Page.Popup, page); + } } _onTargetDestroyed({targetId}) { diff --git a/src/webkit/Target.ts b/src/webkit/Target.ts index b097b507ae..3ce0af0d49 100644 --- a/src/webkit/Target.ts +++ b/src/webkit/Target.ts @@ -29,7 +29,7 @@ export class Target { readonly _type: 'page' | 'service-worker' | 'worker'; private readonly _session: TargetSession; private _pagePromise: Promise> | null = null; - private _page: Page | null = null; + _page: Page | null = null; static fromPage(page: Page): Target { return (page as any)[targetSymbol]; diff --git a/test/page.spec.js b/test/page.spec.js index 0a56966f09..bb2d14bf07 100644 --- a/test/page.spec.js +++ b/test/page.spec.js @@ -118,7 +118,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF }); }); - describe.skip(WEBKIT)('Page.Events.Popup', function() { + describe('Page.Events.Popup', function() { it('should work', async({page}) => { const [popup] = await Promise.all([ new Promise(x => page.once('popup', x)), @@ -137,7 +137,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF }); it('should work with clicking target=_blank', async({page, server}) => { await page.goto(server.EMPTY_PAGE); - await page.setContent('yo'); + await page.setContent('yo'); const [popup] = await Promise.all([ new Promise(x => page.once('popup', x)), page.click('a'), @@ -165,6 +165,18 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF expect(await page.evaluate(() => !!window.opener)).toBe(false); expect(await popup.evaluate(() => !!window.opener)).toBe(false); }); + it('should not treat navigations as new popups', async({page, server}) => { + await page.goto(server.EMPTY_PAGE); + await page.setContent('yo'); + const [popup] = await Promise.all([ + new Promise(x => page.once('popup', x)), + page.click('a'), + ]); + let badSecondPopup = false; + page.on('popup', () => badSecondPopup = true); + await popup.goto(server.CROSS_PROCESS_PREFIX + '/empty.html'); + expect(badSecondPopup).toBe(false); + }) }); describe('Page.Events.Console', function() { @@ -1154,10 +1166,8 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF }); }); - // FIXME: WebKit shouldn't send targetDestroyed on PSON so that we could - // convert target destroy events into close. describe('Page.Events.Close', function() { - it.skip(WEBKIT)('should work with window.close', async function({ browser, page, context, server }) { + it('should work with window.close', async function({ browser, page, context, server }) { const newPagePromise = new Promise(f => page.once('popup', f)); await page.evaluate(() => window['newPage'] = window.open('about:blank')); const newPage = await newPagePromise; @@ -1165,7 +1175,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF await page.evaluate(() => window['newPage'].close()); await closedPromise; }); - it.skip(WEBKIT)('should work with page.close', async function({ page, context, server }) { + it('should work with page.close', async function({ page, context, server }) { const newPage = await context.newPage(); const closedPromise = new Promise(x => newPage.on('close', x)); await newPage.close();