Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(page): introduce "Popup" event #3661

Merged
merged 1 commit into from
Dec 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 20 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
* [event: 'load'](#event-load)
* [event: 'metrics'](#event-metrics)
* [event: 'pageerror'](#event-pageerror)
* [event: 'popup'](#event-popup)
* [event: 'request'](#event-request)
* [event: 'requestfailed'](#event-requestfailed)
* [event: 'requestfinished'](#event-requestfinished)
Expand Down Expand Up @@ -963,6 +964,25 @@ of metrics see `page.metrics`.

Emitted when an uncaught exception happens within the page.

#### event: 'popup'
- <[Page]> Page corresponding to "popup" window

Emitted when the page opens a new tab or window.

```js
const [popup] = await Promise.all([
new Promise(resolve => page.once('popup', resolve)),
page.click('a[target=_blank]'),
]);
```

```js
const [popup] = await Promise.all([
new Promise(resolve => page.once('popup', resolve)),
page.evaluate(() => window.open('https://example.com')),
]);
```

#### event: 'request'
- <[Request]>

Expand Down
1 change: 1 addition & 0 deletions lib/Page.js
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,7 @@ Page.Events = {
FrameNavigated: 'framenavigated',
Load: 'load',
Metrics: 'metrics',
Popup: 'popup',
WorkerCreated: 'workercreated',
WorkerDestroyed: 'workerdestroyed',
};
Expand Down
14 changes: 13 additions & 1 deletion lib/Target.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,19 @@ class Target {
this._screenshotTaskQueue = screenshotTaskQueue;
/** @type {?Promise<!Puppeteer.Page>} */
this._pagePromise = null;
this._initializedPromise = new Promise(fulfill => this._initializedCallback = fulfill);
this._initializedPromise = new Promise(fulfill => this._initializedCallback = fulfill).then(async success => {
if (!success)
return false;
const opener = this.opener();
if (!opener || !opener._pagePromise || this.type() !== 'page')
return true;
const openerPage = await opener._pagePromise;
if (!openerPage.listenerCount(Page.Events.Popup))
return true;
const popupPage = await this.page();
openerPage.emit(Page.Events.Popup, popupPage);
return true;
});
this._isClosedPromise = new Promise(fulfill => this._closedCallback = fulfill);
this._isInitialized = this._targetInfo.type !== 'page' || this._targetInfo.url !== '';
if (this._isInitialized)
Expand Down
49 changes: 49 additions & 0 deletions test/page.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,55 @@ module.exports.addTests = function({testRunner, expect, headless}) {
});
});

describe('Page.Events.Popup', function() {
it('should work', async({page}) => {
const [popup] = await Promise.all([
new Promise(x => page.once('popup', x)),
page.evaluate(() => window.open('about:blank')),
]);
expect(await page.evaluate(() => !!window.opener)).toBe(false);
expect(await popup.evaluate(() => !!window.opener)).toBe(true);
});
it('should work with noopener', async({page}) => {
const [popup] = await Promise.all([
new Promise(x => page.once('popup', x)),
page.evaluate(() => window.open('about:blank', null, 'noopener')),
]);
expect(await page.evaluate(() => !!window.opener)).toBe(false);
expect(await popup.evaluate(() => !!window.opener)).toBe(false);
});
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>');
const [popup] = await Promise.all([
new Promise(x => page.once('popup', x)),
page.click('a'),
]);
expect(await page.evaluate(() => !!window.opener)).toBe(false);
expect(await popup.evaluate(() => !!window.opener)).toBe(true);
});
it('should work with fake-clicking target=_blank and rel=noopener', 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.$eval('a', a => a.click()),
]);
expect(await page.evaluate(() => !!window.opener)).toBe(false);
expect(await popup.evaluate(() => !!window.opener)).toBe(false);
});
it('should work with clicking target=_blank and rel=noopener', 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'),
]);
expect(await page.evaluate(() => !!window.opener)).toBe(false);
expect(await popup.evaluate(() => !!window.opener)).toBe(false);
});
});

describe('BrowserContext.overridePermissions', function() {
function getPermission(page, name) {
return page.evaluate(name => navigator.permissions.query({name}).then(result => result.state), name);
Expand Down