feat(webkit): page.on('popup') (#202)

This commit is contained in:
Joel Einbinder 2019-12-10 15:07:01 -08:00 committed by Andrey Lushnikov
parent c8067dbcde
commit 0af3b9dfc8
3 changed files with 29 additions and 8 deletions

View File

@ -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<Target>(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}) {

View File

@ -29,7 +29,7 @@ export class Target {
readonly _type: 'page' | 'service-worker' | 'worker';
private readonly _session: TargetSession;
private _pagePromise: Promise<Page<Browser, BrowserContext>> | null = null;
private _page: Page<Browser, BrowserContext> | null = null;
_page: Page<Browser, BrowserContext> | null = null;
static fromPage(page: Page<Browser, BrowserContext>): Target {
return (page as any)[targetSymbol];

View File

@ -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('<a target=_blank href="/one-style.html">yo</a>');
await page.setContent('<a target=_blank rel="opener" href="/one-style.html">yo</a>');
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('<a target=_blank rel=noopener href="/one-style.html">yo</a>');
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();