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

chore(docs): migrate & document all Page events #6154

Merged
merged 2 commits into from Jul 6, 2020
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
2 changes: 1 addition & 1 deletion new-docs/puppeteer.md
Expand Up @@ -27,7 +27,7 @@
| [JSHandle](./puppeteer.jshandle.md) | Represents an in-page JavaScript object. JSHandles can be created with the [page.evaluateHandle](./puppeteer.page.evaluatehandle.md) method. |
| [Keyboard](./puppeteer.keyboard.md) | Keyboard provides an api for managing a virtual keyboard. The high level api is [Keyboard.type()](./puppeteer.keyboard.type.md)<!-- -->, which takes raw characters and generates proper keydown, keypress/input, and keyup events on your page. |
| [Mouse](./puppeteer.mouse.md) | The Mouse class operates in main-frame CSS pixels relative to the top-left corner of the viewport. |
| [Page](./puppeteer.page.md) | Page provides methods to interact with a single tab or \[extension background page\](https://developer.chrome.com/extensions/background\_pages) in Chromium. One \[Browser\] instance might have multiple \[Page\] instances. |
| [Page](./puppeteer.page.md) | Page provides methods to interact with a single tab or [extension background page](https://developer.chrome.com/extensions/background_pages) in Chromium. |
| [Puppeteer](./puppeteer.puppeteer.md) | The main Puppeteer class Puppeteer module provides a method to launch a browser instance. |
| [SecurityDetails](./puppeteer.securitydetails.md) | The SecurityDetails class represents the security details of a response that was received over a secure connection. |
| [Target](./puppeteer.target.md) | |
Expand Down
4 changes: 3 additions & 1 deletion new-docs/puppeteer.page.md
Expand Up @@ -4,7 +4,7 @@

## Page class

Page provides methods to interact with a single tab or \[extension background page\](https://developer.chrome.com/extensions/background\_pages) in Chromium. One \[Browser\] instance might have multiple \[Page\] instances.
Page provides methods to interact with a single tab or [extension background page](https://developer.chrome.com/extensions/background_pages) in Chromium.

<b>Signature:</b>

Expand All @@ -15,6 +15,8 @@ export declare class Page extends EventEmitter

## Remarks

One Browser instance might have multiple Page instances.

The constructor for this class is marked as internal. Third-party code should not call the constructor directly or create subclasses that extend the `Page` class.

## Example 1
Expand Down
17 changes: 17 additions & 0 deletions new-docs/puppeteer.pageemittedevents.md
Expand Up @@ -16,5 +16,22 @@ export declare const enum PageEmittedEvents

| Member | Value | Description |
| --- | --- | --- |
| Close | <code>&quot;close&quot;</code> | Emitted when the page closes. |
| Console | <code>&quot;console&quot;</code> | Emitted when JavaScript within the page calls one of console API methods, e.g. <code>console.log</code> or <code>console.dir</code>. Also emitted if the page throws an error or a warning. |
| Dialog | <code>&quot;dialog&quot;</code> | Emitted when a JavaScript dialog appears, such as <code>alert</code>, <code>prompt</code>, <code>confirm</code> or <code>beforeunload</code>. Puppeteer can respond to the dialog via [Dialog.accept()](./puppeteer.dialog.accept.md) or [Dialog.dismiss()](./puppeteer.dialog.dismiss.md)<!-- -->. |
| DOMContentLoaded | <code>&quot;domcontentloaded&quot;</code> | Emitted when the JavaScript [DOMContentLoaded](https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded) event is dispatched. |
| Error | <code>&quot;error&quot;</code> | Emitted when the page crashes. Will contain an <code>Error</code>. |
| FrameAttached | <code>&quot;frameattached&quot;</code> | Emitted when a frame is attached. Will contain a [Frame](./puppeteer.frame.md)<!-- -->. |
| FrameDetached | <code>&quot;framedetached&quot;</code> | Emitted when a frame is detached. Will contain a [Frame](./puppeteer.frame.md)<!-- -->. |
| FrameNavigated | <code>&quot;framenavigated&quot;</code> | Emitted when a frame is navigated to a new URL. Will contain a [Frame](./puppeteer.frame.md)<!-- -->. |
| Load | <code>&quot;load&quot;</code> | Emitted when the JavaScript [load](https://developer.mozilla.org/en-US/docs/Web/Events/load) event is dispatched. |
| Metrics | <code>&quot;metrics&quot;</code> | Emitted when the JavaScript code makes a call to <code>console.timeStamp</code>. For the list of metrics see [page.metrics](./puppeteer.page.metrics.md)<!-- -->. |
| PageError | <code>&quot;pageerror&quot;</code> | Emitted when an uncaught exception happens within the page. Contains an <code>Error</code>. |
| Popup | <code>&quot;popup&quot;</code> | Emitted when the page opens a new tab or window.<!-- -->Contains a [Page](./puppeteer.page.md) corresponding to the popup window. |
| Request | <code>&quot;request&quot;</code> | Emitted when a page issues a request and contains a [HTTPRequest](./puppeteer.httprequest.md)<!-- -->. |
| RequestFailed | <code>&quot;requestfailed&quot;</code> | Emitted when a request fails, for example by timing out.<!-- -->Contains a [HTTPRequest](./puppeteer.httprequest.md)<!-- -->. |
| RequestFinished | <code>&quot;requestfinished&quot;</code> | Emitted when a request finishes successfully. Contains a [HTTPRequest](./puppeteer.httprequest.md)<!-- -->. |
| Response | <code>&quot;response&quot;</code> | Emitted when a response is received. Contains a [HTTPResponse](./puppeteer.httpresponse.md)<!-- -->. |
| WorkerCreated | <code>&quot;workercreated&quot;</code> | Emitted when a dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is spawned by the page. |
| WorkerDestroyed | <code>&quot;workerdestroyed&quot;</code> | Emitted when a dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is destroyed by the page. |

166 changes: 144 additions & 22 deletions src/common/Page.ts
Expand Up @@ -198,13 +198,134 @@ type VisionDeficiency =
* @public
*/
export const enum PageEmittedEvents {
/** Emitted when the page closes. */
Close = 'close',
/**
* Emitted when JavaScript within the page calls one of console API methods,
* e.g. `console.log` or `console.dir`. Also emitted if the page throws an
* error or a warning.
*
* @remarks
*
* A `console` event provides a {@link ConsoleMessage} representing the
* console message that was logged.
*
* @example
* An example of handling `console` event:
* ```js
* page.on('console', msg => {
* for (let i = 0; i < msg.args().length; ++i)
* console.log(`${i}: ${msg.args()[i]}`);
* });
* page.evaluate(() => console.log('hello', 5, {foo: 'bar'}));
* ```
*/
Console = 'console',
/**
* Emitted when a JavaScript dialog appears, such as `alert`, `prompt`,
* `confirm` or `beforeunload`. Puppeteer can respond to the dialog via
* {@link Dialog.accept} or {@link Dialog.dismiss}.
*/
Dialog = 'dialog',
/**
* Emitted when the JavaScript
* {@link https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded | DOMContentLoaded } event is dispatched.
*/
DOMContentLoaded = 'domcontentloaded',
/**
* Emitted when the page crashes. Will contain an `Error`.
*/
Error = 'error',
/** Emitted when a frame is attached. Will contain a {@link Frame}. */
FrameAttached = 'frameattached',
/** Emitted when a frame is detached. Will contain a {@link Frame}. */
FrameDetached = 'framedetached',
/** Emitted when a frame is navigated to a new URL. Will contain a {@link Frame}. */
FrameNavigated = 'framenavigated',
/**
* Emitted when the JavaScript
* {@link https://developer.mozilla.org/en-US/docs/Web/Events/load | load}
* event is dispatched.
*/
Load = 'load',
/**
* Emitted when the JavaScript code makes a call to `console.timeStamp`. For
* the list of metrics see {@link Page.metrics | page.metrics}.
*
* @remarks
* Contains an object with two properties:
* - `title`: the title passed to `console.timeStamp`
* - `metrics`: objec containing metrics as key/value pairs. The values will
* be `number`s.
*/
Metrics = 'metrics',
/**
* Emitted when an uncaught exception happens within the page.
* Contains an `Error`.
*/
PageError = 'pageerror',
/**
* Emitted when the page opens a new tab or window.
*
* Contains a {@link Page} corresponding to the popup window.
*
* @example
*
* ```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')),
* ]);
* ```
*/
Popup = 'popup',
/**
* Emitted when a page issues a request and contains a {@link HTTPRequest}.
*
* @remarks
* The object is readonly. See {@Page.setRequestInterception} for intercepting
* and mutating requests.
*/
Request = 'request',
/**
* Emitted when a request fails, for example by timing out.
*
* Contains a {@link HTTPRequest}.
*
* @remarks
*
* NOTE: HTTP Error responses, such as 404 or 503, are still successful
* responses from HTTP standpoint, so request will complete with
* `requestfinished` event and not with `requestfailed`.
*/
RequestFailed = 'requestfailed',
/**
* Emitted when a request finishes successfully. Contains a {@link HTTPRequest}.
*/
RequestFinished = 'requestfinished',
/**
* Emitted when a response is received. Contains a {@link HTTPResponse}.
*/
Response = 'response',
/**
* Emitted when a dedicated
* {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API | WebWorker}
* is spawned by the page.
* @eventProperty
*/
WorkerCreated = 'workercreated',
/**
* Emitted when a dedicated
* {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API | WebWorker}
* is destroyed by the page.
*/
WorkerDestroyed = 'workerdestroyed',
}

class ScreenshotTaskQueue {
Expand All @@ -224,12 +345,13 @@ class ScreenshotTaskQueue {
}

/**
* Page provides methods to interact with a single tab or [extension background
* page](https://developer.chrome.com/extensions/background_pages) in Chromium.
* One [Browser] instance might have multiple [Page] instances.
* Page provides methods to interact with a single tab or
* {@link https://developer.chrome.com/extensions/background_pages | extension background page} in Chromium.
*
* @remarks
*
* One Browser instance might have multiple Page instances.
*
* @example
* This example creates a page, navigates it to a URL, and then * saves a screenshot:
* ```js
Expand All @@ -244,7 +366,7 @@ class ScreenshotTaskQueue {
* })();
* ```
*
* The Page class extends from Puppeteer's {@link EventEmitter } class and will
* The Page class extends from Puppeteer's {@link EventEmitter} class and will
* emit various events which are documented in the {@link PageEmittedEvents} enum.
*
* @example
Expand Down Expand Up @@ -350,39 +472,39 @@ export class Page extends EventEmitter {
client.on('Target.detachedFromTarget', (event) => {
const worker = this._workers.get(event.sessionId);
if (!worker) return;
this.emit(Events.Page.WorkerDestroyed, worker);
this.emit(PageEmittedEvents.WorkerDestroyed, worker);
this._workers.delete(event.sessionId);
});

this._frameManager.on(Events.FrameManager.FrameAttached, (event) =>
this.emit(Events.Page.FrameAttached, event)
this.emit(PageEmittedEvents.FrameAttached, event)
);
this._frameManager.on(Events.FrameManager.FrameDetached, (event) =>
this.emit(Events.Page.FrameDetached, event)
this.emit(PageEmittedEvents.FrameDetached, event)
);
this._frameManager.on(Events.FrameManager.FrameNavigated, (event) =>
this.emit(Events.Page.FrameNavigated, event)
this.emit(PageEmittedEvents.FrameNavigated, event)
);

const networkManager = this._frameManager.networkManager();
networkManager.on(Events.NetworkManager.Request, (event) =>
this.emit(Events.Page.Request, event)
this.emit(PageEmittedEvents.Request, event)
);
networkManager.on(Events.NetworkManager.Response, (event) =>
this.emit(Events.Page.Response, event)
this.emit(PageEmittedEvents.Response, event)
);
networkManager.on(Events.NetworkManager.RequestFailed, (event) =>
this.emit(Events.Page.RequestFailed, event)
this.emit(PageEmittedEvents.RequestFailed, event)
);
networkManager.on(Events.NetworkManager.RequestFinished, (event) =>
this.emit(Events.Page.RequestFinished, event)
this.emit(PageEmittedEvents.RequestFinished, event)
);
this._fileChooserInterceptors = new Set();

client.on('Page.domContentEventFired', () =>
this.emit(Events.Page.DOMContentLoaded)
this.emit(PageEmittedEvents.DOMContentLoaded)
);
client.on('Page.loadEventFired', () => this.emit(Events.Page.Load));
client.on('Page.loadEventFired', () => this.emit(PageEmittedEvents.Load));
client.on('Runtime.consoleAPICalled', (event) => this._onConsoleAPI(event));
client.on('Runtime.bindingCalled', (event) => this._onBindingCalled(event));
client.on('Page.javascriptDialogOpening', (event) => this._onDialog(event));
Expand All @@ -394,7 +516,7 @@ export class Page extends EventEmitter {
client.on('Log.entryAdded', (event) => this._onLogEntryAdded(event));
client.on('Page.fileChooserOpened', (event) => this._onFileChooser(event));
this._target._isClosedPromise.then(() => {
this.emit(Events.Page.Close);
this.emit(PageEmittedEvents.Close);
this._closed = true;
});
}
Expand Down Expand Up @@ -523,7 +645,7 @@ export class Page extends EventEmitter {
if (args) args.map((arg) => helper.releaseObject(this._client, arg));
if (source !== 'worker')
this.emit(
Events.Page.Console,
PageEmittedEvents.Console,
new ConsoleMessage(level, text, [], { url, lineNumber })
);
}
Expand Down Expand Up @@ -963,7 +1085,7 @@ export class Page extends EventEmitter {
}

private _emitMetrics(event: Protocol.Performance.metricsPayload): void {
this.emit(Events.Page.Metrics, {
this.emit(PageEmittedEvents.Metrics, {
title: event.title,
metrics: this._buildMetricsObject(event.metrics),
});
Expand All @@ -985,7 +1107,7 @@ export class Page extends EventEmitter {
const message = helper.getExceptionMessage(exceptionDetails);
const err = new Error(message);
err.stack = ''; // Don't report clientside error with a node stack attached
this.emit(Events.Page.PageError, err);
this.emit(PageEmittedEvents.PageError, err);
}

private async _onConsoleAPI(
Expand Down Expand Up @@ -1078,7 +1200,7 @@ export class Page extends EventEmitter {
args: JSHandle[],
stackTrace?: Protocol.Runtime.StackTrace
): void {
if (!this.listenerCount(Events.Page.Console)) {
if (!this.listenerCount(PageEmittedEvents.Console)) {
args.forEach((arg) => arg.dispose());
return;
}
Expand All @@ -1102,7 +1224,7 @@ export class Page extends EventEmitter {
args,
location
);
this.emit(Events.Page.Console, message);
this.emit(PageEmittedEvents.Console, message);
}

private _onDialog(event: Protocol.Page.javascriptDialogOpeningPayload): void {
Expand All @@ -1125,7 +1247,7 @@ export class Page extends EventEmitter {
event.message,
event.defaultPrompt
);
this.emit(Events.Page.Dialog, dialog);
this.emit(PageEmittedEvents.Dialog, dialog);
}

url(): string {
Expand Down
7 changes: 3 additions & 4 deletions src/common/Target.ts
Expand Up @@ -14,8 +14,7 @@
* limitations under the License.
*/

import { Events } from './Events';
import { Page } from './Page';
import { Page, PageEmittedEvents } from './Page';
import { WebWorker } from './WebWorker';
import { CDPSession } from './Connection';
import { Browser, BrowserContext } from './Browser';
Expand Down Expand Up @@ -87,9 +86,9 @@ export class Target {
if (!opener || !opener._pagePromise || this.type() !== 'page')
return true;
const openerPage = await opener._pagePromise;
if (!openerPage.listenerCount(Events.Page.Popup)) return true;
if (!openerPage.listenerCount(PageEmittedEvents.Popup)) return true;
const popupPage = await this.page();
openerPage.emit(Events.Page.Popup, popupPage);
openerPage.emit(PageEmittedEvents.Popup, popupPage);
return true;
});
this._isClosedPromise = new Promise<boolean>(
Expand Down