From 4638019902f3f556cdc9baa3d49172cb94d818f7 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Sat, 21 Dec 2019 09:03:52 -0800 Subject: [PATCH] feat(api): use good old inheritance instead of feature detection (#329) --- docs/api.md | 230 ++++++++++++++--------------- src/chromium/crApi.ts | 4 +- src/chromium/crFrameManager.ts | 42 ++++-- src/chromium/events.ts | 2 +- src/chromium/features/crPdf.ts | 2 +- src/chromium/features/crWorkers.ts | 11 +- src/page.ts | 18 +-- test/chromium/pdf.spec.js | 2 +- test/chromium/workers.spec.js | 12 +- 9 files changed, 166 insertions(+), 157 deletions(-) diff --git a/docs/api.md b/docs/api.md index 7beac87720..835ae62fa4 100644 --- a/docs/api.md +++ b/docs/api.md @@ -142,14 +142,12 @@ * [page.$eval(selector, pageFunction[, ...args])](#pageevalselector-pagefunction-args-1) * [page.$wait(selector, pageFunction[, options[, ...args]])](#pagewaitselector-pagefunction-options-args) * [page.$x(expression)](#pagexexpression) - * [page.accessibility](#pageaccessibility) * [page.addScriptTag(options)](#pageaddscripttagoptions) * [page.addStyleTag(options)](#pageaddstyletagoptions) * [page.browserContext()](#pagebrowsercontext) * [page.click(selector[, options])](#pageclickselector-options) * [page.close([options])](#pagecloseoptions) * [page.content()](#pagecontent) - * [page.coverage](#pagecoverage) * [page.dblclick(selector[, options])](#pagedblclickselector-options) * [page.emulateMedia(options)](#pageemulatemediaoptions) * [page.evaluate(pageFunction[, ...args])](#pageevaluatepagefunction-args) @@ -163,12 +161,10 @@ * [page.goForward([options])](#pagegoforwardoptions) * [page.goto(url[, options])](#pagegotourl-options) * [page.hover(selector[, options])](#pagehoverselector-options) - * [page.interception](#pageinterception) * [page.isClosed()](#pageisclosed) * [page.keyboard](#pagekeyboard) * [page.mainFrame()](#pagemainframe) * [page.mouse](#pagemouse) - * [page.pdf](#pagepdf) * [page.reload([options])](#pagereloadoptions) * [page.screenshot([options])](#pagescreenshotoptions) * [page.select(selector, value, options)](#pageselectselector-value-options) @@ -191,7 +187,6 @@ * [page.waitForRequest(urlOrPredicate[, options])](#pagewaitforrequesturlorpredicate-options) * [page.waitForResponse(urlOrPredicate[, options])](#pagewaitforresponseurlorpredicate-options) * [page.waitForSelector(selector[, options])](#pagewaitforselectorselector-options) - * [page.workers](#pageworkers) - [class: Request](#class-request) * [request.failure()](#requestfailure) * [request.frame()](#requestframe) @@ -244,8 +239,6 @@ * [chromiumInterception.setOfflineMode(enabled)](#chromiuminterceptionsetofflinemodeenabled) - [class: ChromiumOverrides](#class-chromiumoverrides) * [chromiumOverrides.setGeolocation(options)](#chromiumoverridessetgeolocationoptions) -- [class: ChromiumPDF](#class-chromiumpdf) - * [chromiumPDF.generate([options])](#chromiumpdfgenerateoptions) - [class: ChromiumPlaywright](#class-chromiumplaywright) * [chromiumPlaywright.connect(options)](#chromiumplaywrightconnectoptions) * [chromiumPlaywright.createBrowserFetcher([options])](#chromiumplaywrightcreatebrowserfetcheroptions) @@ -256,6 +249,14 @@ * [chromiumPlaywright.executablePath()](#chromiumplaywrightexecutablepath) * [chromiumPlaywright.launch([options])](#chromiumplaywrightlaunchoptions) * [chromiumPlaywright.launchServer([options])](#chromiumplaywrightlaunchserveroptions) +- [class: ChromiumPage](#class-chromiumpage) + * [event: 'workercreated'](#event-workercreated) + * [event: 'workerdestroyed'](#event-workerdestroyed) + * [chromiumPage.accessibility](#chromiumpageaccessibility) + * [chromiumPage.coverage](#chromiumpagecoverage) + * [chromiumPage.interception](#chromiumpageinterception) + * [chromiumPage.pdf([options])](#chromiumpagepdfoptions) + * [chromiumPage.workers()](#chromiumpageworkers) - [class: ChromiumSession](#class-chromiumsession) * [chromiumSession.detach()](#chromiumsessiondetach) * [chromiumSession.send(method[, params])](#chromiumsessionsendmethod-params) @@ -270,10 +271,6 @@ * [chromiumWorker.evaluate(pageFunction[, ...args])](#chromiumworkerevaluatepagefunction-args) * [chromiumWorker.evaluateHandle(pageFunction[, ...args])](#chromiumworkerevaluatehandlepagefunction-args) * [chromiumWorker.url()](#chromiumworkerurl) -- [class: ChromiumWorkers](#class-chromiumworkers) - * [event: 'workercreated'](#event-workercreated) - * [event: 'workerdestroyed'](#event-workerdestroyed) - * [chromiumWorkers.list()](#chromiumworkerslist) - [class: FirefoxBrowser](#class-firefoxbrowser) - [class: WebKitBrowser](#class-webkitbrowser) - [Working with selectors](#working-with-selectors) @@ -1897,9 +1894,6 @@ The method evaluates the XPath expression. Shortcut for [page.mainFrame().$x(expression)](#framexexpression) -#### page.accessibility -- returns: <[Accessibility]> - #### page.addScriptTag(options) - `options` <[Object]> - `url` <[string]> URL of a script to be added. @@ -1975,10 +1969,6 @@ By default, `page.close()` **does not** run beforeunload handlers. Gets the full HTML contents of the page, including the doctype. -#### page.coverage - -- returns: <[Coverage]> - #### page.dblclick(selector[, options]) - `selector` <[string]> A selector to search for element to double click. If there are multiple elements satisfying the selector, the first will be double clicked. - `options` <[Object]> @@ -2281,9 +2271,6 @@ If there's no element matching `selector`, the method throws an error. Shortcut for [page.mainFrame().hover(selector)](#framehoverselector). -#### page.interception -- returns: <[Interception]> - #### page.isClosed() - returns: <[boolean]> @@ -2303,9 +2290,6 @@ Page is guaranteed to have a main frame which persists during navigations. - returns: <[Mouse]> -#### page.pdf -- returns: <[PDF]> - #### page.reload([options]) - `options` <[Object]> Navigation parameters which might have the following properties: - `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods. @@ -2692,11 +2676,6 @@ const playwright = require('playwright'); ``` Shortcut for [page.mainFrame().waitForSelector(selector[, options])](#framewaitforselectorselector-options). -#### page.workers -- returns: <[Workers]> - -> **NOTE** This does not contain ServiceWorkers - ### class: Request Whenever the page sends a request, such as for a network resource, the following events are emitted by playwright's page: @@ -3202,76 +3181,6 @@ await browserContext.overrides.setGeolocation({latitude: 59.95, longitude: 30.31 > **NOTE** Consider using [browserContext.setPermissions](#browsercontextsetpermissions-permissions) to grant permissions for the page to read its geolocation. -### class: ChromiumPDF - -#### chromiumPDF.generate([options]) -- `options` <[Object]> Options object which might have the following properties: - - `path` <[string]> The file path to save the PDF to. If `path` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). If no path is provided, the PDF won't be saved to the disk. - - `scale` <[number]> Scale of the webpage rendering. Defaults to `1`. Scale amount must be between 0.1 and 2. - - `displayHeaderFooter` <[boolean]> Display header and footer. Defaults to `false`. - - `headerTemplate` <[string]> HTML template for the print header. Should be valid HTML markup with following classes used to inject printing values into them: - - `'date'` formatted print date - - `'title'` document title - - `'url'` document location - - `'pageNumber'` current page number - - `'totalPages'` total pages in the document - - `footerTemplate` <[string]> HTML template for the print footer. Should use the same format as the `headerTemplate`. - - `printBackground` <[boolean]> Print background graphics. Defaults to `false`. - - `landscape` <[boolean]> Paper orientation. Defaults to `false`. - - `pageRanges` <[string]> Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages. - - `format` <[string]> Paper format. If set, takes priority over `width` or `height` options. Defaults to 'Letter'. - - `width` <[string]|[number]> Paper width, accepts values labeled with units. - - `height` <[string]|[number]> Paper height, accepts values labeled with units. - - `margin` <[Object]> Paper margins, defaults to none. - - `top` <[string]|[number]> Top margin, accepts values labeled with units. - - `right` <[string]|[number]> Right margin, accepts values labeled with units. - - `bottom` <[string]|[number]> Bottom margin, accepts values labeled with units. - - `left` <[string]|[number]> Left margin, accepts values labeled with units. - - `preferCSSPageSize` <[boolean]> Give any CSS `@page` size declared in the page priority over what is declared in `width` and `height` or `format` options. Defaults to `false`, which will scale the content to fit the paper size. -- returns: <[Promise]<[Buffer]>> Promise which resolves with PDF buffer. - -> **NOTE** Generating a pdf is currently only supported in Chrome headless. - -`pdf.generate()` generates a pdf of the page with `print` css media. To generate a pdf with `screen` media, call [page.emulateMedia({ type: 'screen' })](#pageemulatemedia) before calling `pdf.generate()`: - -> **NOTE** By default, `pdf.generate()` generates a pdf with modified colors for printing. Use the [`-webkit-print-color-adjust`](https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-print-color-adjust) property to force rendering of exact colors. - -```js -// Generates a PDF with 'screen' media type. -await page.emulateMedia({type: 'screen'}); -await page.pdf.generate({path: 'page.pdf'}); -``` - -The `width`, `height`, and `margin` options accept values labeled with units. Unlabeled values are treated as pixels. - -A few examples: -- `page.pdf.generate({width: 100})` - prints with width set to 100 pixels -- `page.pdf.generate({width: '100px'})` - prints with width set to 100 pixels -- `page.pdf.generate({width: '10cm'})` - prints with width set to 10 centimeters. - -All possible units are: -- `px` - pixel -- `in` - inch -- `cm` - centimeter -- `mm` - millimeter - -The `format` options are: -- `Letter`: 8.5in x 11in -- `Legal`: 8.5in x 14in -- `Tabloid`: 11in x 17in -- `Ledger`: 17in x 11in -- `A0`: 33.1in x 46.8in -- `A1`: 23.4in x 33.1in -- `A2`: 16.54in x 23.4in -- `A3`: 11.7in x 16.54in -- `A4`: 8.27in x 11.7in -- `A5`: 5.83in x 8.27in -- `A6`: 4.13in x 5.83in - -> **NOTE** `headerTemplate` and `footerTemplate` markup have the following limitations: -> 1. Script tags inside templates are not evaluated. -> 2. Page styles are not visible inside templates. - ### class: ChromiumPlaywright Playwright module provides a method to launch a Chromium instance. @@ -3431,6 +3340,105 @@ const browser = await playwright.launch({ - `pipe` <[boolean]> Connects to the browser over a pipe instead of a WebSocket. Defaults to `false`. - returns: <[Promise]<[BrowserServer]>> Promise which resolves to browser server instance. +### class: ChromiumPage +* extends: [Page] + +The ChromiumPage class represents a Chromium-specific extension of the page. + +#### event: 'workercreated' +- <[Worker]> + +Emitted when a dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is spawned by the page. + +#### event: 'workerdestroyed' +- <[Worker]> + +Emitted when a dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is terminated. + +#### chromiumPage.accessibility +- returns: <[Accessibility]> + +#### chromiumPage.coverage + +- returns: <[Coverage]> + +#### chromiumPage.interception +- returns: <[Interception]> + +#### chromiumPage.pdf([options]) +- `options` <[Object]> Options object which might have the following properties: + - `path` <[string]> The file path to save the PDF to. If `path` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). If no path is provided, the PDF won't be saved to the disk. + - `scale` <[number]> Scale of the webpage rendering. Defaults to `1`. Scale amount must be between 0.1 and 2. + - `displayHeaderFooter` <[boolean]> Display header and footer. Defaults to `false`. + - `headerTemplate` <[string]> HTML template for the print header. Should be valid HTML markup with following classes used to inject printing values into them: + - `'date'` formatted print date + - `'title'` document title + - `'url'` document location + - `'pageNumber'` current page number + - `'totalPages'` total pages in the document + - `footerTemplate` <[string]> HTML template for the print footer. Should use the same format as the `headerTemplate`. + - `printBackground` <[boolean]> Print background graphics. Defaults to `false`. + - `landscape` <[boolean]> Paper orientation. Defaults to `false`. + - `pageRanges` <[string]> Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages. + - `format` <[string]> Paper format. If set, takes priority over `width` or `height` options. Defaults to 'Letter'. + - `width` <[string]|[number]> Paper width, accepts values labeled with units. + - `height` <[string]|[number]> Paper height, accepts values labeled with units. + - `margin` <[Object]> Paper margins, defaults to none. + - `top` <[string]|[number]> Top margin, accepts values labeled with units. + - `right` <[string]|[number]> Right margin, accepts values labeled with units. + - `bottom` <[string]|[number]> Bottom margin, accepts values labeled with units. + - `left` <[string]|[number]> Left margin, accepts values labeled with units. + - `preferCSSPageSize` <[boolean]> Give any CSS `@page` size declared in the page priority over what is declared in `width` and `height` or `format` options. Defaults to `false`, which will scale the content to fit the paper size. +- returns: <[Promise]<[Buffer]>> Promise which resolves with PDF buffer. + +> **NOTE** Generating a pdf is currently only supported in Chrome headless. + +`page.pdf()` generates a pdf of the page with `print` css media. To generate a pdf with `screen` media, call [page.emulateMedia({ type: 'screen' })](#pageemulatemedia) before calling `page.pdf()`: + +> **NOTE** By default, `page.pdf()` generates a pdf with modified colors for printing. Use the [`-webkit-print-color-adjust`](https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-print-color-adjust) property to force rendering of exact colors. + +```js +// Generates a PDF with 'screen' media type. +await page.emulateMedia({type: 'screen'}); +await page.pdf({path: 'page.pdf'}); +``` + +The `width`, `height`, and `margin` options accept values labeled with units. Unlabeled values are treated as pixels. + +A few examples: +- `page.pdf({width: 100})` - prints with width set to 100 pixels +- `page.pdf({width: '100px'})` - prints with width set to 100 pixels +- `page.pdf({width: '10cm'})` - prints with width set to 10 centimeters. + +All possible units are: +- `px` - pixel +- `in` - inch +- `cm` - centimeter +- `mm` - millimeter + +The `format` options are: +- `Letter`: 8.5in x 11in +- `Legal`: 8.5in x 14in +- `Tabloid`: 11in x 17in +- `Ledger`: 17in x 11in +- `A0`: 33.1in x 46.8in +- `A1`: 23.4in x 33.1in +- `A2`: 16.54in x 23.4in +- `A3`: 11.7in x 16.54in +- `A4`: 8.27in x 11.7in +- `A5`: 5.83in x 8.27in +- `A6`: 4.13in x 5.83in + +> **NOTE** `headerTemplate` and `footerTemplate` markup have the following limitations: +> 1. Script tags inside templates are not evaluated. +> 2. Page styles are not visible inside templates. + +#### chromiumPage.workers() +- returns: <[Array]<[Worker]>> +This method returns all of the dedicated [WebWorkers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) associated with the page. + +> **NOTE** This does not contain ServiceWorkers + ### class: ChromiumSession * extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter) @@ -3502,8 +3510,8 @@ The Worker class represents a [WebWorker](https://developer.mozilla.org/en-US/do The events `workercreated` and `workerdestroyed` are emitted on the page object to signal the worker lifecycle. ```js -page.workers.on('workercreated', worker => console.log('Worker created: ' + worker.url())); -page.workers.on('workerdestroyed', worker => console.log('Worker destroyed: ' + worker.url())); +page.on('workercreated', worker => console.log('Worker created: ' + worker.url())); +page.on('workerdestroyed', worker => console.log('Worker destroyed: ' + worker.url())); console.log('Current workers:'); for (const worker of page.workers()) @@ -3531,26 +3539,6 @@ If the function passed to the `worker.evaluateHandle` returns a [Promise], then #### chromiumWorker.url() - returns: <[string]> -### class: ChromiumWorkers - -The Workers class represents a [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) collection. - -#### event: 'workercreated' -- <[Worker]> - -Emitted when a dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is spawned by the page. - -#### event: 'workerdestroyed' -- <[Worker]> - -Emitted when a dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is terminated. - -#### chromiumWorkers.list() -- returns: <[Array]<[Worker]>> -This method returns all of the dedicated [WebWorkers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) associated with the page. - -> **NOTE** This does not contain ServiceWorkers - ### class: FirefoxBrowser * extends: [Browser] diff --git a/src/chromium/crApi.ts b/src/chromium/crApi.ts index be20c3aa4c..6b4d34a759 100644 --- a/src/chromium/crApi.ts +++ b/src/chromium/crApi.ts @@ -3,11 +3,11 @@ export { CRBrowser as ChromiumBrowser } from './crBrowser'; export { CRSession as ChromiumSession } from './crConnection'; +export { CRPage as ChromiumPage } from './crFrameManager'; export { CRPlaywright as ChromiumPlaywright } from './crPlaywright'; export { CRTarget as ChromiumTarget } from './crTarget'; export { CRAccessibility as ChromiumAccessibility } from './features/crAccessibility'; export { CRCoverage as ChromiumCoverage } from './features/crCoverage'; export { CRInterception as ChromiumInterception } from './features/crInterception'; export { CROverrides as ChromiumOverrides } from './features/crOverrides'; -export { CRPDF as ChromiumPDF } from './features/crPdf'; -export { CRWorker as ChromiumWorker, CRWorkers as ChromiumWorkers } from './features/crWorkers'; +export { CRWorker as ChromiumWorker } from './features/crWorkers'; diff --git a/src/chromium/crFrameManager.ts b/src/chromium/crFrameManager.ts index d281ac0f3c..84a75820b0 100644 --- a/src/chromium/crFrameManager.ts +++ b/src/chromium/crFrameManager.ts @@ -31,8 +31,8 @@ import { PageDelegate } from '../page'; import { RawMouseImpl, RawKeyboardImpl } from './crInput'; import { CRAccessibility } from './features/crAccessibility'; import { CRCoverage } from './features/crCoverage'; -import { CRPDF } from './features/crPdf'; -import { CRWorkers } from './features/crWorkers'; +import { CRPDF, PDFOptions } from './features/crPdf'; +import { CRWorkers, CRWorker } from './features/crWorkers'; import { CRInterception } from './features/crInterception'; import { CRBrowser } from './crBrowser'; import { BrowserContext } from '../browserContext'; @@ -44,7 +44,7 @@ const UTILITY_WORLD_NAME = '__playwright_utility_world__'; export class CRFrameManager implements PageDelegate { _client: CRSession; - private _page: Page; + private _page: CRPage; readonly _networkManager: CRNetworkManager; private _contextIdToContext = new Map(); private _isolatedWorlds = new Set(); @@ -58,13 +58,8 @@ export class CRFrameManager implements PageDelegate { this._browser = browser; this.rawKeyboard = new RawKeyboardImpl(client); this.rawMouse = new RawMouseImpl(client); - this._page = new Page(this, browserContext); - this._networkManager = new CRNetworkManager(client, this._page); - (this._page as any).accessibility = new CRAccessibility(client); - (this._page as any).coverage = new CRCoverage(client); - (this._page as any).pdf = new CRPDF(client); - (this._page as any).workers = new CRWorkers(client, this._page._addConsoleMessage.bind(this._page), error => this._page.emit(Events.Page.PageError, error)); - (this._page as any).interception = new CRInterception(this._networkManager); + this._page = new CRPage(client, this, browserContext); + this._networkManager = this._page._networkManager; this._eventListeners = [ helper.addEventListener(client, 'Inspector.targetCrashed', event => this._onTargetCrashed()), @@ -454,6 +449,33 @@ export class CRFrameManager implements PageDelegate { } } +export class CRPage extends Page { + readonly accessibility: CRAccessibility; + readonly coverage: CRCoverage; + readonly interception: CRInterception; + private _pdf: CRPDF; + private _workers: CRWorkers; + _networkManager: CRNetworkManager; + + constructor(client: CRSession, delegate: CRFrameManager, browserContext: BrowserContext) { + super(delegate, browserContext); + this.accessibility = new CRAccessibility(client); + this.coverage = new CRCoverage(client); + this._pdf = new CRPDF(client); + this._workers = new CRWorkers(client, this, this._addConsoleMessage.bind(this), error => this.emit(Events.Page.PageError, error)); + this._networkManager = new CRNetworkManager(client, this); + this.interception = new CRInterception(this._networkManager); + } + + async pdf(options?: PDFOptions): Promise { + return this._pdf.generate(options); + } + + workers(): CRWorker[] { + return this._workers.list(); + } +} + function toRemoteObject(handle: dom.ElementHandle): Protocol.Runtime.RemoteObject { return handle._remoteObject as Protocol.Runtime.RemoteObject; } diff --git a/src/chromium/events.ts b/src/chromium/events.ts index 108f7e4c7e..f3cf01b51a 100644 --- a/src/chromium/events.ts +++ b/src/chromium/events.ts @@ -22,7 +22,7 @@ export const Events = { TargetChanged: 'targetchanged', }, - CRWorkers: { + CRPage: { WorkerCreated: 'workercreated', WorkerDestroyed: 'workerdestroyed', } diff --git a/src/chromium/features/crPdf.ts b/src/chromium/features/crPdf.ts index 013e1a01ce..1bde2f69d9 100644 --- a/src/chromium/features/crPdf.ts +++ b/src/chromium/features/crPdf.ts @@ -19,7 +19,7 @@ import { assert, helper } from '../../helper'; import { CRSession } from '../crConnection'; import { readProtocolStream } from '../crProtocolHelper'; -type PDFOptions = { +export type PDFOptions = { scale?: number, displayHeaderFooter?: boolean, headerTemplate?: string, diff --git a/src/chromium/features/crWorkers.ts b/src/chromium/features/crWorkers.ts index 519578f24a..3802fbe582 100644 --- a/src/chromium/features/crWorkers.ts +++ b/src/chromium/features/crWorkers.ts @@ -25,29 +25,28 @@ import * as js from '../../javascript'; import * as console from '../../console'; import { CRExecutionContext } from '../crExecutionContext'; import { toConsoleMessageLocation, exceptionToError } from '../crProtocolHelper'; +import { CRPage } from '../crFrameManager'; type AddToConsoleCallback = (type: string, args: js.JSHandle[], location: console.ConsoleMessageLocation) => void; type HandleExceptionCallback = (error: Error) => void; -export class CRWorkers extends EventEmitter { +export class CRWorkers { private _workers = new Map(); - constructor(client: CRSession, addToConsole: AddToConsoleCallback, handleException: HandleExceptionCallback) { - super(); - + constructor(client: CRSession, page: CRPage, addToConsole: AddToConsoleCallback, handleException: HandleExceptionCallback) { client.on('Target.attachedToTarget', event => { if (event.targetInfo.type !== 'worker') return; const session = CRConnection.fromSession(client).session(event.sessionId); const worker = new CRWorker(session, event.targetInfo.url, addToConsole, handleException); this._workers.set(event.sessionId, worker); - this.emit(Events.CRWorkers.WorkerCreated, worker); + page.emit(Events.CRPage.WorkerCreated, worker); }); client.on('Target.detachedFromTarget', event => { const worker = this._workers.get(event.sessionId); if (!worker) return; - this.emit(Events.CRWorkers.WorkerDestroyed, worker); + page.emit(Events.CRPage.WorkerDestroyed, worker); this._workers.delete(event.sessionId); }); } diff --git a/src/page.ts b/src/page.ts index f37dbeb513..48dce67556 100644 --- a/src/page.ts +++ b/src/page.ts @@ -208,9 +208,9 @@ export class Page extends EventEmitter { await this._delegate.exposeBinding(name, helper.evaluationString(addPageBinding, name)); function addPageBinding(bindingName: string) { - const binding = window[bindingName]; - window[bindingName] = (...args) => { - const me = window[bindingName]; + const binding = (window as any)[bindingName]; + (window as any)[bindingName] = (...args: any[]) => { + const me = (window as any)[bindingName]; let callbacks = me['callbacks']; if (!callbacks) { callbacks = new Map(); @@ -250,20 +250,20 @@ export class Page extends EventEmitter { context.evaluate(expression).catch(debugError); function deliverResult(name: string, seq: number, result: any) { - window[name]['callbacks'].get(seq).resolve(result); - window[name]['callbacks'].delete(seq); + (window as any)[name]['callbacks'].get(seq).resolve(result); + (window as any)[name]['callbacks'].delete(seq); } function deliverError(name: string, seq: number, message: string, stack: string) { const error = new Error(message); error.stack = stack; - window[name]['callbacks'].get(seq).reject(error); - window[name]['callbacks'].delete(seq); + (window as any)[name]['callbacks'].get(seq).reject(error); + (window as any)[name]['callbacks'].delete(seq); } function deliverErrorValue(name: string, seq: number, value: any) { - window[name]['callbacks'].get(seq).reject(value); - window[name]['callbacks'].delete(seq); + (window as any)[name]['callbacks'].get(seq).reject(value); + (window as any)[name]['callbacks'].delete(seq); } } diff --git a/test/chromium/pdf.spec.js b/test/chromium/pdf.spec.js index a44e73730e..a6f3a0f071 100644 --- a/test/chromium/pdf.spec.js +++ b/test/chromium/pdf.spec.js @@ -26,7 +26,7 @@ module.exports.describe = function({testRunner, expect, headless, ASSETS_DIR}) { describe.skip(!headless)('Page.pdf', function() { it('should be able to save file', async({page, server}) => { const outputFile = path.join(ASSETS_DIR, 'output.pdf'); - await page.pdf.generate({path: outputFile}); + await page.pdf({path: outputFile}); expect(fs.readFileSync(outputFile).byteLength).toBeGreaterThan(0); fs.unlinkSync(outputFile); }); diff --git a/test/chromium/workers.spec.js b/test/chromium/workers.spec.js index 252a92c161..dff567923c 100644 --- a/test/chromium/workers.spec.js +++ b/test/chromium/workers.spec.js @@ -26,22 +26,22 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT}) { describe('Workers', function() { it('Page.workers', async function({page, server}) { await Promise.all([ - new Promise(x => page.workers.once('workercreated', x)), + new Promise(x => page.once('workercreated', x)), page.goto(server.PREFIX + '/worker/worker.html')]); - const worker = page.workers.list()[0]; + const worker = page.workers()[0]; expect(worker.url()).toContain('worker.js'); expect(await worker.evaluate(() => self['workerFunction']())).toBe('worker function result'); await page.goto(server.EMPTY_PAGE); - expect(page.workers.list().length).toBe(0); + expect(page.workers().length).toBe(0); }); it('should emit created and destroyed events', async function({page}) { - const workerCreatedPromise = new Promise(x => page.workers.once('workercreated', x)); + const workerCreatedPromise = new Promise(x => page.once('workercreated', x)); const workerObj = await page.evaluateHandle(() => new Worker('data:text/javascript,1')); const worker = await workerCreatedPromise; const workerThisObj = await worker.evaluateHandle(() => this); - const workerDestroyedPromise = new Promise(x => page.workers.once('workerdestroyed', x)); + const workerDestroyedPromise = new Promise(x => page.once('workerdestroyed', x)); await page.evaluate(workerObj => workerObj.terminate(), workerObj); expect(await workerDestroyedPromise).toBe(worker); const error = await workerThisObj.getProperty('self').catch(error => error); @@ -68,7 +68,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT}) { expect(await (await log.args()[3].getProperty('origin')).jsonValue()).toBe('null'); }); it('should evaluate', async function({page}) { - const workerCreatedPromise = new Promise(x => page.workers.once('workercreated', x)); + const workerCreatedPromise = new Promise(x => page.once('workercreated', x)); await page.evaluate(() => new Worker(`data:text/javascript,console.log(1)`)); const worker = await workerCreatedPromise; expect(await worker.evaluate('1+1')).toBe(2);