Skip to content

Commit

Permalink
chore(docs): migrate & document all Page events (#6154)
Browse files Browse the repository at this point in the history
* chore(docs): migrate & document all Page events

Rather than a generic `Events.ts` file we can instead document events as
an enum within each individual class. It's easier to document and work
with, and it's clearer where events originate from.
  • Loading branch information
jackfranklin committed Jul 6, 2020
1 parent e67a860 commit ba7624a
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 28 deletions.
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 @@ -197,13 +197,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 @@ -223,12 +344,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 @@ -243,7 +365,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 @@ -349,39 +471,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 @@ -393,7 +515,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 @@ -522,7 +644,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 @@ -1001,7 +1123,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 @@ -1023,7 +1145,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 @@ -1116,7 +1238,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 @@ -1140,7 +1262,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 @@ -1163,7 +1285,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

0 comments on commit ba7624a

Please sign in to comment.