mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
fix: type page event listeners correctly (#6891)
This PR fixes the fact that currently if you have: ```ts page.on('request', request => { }) ``` Then `request` will be typed as `any`. We can fix this by defining an interface of event name => callback argument type, and looking that up when you call `page.on`. Also includes a drive-by fix to ensure we convert response headers to strings, and updates the types accordingly.
This commit is contained in:
parent
e31e68dfa1
commit
866d34ee11
@ -40,7 +40,10 @@ export interface ContinueRequestOverrides {
|
|||||||
*/
|
*/
|
||||||
export interface ResponseForRequest {
|
export interface ResponseForRequest {
|
||||||
status: number;
|
status: number;
|
||||||
headers: Record<string, string>;
|
/**
|
||||||
|
* Optional response headers. All values are converted to strings.
|
||||||
|
*/
|
||||||
|
headers: Record<string, unknown>;
|
||||||
contentType: string;
|
contentType: string;
|
||||||
body: string | Buffer;
|
body: string | Buffer;
|
||||||
}
|
}
|
||||||
@ -346,7 +349,7 @@ export class HTTPRequest {
|
|||||||
*
|
*
|
||||||
* @param response - the response to fulfill the request with.
|
* @param response - the response to fulfill the request with.
|
||||||
*/
|
*/
|
||||||
async respond(response: ResponseForRequest): Promise<void> {
|
async respond(response: Partial<ResponseForRequest>): Promise<void> {
|
||||||
// Mocking responses for dataURL requests is not currently supported.
|
// Mocking responses for dataURL requests is not currently supported.
|
||||||
if (this._url.startsWith('data:')) return;
|
if (this._url.startsWith('data:')) return;
|
||||||
assert(this._allowInterception, 'Request Interception is not enabled!');
|
assert(this._allowInterception, 'Request Interception is not enabled!');
|
||||||
@ -361,7 +364,9 @@ export class HTTPRequest {
|
|||||||
const responseHeaders: Record<string, string> = {};
|
const responseHeaders: Record<string, string> = {};
|
||||||
if (response.headers) {
|
if (response.headers) {
|
||||||
for (const header of Object.keys(response.headers))
|
for (const header of Object.keys(response.headers))
|
||||||
responseHeaders[header.toLowerCase()] = response.headers[header];
|
responseHeaders[header.toLowerCase()] = String(
|
||||||
|
response.headers[header]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (response.contentType)
|
if (response.contentType)
|
||||||
responseHeaders['content-type'] = response.contentType;
|
responseHeaders['content-type'] = response.contentType;
|
||||||
|
@ -329,6 +329,35 @@ export const enum PageEmittedEvents {
|
|||||||
WorkerDestroyed = 'workerdestroyed',
|
WorkerDestroyed = 'workerdestroyed',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Denotes the objects received by callback functions for page events.
|
||||||
|
*
|
||||||
|
* See {@link PageEmittedEvents} for more detail on the events and when they are
|
||||||
|
* emitted.
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export interface PageEventObject {
|
||||||
|
close: never;
|
||||||
|
console: ConsoleMessage;
|
||||||
|
dialog: Dialog;
|
||||||
|
domcontentloaded: never;
|
||||||
|
error: Error;
|
||||||
|
frameattached: Frame;
|
||||||
|
framedetached: Frame;
|
||||||
|
framenavigated: Frame;
|
||||||
|
load: never;
|
||||||
|
metrics: { title: string; metrics: Metrics };
|
||||||
|
pageerror: Error;
|
||||||
|
popup: Page;
|
||||||
|
request: HTTPRequest;
|
||||||
|
response: HTTPResponse;
|
||||||
|
requestfailed: HTTPRequest;
|
||||||
|
requestfinished: HTTPRequest;
|
||||||
|
requestservedfromcache: HTTPRequest;
|
||||||
|
workercreated: WebWorker;
|
||||||
|
workerdestroyed: WebWorker;
|
||||||
|
}
|
||||||
|
|
||||||
class ScreenshotTaskQueue {
|
class ScreenshotTaskQueue {
|
||||||
_chain: Promise<Buffer | string | void>;
|
_chain: Promise<Buffer | string | void>;
|
||||||
|
|
||||||
@ -559,6 +588,27 @@ export class Page extends EventEmitter {
|
|||||||
return this._javascriptEnabled;
|
return this._javascriptEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen to page events.
|
||||||
|
*/
|
||||||
|
public on<K extends keyof PageEventObject>(
|
||||||
|
eventName: K,
|
||||||
|
handler: (event: PageEventObject[K]) => void
|
||||||
|
): EventEmitter {
|
||||||
|
// Note: this method only exists to define the types; we delegate the impl
|
||||||
|
// to EventEmitter.
|
||||||
|
return super.on(eventName, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public once<K extends keyof PageEventObject>(
|
||||||
|
eventName: K,
|
||||||
|
handler: (event: PageEventObject[K]) => void
|
||||||
|
): EventEmitter {
|
||||||
|
// Note: this method only exists to define the types; we delegate the impl
|
||||||
|
// to EventEmitter.
|
||||||
|
return super.once(eventName, handler);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param options - Optional waiting parameters
|
* @param options - Optional waiting parameters
|
||||||
* @returns Resolves after a page requests a file picker.
|
* @returns Resolves after a page requests a file picker.
|
||||||
|
@ -5,6 +5,9 @@ async function run() {
|
|||||||
const devices = puppeteer.devices;
|
const devices = puppeteer.devices;
|
||||||
console.log(devices);
|
console.log(devices);
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
|
page.on('request', (request) => {
|
||||||
|
const resourceType = request.resourceType();
|
||||||
|
});
|
||||||
const div = (await page.$('div')) as puppeteer.ElementHandle<
|
const div = (await page.$('div')) as puppeteer.ElementHandle<
|
||||||
HTMLAnchorElement
|
HTMLAnchorElement
|
||||||
>;
|
>;
|
||||||
|
@ -864,6 +864,27 @@ function compareDocumentations(actual, expected) {
|
|||||||
expectedName: 'Array<Permission>',
|
expectedName: 'Array<Permission>',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'Method HTTPRequest.respond() response.body',
|
||||||
|
{
|
||||||
|
actualName: 'string|Buffer',
|
||||||
|
expectedName: 'Object',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'Method HTTPRequest.respond() response.contentType',
|
||||||
|
{
|
||||||
|
actualName: 'string',
|
||||||
|
expectedName: 'Object',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'Method HTTPRequest.respond() response.status',
|
||||||
|
{
|
||||||
|
actualName: 'number',
|
||||||
|
expectedName: 'Object',
|
||||||
|
},
|
||||||
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const expectedForSource = expectedNamingMismatches.get(source);
|
const expectedForSource = expectedNamingMismatches.get(source);
|
||||||
|
Loading…
Reference in New Issue
Block a user