From 31309b0e204f943e799308871056be00aeaf8ccd Mon Sep 17 00:00:00 2001 From: Jack Franklin Date: Fri, 10 Jul 2020 11:51:52 +0100 Subject: [PATCH] chore: use devtools-protocol package (#6172) * chore: Use devtools-protocol package Rather than maintain our own protocol we can instead use the devtools-protocol package and pin it to the version of Chromium that Puppeteer is shipping with. The only changes are naming changes between the bespoke protocol that Puppeteer created and the devtools-protocol one. --- .eslintignore | 2 - .travis.yml | 2 +- docs/api.md | 6 +- new-docs/puppeteer.cdpsession.md | 2 +- new-docs/puppeteer.cdpsession.send.md | 6 +- new-docs/puppeteer.page.deletecookie.md | 4 +- package.json | 10 +- ...nsure-correct-devtools-protocol-package.ts | 83 + src/common/Accessibility.ts | 2 +- src/common/Browser.ts | 8 +- src/common/Connection.ts | 25 +- src/common/Coverage.ts | 16 +- src/common/Dialog.ts | 2 +- src/common/EmulationManager.ts | 2 +- src/common/ExecutionContext.ts | 4 +- src/common/FileChooser.ts | 4 +- src/common/FrameManager.ts | 11 +- src/common/HTTPRequest.ts | 4 +- src/common/HTTPResponse.ts | 2 +- src/common/JSHandle.ts | 11 +- src/common/NetworkManager.ts | 20 +- src/common/Page.ts | 33 +- src/common/SecurityDetails.ts | 2 +- src/common/Target.ts | 2 +- src/common/WebWorker.ts | 4 +- src/common/helper.ts | 2 +- src/protocol.d.ts | 15503 ---------------- utils/apply_next_version.js | 4 + utils/doclint/check_public_api/JSBuilder.js | 16 +- utils/doclint/check_public_api/index.js | 41 +- utils/protocol-types-generator/index.js | 276 - 31 files changed, 227 insertions(+), 15882 deletions(-) create mode 100644 scripts/ensure-correct-devtools-protocol-package.ts delete mode 100644 src/protocol.d.ts delete mode 100644 utils/protocol-types-generator/index.js diff --git a/.eslintignore b/.eslintignore index 54c6043ef96..758aeb91ddb 100644 --- a/.eslintignore +++ b/.eslintignore @@ -6,8 +6,6 @@ node6/* node6-test/* experimental/ lib/ -src/externs.d.ts -src/protocol.d.ts /index.d.ts # We ignore this file because it uses ES imports which we don't yet use # in the Puppeteer src, so it trips up the ESLint-TypeScript parser. diff --git a/.travis.yml b/.travis.yml index ac86d00e06e..1d50febba49 100644 --- a/.travis.yml +++ b/.travis.yml @@ -63,9 +63,9 @@ jobs: env: - CHROMIUM=true script: - - npm run compare-protocol-d-ts - npm run lint - npm run ensure-new-docs-up-to-date + - npm run ensure-correct-devtools-protocol-revision # This bot runs separately as it changes package.json to test puppeteer-core # and we don't want that leaking into other bots and causing issues. diff --git a/docs/api.md b/docs/api.md index 83dcc3d929c..45a784e6308 100644 --- a/docs/api.md +++ b/docs/api.md @@ -331,7 +331,7 @@ * [target.worker()](#targetworker) - [class: CDPSession](#class-cdpsession) * [cdpSession.detach()](#cdpsessiondetach) - * [cdpSession.send(method[, params])](#cdpsessionsendmethod-params) + * [cdpSession.send(method[, ...paramArgs])](#cdpsessionsendmethod-paramargs) - [class: Coverage](#class-coverage) * [coverage.startCSSCoverage([options])](#coveragestartcsscoverageoptions) * [coverage.startJSCoverage([options])](#coveragestartjscoverageoptions) @@ -3946,9 +3946,9 @@ await client.send('Animation.setPlaybackRate', { Detaches the cdpSession from the target. Once detached, the cdpSession object won't emit any events and can't be used to send messages. -#### cdpSession.send(method[, params]) +#### cdpSession.send(method[, ...paramArgs]) - `method` <[string]> protocol method name -- `params` <[Object]> Optional method parameters +- `...paramArgs` <[Object]> Optional method parameters - returns: <[Promise]<[Object]>> ### class: Coverage diff --git a/new-docs/puppeteer.cdpsession.md b/new-docs/puppeteer.cdpsession.md index 038b0bda54f..db75960e402 100644 --- a/new-docs/puppeteer.cdpsession.md +++ b/new-docs/puppeteer.cdpsession.md @@ -41,5 +41,5 @@ await client.send('Animation.setPlaybackRate', { | Method | Modifiers | Description | | --- | --- | --- | | [detach()](./puppeteer.cdpsession.detach.md) | | Detaches the cdpSession from the target. Once detached, the cdpSession object won't emit any events and can't be used to send messages. | -| [send(method, params)](./puppeteer.cdpsession.send.md) | | | +| [send(method, paramArgs)](./puppeteer.cdpsession.send.md) | | | diff --git a/new-docs/puppeteer.cdpsession.send.md b/new-docs/puppeteer.cdpsession.send.md index 8fba8aa8ca6..dce83b49830 100644 --- a/new-docs/puppeteer.cdpsession.send.md +++ b/new-docs/puppeteer.cdpsession.send.md @@ -7,7 +7,7 @@ Signature: ```typescript -send(method: T, params?: Protocol.CommandParameters[T]): Promise; +send(method: T, ...paramArgs: ProtocolMapping.Commands[T]['paramsType']): Promise; ``` ## Parameters @@ -15,9 +15,9 @@ send(method: T, params?: Protocol.Co | Parameter | Type | Description | | --- | --- | --- | | method | T | | -| params | Protocol.CommandParameters\[T\] | | +| paramArgs | ProtocolMapping.Commands\[T\]\['paramsType'\] | | Returns: -Promise<Protocol.CommandReturnValues\[T\]> +Promise<ProtocolMapping.Commands\[T\]\['returnType'\]> diff --git a/new-docs/puppeteer.page.deletecookie.md b/new-docs/puppeteer.page.deletecookie.md index 58522b41a81..edb0e6c4fb4 100644 --- a/new-docs/puppeteer.page.deletecookie.md +++ b/new-docs/puppeteer.page.deletecookie.md @@ -7,14 +7,14 @@ Signature: ```typescript -deleteCookie(...cookies: Protocol.Network.deleteCookiesParameters[]): Promise; +deleteCookie(...cookies: Protocol.Network.DeleteCookiesRequest[]): Promise; ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| cookies | Protocol.Network.deleteCookiesParameters\[\] | | +| cookies | Protocol.Network.DeleteCookiesRequest\[\] | | Returns: diff --git a/package.json b/package.json index 8a9c2b33d93..f0101afc755 100644 --- a/package.json +++ b/package.json @@ -24,16 +24,15 @@ "doc": "node utils/doclint/cli.js", "clean-lib": "rm -rf lib", "tsc": "npm run clean-lib && tsc --version && npm run tsc-cjs && npm run tsc-esm", - "tsc-cjs": "tsc -p . && cp src/protocol.d.ts lib/cjs", - "tsc-esm": "tsc --build tsconfig-esm.json && cp src/protocol.d.ts lib/esm", + "tsc-cjs": "tsc -p .", + "tsc-esm": "tsc --build tsconfig-esm.json", "typecheck": "tsc -p . --noEmit", "apply-next-version": "node utils/apply_next_version.js", - "update-protocol-d-ts": "node utils/protocol-types-generator update", - "compare-protocol-d-ts": "node utils/protocol-types-generator compare", "test-install": "scripts/test-install.sh", "generate-docs": "npm run tsc && api-extractor run --local --verbose && api-documenter markdown -i temp -o new-docs", "ensure-new-docs-up-to-date": "npm run generate-docs && exit `git status --porcelain | head -255 | wc -l`", - "generate-dependency-graph": "echo 'Requires graphviz installed locally!' && depcruise --exclude 'api.ts' --do-not-follow '^node_modules' --output-type dot src/index.ts | dot -T png > dependency-chart.png" + "generate-dependency-graph": "echo 'Requires graphviz installed locally!' && depcruise --exclude 'api.ts' --do-not-follow '^node_modules' --output-type dot src/index.ts | dot -T png > dependency-chart.png", + "ensure-correct-devtools-protocol-revision": "ts-node scripts/ensure-correct-devtools-protocol-package" }, "files": [ "lib/", @@ -46,6 +45,7 @@ "license": "Apache-2.0", "dependencies": { "debug": "^4.1.0", + "devtools-protocol": "0.0.754670", "extract-zip": "^2.0.0", "https-proxy-agent": "^4.0.0", "mime": "^2.0.3", diff --git a/scripts/ensure-correct-devtools-protocol-package.ts b/scripts/ensure-correct-devtools-protocol-package.ts new file mode 100644 index 00000000000..f953844ce0b --- /dev/null +++ b/scripts/ensure-correct-devtools-protocol-package.ts @@ -0,0 +1,83 @@ +/** + * Copyright 2020 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This script ensures that the pinned version of devtools-protocol in + * package.json is the right version for the current revision of Chromium that + * Puppeteer ships with. + * + * The devtools-protocol package publisher runs every hour and checks if there + * are protocol changes. If there are, it will be versioned with the revision + * number of the commit that last changed the .pdl files. + * + * Chromium branches/releases are figured out at a later point in time, so it's + * not true that each Chromium revision will have an exact matching revision + * version of devtools-protocol. To ensure we're using a devtools-protocol that + * is aligned with our revision, we want to find the largest package number + * that's <= the revision that Puppeteer is using. + * + * This script uses npm's `view` function to list all versions in a range and + * find the one closest to our Chromium revision. + */ + +import { PUPPETEER_REVISIONS } from '../src/revisions'; +import { execSync } from 'child_process'; + +import packageJson from '../package.json'; + +const currentProtocolPackageInstalledVersion = + packageJson.dependencies['devtools-protocol']; + +/** + * Ensure that the devtools-protocol version is pinned. + */ +if (/^[^0-9]/.test(currentProtocolPackageInstalledVersion)) { + console.log( + `ERROR: devtools-protocol package is not pinned to a specific version.\n` + ); + process.exit(1); +} + +// find the right revision for our Chromium revision + +const command = `npm view "devtools-protocol@<=0.0.${PUPPETEER_REVISIONS.chromium}" version | tail -1`; + +console.log( + 'Checking npm for devtools-protocol revisions:\n', + `'${command}'`, + '\n' +); + +const output = execSync(command, { + encoding: 'utf8', +}); + +const bestRevisionFromNpm = output.split(' ')[1].replace(/'|\n/g, ''); + +if (currentProtocolPackageInstalledVersion !== bestRevisionFromNpm) { + console.log(`ERROR: bad devtools-protocol revision detected: + + Current Puppeteer Chromium revision: ${PUPPETEER_REVISIONS.chromium} + Current devtools-protocol version in package.json: ${currentProtocolPackageInstalledVersion} + Expected devtools-protocol version: ${bestRevisionFromNpm}`); + + process.exit(1); +} + +console.log( + `Correct devtools-protocol version found (${bestRevisionFromNpm}).` +); +process.exit(0); diff --git a/src/common/Accessibility.ts b/src/common/Accessibility.ts index d9a4b5fc258..cc41c32516d 100644 --- a/src/common/Accessibility.ts +++ b/src/common/Accessibility.ts @@ -16,7 +16,7 @@ import { CDPSession } from './Connection'; import { ElementHandle } from './JSHandle'; -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; /** * Represents a Node and the properties of it that are relevant to Accessibility. diff --git a/src/common/Browser.ts b/src/common/Browser.ts index 0ae871b0529..060e50f16f8 100644 --- a/src/common/Browser.ts +++ b/src/common/Browser.ts @@ -18,8 +18,8 @@ import { assert } from './assert'; import { helper } from './helper'; import { Target } from './Target'; import { EventEmitter } from './EventEmitter'; -import Protocol from '../protocol'; import { Connection, ConnectionEmittedEvents } from './Connection'; +import { Protocol } from 'devtools-protocol'; import { Page } from './Page'; import { ChildProcess } from 'child_process'; import { Viewport } from './PuppeteerViewport'; @@ -272,7 +272,7 @@ export class Browser extends EventEmitter { } private async _targetCreated( - event: Protocol.Target.targetCreatedPayload + event: Protocol.Target.TargetCreatedEvent ): Promise { const targetInfo = event.targetInfo; const { browserContextId } = targetInfo; @@ -314,7 +314,7 @@ export class Browser extends EventEmitter { } private _targetInfoChanged( - event: Protocol.Target.targetInfoChangedPayload + event: Protocol.Target.TargetInfoChangedEvent ): void { const target = this._targets.get(event.targetInfo.targetId); assert(target, 'target should exist before targetInfoChanged'); @@ -500,7 +500,7 @@ export class Browser extends EventEmitter { return !this._connection._closed; } - private _getVersion(): Promise { + private _getVersion(): Promise { return this._connection.send('Browser.getVersion'); } } diff --git a/src/common/Connection.ts b/src/common/Connection.ts index e59ec7bd856..7765fad2b95 100644 --- a/src/common/Connection.ts +++ b/src/common/Connection.ts @@ -18,7 +18,8 @@ import { debug } from './Debug'; const debugProtocolSend = debug('puppeteer:protocol:SEND ►'); const debugProtocolReceive = debug('puppeteer:protocol:RECV ◀'); -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; +import { ProtocolMapping } from 'devtools-protocol/types/protocol-mapping'; import { ConnectionTransport } from './ConnectionTransport'; import { EventEmitter } from './EventEmitter'; @@ -77,10 +78,17 @@ export class Connection extends EventEmitter { return this._url; } - send( + send( method: T, - params?: Protocol.CommandParameters[T] - ): Promise { + ...paramArgs: ProtocolMapping.Commands[T]['paramsType'] + ): Promise { + // There is only ever 1 param arg passed, but the Protocol defines it as an + // array of 0 or 1 items See this comment: + // https://github.com/ChromeDevTools/devtools-protocol/pull/113#issuecomment-412603285 + // which explains why the protocol defines the params this way for better + // type-inference. + // So now we check if there are any params or not and deal with them accordingly. + const params = paramArgs.length ? paramArgs[0] : undefined; const id = this._rawSend({ method, params }); return new Promise((resolve, reject) => { this._callbacks.set(id, { resolve, reject, error: new Error(), method }); @@ -232,10 +240,10 @@ export class CDPSession extends EventEmitter { this._sessionId = sessionId; } - send( + send( method: T, - params?: Protocol.CommandParameters[T] - ): Promise { + ...paramArgs: ProtocolMapping.Commands[T]['paramsType'] + ): Promise { if (!this._connection) return Promise.reject( new Error( @@ -243,6 +251,9 @@ export class CDPSession extends EventEmitter { ) ); + // See the comment in Connection#send explaining why we do this. + const params = paramArgs.length ? paramArgs[0] : undefined; + const id = this._connection._rawSend({ sessionId: this._sessionId, method, diff --git a/src/common/Coverage.ts b/src/common/Coverage.ts index 5b590a0a2be..47fa003e307 100644 --- a/src/common/Coverage.ts +++ b/src/common/Coverage.ts @@ -16,7 +16,7 @@ import { assert } from './assert'; import { helper, debugError, PuppeteerEventListener } from './helper'; -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; import { CDPSession } from './Connection'; import { EVALUATION_SCRIPT_URL } from './ExecutionContext'; @@ -223,7 +223,7 @@ class JSCoverage { } async _onScriptParsed( - event: Protocol.Debugger.scriptParsedPayload + event: Protocol.Debugger.ScriptParsedEvent ): Promise { // Ignore puppeteer-injected scripts if (event.url === EVALUATION_SCRIPT_URL) return; @@ -246,10 +246,10 @@ class JSCoverage { this._enabled = false; const result = await Promise.all< - Protocol.Profiler.takePreciseCoverageReturnValue, - Protocol.Profiler.stopPreciseCoverageReturnValue, - Protocol.Profiler.disableReturnValue, - Protocol.Debugger.disableReturnValue + Protocol.Profiler.TakePreciseCoverageResponse, + void, + void, + void >([ this._client.send('Profiler.takePreciseCoverage'), this._client.send('Profiler.stopPreciseCoverage'), @@ -322,9 +322,7 @@ class CSSCoverage { this._stylesheetSources.clear(); } - async _onStyleSheet( - event: Protocol.CSS.styleSheetAddedPayload - ): Promise { + async _onStyleSheet(event: Protocol.CSS.StyleSheetAddedEvent): Promise { const header = event.header; // Ignore anonymous scripts if (!header.sourceURL) return; diff --git a/src/common/Dialog.ts b/src/common/Dialog.ts index 87974ebdf9c..3223936d331 100644 --- a/src/common/Dialog.ts +++ b/src/common/Dialog.ts @@ -16,7 +16,7 @@ import { assert } from './assert'; import { CDPSession } from './Connection'; -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; /** * Dialog instances are dispatched by the {@link Page} via the `dialog` event. diff --git a/src/common/EmulationManager.ts b/src/common/EmulationManager.ts index 3231aa1bc9c..17d77f38273 100644 --- a/src/common/EmulationManager.ts +++ b/src/common/EmulationManager.ts @@ -15,7 +15,7 @@ */ import { CDPSession } from './Connection'; import { Viewport } from './PuppeteerViewport'; -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; export class EmulationManager { _client: CDPSession; diff --git a/src/common/ExecutionContext.ts b/src/common/ExecutionContext.ts index df7d4024680..b3473f0b541 100644 --- a/src/common/ExecutionContext.ts +++ b/src/common/ExecutionContext.ts @@ -20,7 +20,7 @@ import { createJSHandle, JSHandle, ElementHandle } from './JSHandle'; import { CDPSession } from './Connection'; import { DOMWorld } from './DOMWorld'; import { Frame } from './FrameManager'; -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; import { EvaluateHandleFn, SerializableOrJSHandle } from './EvalTypes'; export const EVALUATION_SCRIPT_URL = '__puppeteer_evaluation_script__'; @@ -301,7 +301,7 @@ export class ExecutionContext { return { value: arg }; } - function rewriteError(error: Error): Protocol.Runtime.evaluateReturnValue { + function rewriteError(error: Error): Protocol.Runtime.EvaluateResponse { if (error.message.includes('Object reference chain is too long')) return { result: { type: 'undefined' } }; if (error.message.includes("Object couldn't be returned by value")) diff --git a/src/common/FileChooser.ts b/src/common/FileChooser.ts index 22eed356569..cbd086d74db 100644 --- a/src/common/FileChooser.ts +++ b/src/common/FileChooser.ts @@ -15,7 +15,7 @@ */ import { ElementHandle } from './JSHandle'; -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; import { assert } from './assert'; /** @@ -45,7 +45,7 @@ export class FileChooser { */ constructor( element: ElementHandle, - event: Protocol.Page.fileChooserOpenedPayload + event: Protocol.Page.FileChooserOpenedEvent ) { this._element = element; this._multiple = event.mode !== 'selectSingle'; diff --git a/src/common/FrameManager.ts b/src/common/FrameManager.ts index f4ec1ab01e9..29a86fdd8cc 100644 --- a/src/common/FrameManager.ts +++ b/src/common/FrameManager.ts @@ -27,7 +27,7 @@ import { JSHandle, ElementHandle } from './JSHandle'; import { MouseButton } from './Input'; import { Page } from './Page'; import { HTTPResponse } from './HTTPResponse'; -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; import { SerializableOrJSHandle, EvaluateHandleFn, @@ -108,10 +108,7 @@ export class FrameManager extends EventEmitter { } async initialize(): Promise { - const result = await Promise.all< - Protocol.Page.enableReturnValue, - Protocol.Page.getFrameTreeReturnValue - >([ + const result = await Promise.all<{}, Protocol.Page.GetFrameTreeResponse>([ this._client.send('Page.enable'), this._client.send('Page.getFrameTree'), ]); @@ -121,7 +118,7 @@ export class FrameManager extends EventEmitter { await Promise.all([ this._client.send('Page.setLifecycleEventsEnabled', { enabled: true }), this._client - .send('Runtime.enable', {}) + .send('Runtime.enable') .then(() => this._ensureIsolatedWorld(UTILITY_WORLD_NAME)), this._networkManager.initialize(), ]); @@ -210,7 +207,7 @@ export class FrameManager extends EventEmitter { return watcher.navigationResponse(); } - _onLifecycleEvent(event: Protocol.Page.lifecycleEventPayload): void { + _onLifecycleEvent(event: Protocol.Page.LifecycleEventEvent): void { const frame = this._frames.get(event.frameId); if (!frame) return; frame._onLifecycleEvent(event.loaderId, event.name); diff --git a/src/common/HTTPRequest.ts b/src/common/HTTPRequest.ts index d2a4548b130..a27b94a8487 100644 --- a/src/common/HTTPRequest.ts +++ b/src/common/HTTPRequest.ts @@ -18,7 +18,7 @@ import { Frame } from './FrameManager'; import { HTTPResponse } from './HTTPResponse'; import { assert } from './assert'; import { helper, debugError } from './helper'; -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; /** * @public @@ -123,7 +123,7 @@ export class HTTPRequest { frame: Frame, interceptionId: string, allowInterception: boolean, - event: Protocol.Network.requestWillBeSentPayload, + event: Protocol.Network.RequestWillBeSentEvent, redirectChain: HTTPRequest[] ) { this._client = client; diff --git a/src/common/HTTPResponse.ts b/src/common/HTTPResponse.ts index c40ecb88fea..575b684e31e 100644 --- a/src/common/HTTPResponse.ts +++ b/src/common/HTTPResponse.ts @@ -17,7 +17,7 @@ import { CDPSession } from './Connection'; import { Frame } from './FrameManager'; import { HTTPRequest } from './HTTPRequest'; import { SecurityDetails } from './SecurityDetails'; -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; /** * @public diff --git a/src/common/JSHandle.ts b/src/common/JSHandle.ts index 082d7d761b1..f5a0c18b283 100644 --- a/src/common/JSHandle.ts +++ b/src/common/JSHandle.ts @@ -22,7 +22,7 @@ import { CDPSession } from './Connection'; import { KeyInput } from './USKeyboardLayout'; import { FrameManager, Frame } from './FrameManager'; import { getQueryHandlerAndSelector } from './QueryHandler'; -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; import { EvaluateFn, SerializableOrJSHandle, @@ -445,11 +445,12 @@ export class ElementHandle< }; } - private _getBoxModel(): Promise { + private _getBoxModel(): Promise { + const params: Protocol.DOM.GetBoxModelRequest = { + objectId: this._remoteObject.objectId, + }; return this._client - .send('DOM.getBoxModel', { - objectId: this._remoteObject.objectId, - }) + .send('DOM.getBoxModel', params) .catch((error) => debugError(error)); } diff --git a/src/common/NetworkManager.ts b/src/common/NetworkManager.ts index 68eda72bf34..4eaf1e059fc 100644 --- a/src/common/NetworkManager.ts +++ b/src/common/NetworkManager.ts @@ -16,7 +16,7 @@ import { EventEmitter } from './EventEmitter'; import { assert } from './assert'; import { helper, debugError } from './helper'; -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; import { CDPSession } from './Connection'; import { FrameManager } from './FrameManager'; import { HTTPRequest } from './HTTPRequest'; @@ -53,7 +53,7 @@ export class NetworkManager extends EventEmitter { _requestIdToRequest = new Map(); _requestIdToRequestWillBeSentEvent = new Map< string, - Protocol.Network.requestWillBeSentPayload + Protocol.Network.RequestWillBeSentEvent >(); _extraHTTPHeaders: Record = {}; _offline = false; @@ -182,7 +182,7 @@ export class NetworkManager extends EventEmitter { }); } - _onRequestWillBeSent(event: Protocol.Network.requestWillBeSentPayload): void { + _onRequestWillBeSent(event: Protocol.Network.RequestWillBeSentEvent): void { // Request interception doesn't happen for data URLs with Network Service. if ( this._protocolRequestInterceptionEnabled && @@ -201,7 +201,7 @@ export class NetworkManager extends EventEmitter { this._onRequest(event, null); } - _onAuthRequired(event: Protocol.Fetch.authRequiredPayload): void { + _onAuthRequired(event: Protocol.Fetch.AuthRequiredEvent): void { /* TODO(jacktfranklin): This is defined in protocol.d.ts but not * in an easily referrable way - we should look at exposing it. */ @@ -225,7 +225,7 @@ export class NetworkManager extends EventEmitter { .catch(debugError); } - _onRequestPaused(event: Protocol.Fetch.requestPausedPayload): void { + _onRequestPaused(event: Protocol.Fetch.RequestPausedEvent): void { if ( !this._userRequestInterceptionEnabled && this._protocolRequestInterceptionEnabled @@ -251,7 +251,7 @@ export class NetworkManager extends EventEmitter { } _onRequest( - event: Protocol.Network.requestWillBeSentPayload, + event: Protocol.Network.RequestWillBeSentEvent, interceptionId?: string ): void { let redirectChain = []; @@ -280,7 +280,7 @@ export class NetworkManager extends EventEmitter { } _onRequestServedFromCache( - event: Protocol.Network.requestServedFromCachePayload + event: Protocol.Network.RequestServedFromCacheEvent ): void { const request = this._requestIdToRequest.get(event.requestId); if (request) request._fromMemoryCache = true; @@ -302,7 +302,7 @@ export class NetworkManager extends EventEmitter { this.emit(NetworkManagerEmittedEvents.RequestFinished, request); } - _onResponseReceived(event: Protocol.Network.responseReceivedPayload): void { + _onResponseReceived(event: Protocol.Network.ResponseReceivedEvent): void { const request = this._requestIdToRequest.get(event.requestId); // FileUpload sends a response without a matching request. if (!request) return; @@ -311,7 +311,7 @@ export class NetworkManager extends EventEmitter { this.emit(NetworkManagerEmittedEvents.Response, response); } - _onLoadingFinished(event: Protocol.Network.loadingFinishedPayload): void { + _onLoadingFinished(event: Protocol.Network.LoadingFinishedEvent): void { const request = this._requestIdToRequest.get(event.requestId); // For certain requestIds we never receive requestWillBeSent event. // @see https://crbug.com/750469 @@ -325,7 +325,7 @@ export class NetworkManager extends EventEmitter { this.emit(NetworkManagerEmittedEvents.RequestFinished, request); } - _onLoadingFailed(event: Protocol.Network.loadingFailedPayload): void { + _onLoadingFailed(event: Protocol.Network.LoadingFailedEvent): void { const request = this._requestIdToRequest.get(event.requestId); // For certain requestIds we never receive requestWillBeSent event. // @see https://crbug.com/750469 diff --git a/src/common/Page.ts b/src/common/Page.ts index 48c2e22fd62..257784a09bf 100644 --- a/src/common/Page.ts +++ b/src/common/Page.ts @@ -40,7 +40,7 @@ import { TimeoutSettings } from './TimeoutSettings'; import { FileChooser } from './FileChooser'; import { ConsoleMessage, ConsoleMessageType } from './ConsoleMessage'; import { PuppeteerLifeCycleEvent } from './LifecycleWatcher'; -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; import { SerializableOrJSHandle, EvaluateHandleFn, @@ -527,13 +527,13 @@ export class Page extends EventEmitter { waitForDebuggerOnStart: false, flatten: true, }), - this._client.send('Performance.enable', {}), - this._client.send('Log.enable', {}), + this._client.send('Performance.enable'), + this._client.send('Log.enable'), ]); } private async _onFileChooser( - event: Protocol.Page.fileChooserOpenedPayload + event: Protocol.Page.FileChooserOpenedEvent ): Promise { if (!this._fileChooserInterceptors.size) return; const frame = this._frameManager.frame(event.frameId); @@ -638,7 +638,7 @@ export class Page extends EventEmitter { this.emit('error', new Error('Page crashed!')); } - private _onLogEntryAdded(event: Protocol.Log.entryAddedPayload): void { + private _onLogEntryAdded(event: Protocol.Log.EntryAddedEvent): void { const { level, text, args, source, url, lineNumber } = event.entry; if (args) args.map((arg) => helper.releaseObject(this._client, arg)); if (source !== 'worker') @@ -1012,7 +1012,7 @@ export class Page extends EventEmitter { } async deleteCookie( - ...cookies: Protocol.Network.deleteCookiesParameters[] + ...cookies: Protocol.Network.DeleteCookiesRequest[] ): Promise { const pageURL = this.url(); for (const cookie of cookies) { @@ -1121,7 +1121,7 @@ export class Page extends EventEmitter { return this._buildMetricsObject(response.metrics); } - private _emitMetrics(event: Protocol.Performance.metricsPayload): void { + private _emitMetrics(event: Protocol.Performance.MetricsEvent): void { this.emit(PageEmittedEvents.Metrics, { title: event.title, metrics: this._buildMetricsObject(event.metrics), @@ -1148,7 +1148,7 @@ export class Page extends EventEmitter { } private async _onConsoleAPI( - event: Protocol.Runtime.consoleAPICalledPayload + event: Protocol.Runtime.ConsoleAPICalledEvent ): Promise { if (event.executionContextId === 0) { // DevTools protocol stores the last 1000 console messages. These @@ -1174,7 +1174,7 @@ export class Page extends EventEmitter { } private async _onBindingCalled( - event: Protocol.Runtime.bindingCalledPayload + event: Protocol.Runtime.BindingCalledEvent ): Promise { const { name, seq, args } = JSON.parse(event.payload); let expression = null; @@ -1264,7 +1264,7 @@ export class Page extends EventEmitter { this.emit(PageEmittedEvents.Console, message); } - private _onDialog(event: Protocol.Page.javascriptDialogOpeningPayload): void { + private _onDialog(event: Protocol.Page.JavascriptDialogOpeningEvent): void { let dialogType = null; const validDialogTypes = new Set([ 'alert', @@ -1307,10 +1307,10 @@ export class Page extends EventEmitter { } async reload(options?: WaitForOptions): Promise { - const result = await Promise.all< - HTTPResponse, - Protocol.Page.reloadReturnValue - >([this.waitForNavigation(options), this._client.send('Page.reload')]); + const result = await Promise.all([ + this.waitForNavigation(options), + this._client.send('Page.reload'), + ]); return result[0]; } @@ -1386,10 +1386,7 @@ export class Page extends EventEmitter { const history = await this._client.send('Page.getNavigationHistory'); const entry = history.entries[history.currentIndex + delta]; if (!entry) return null; - const result = await Promise.all< - HTTPResponse, - Protocol.Page.navigateToHistoryEntryReturnValue - >([ + const result = await Promise.all([ this.waitForNavigation(options), this._client.send('Page.navigateToHistoryEntry', { entryId: entry.id }), ]); diff --git a/src/common/SecurityDetails.ts b/src/common/SecurityDetails.ts index 9b13db5caeb..aceba1a3d08 100644 --- a/src/common/SecurityDetails.ts +++ b/src/common/SecurityDetails.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; /** * The SecurityDetails class represents the security details of a diff --git a/src/common/Target.ts b/src/common/Target.ts index 7d6988c05e4..b5b9ad11bf6 100644 --- a/src/common/Target.ts +++ b/src/common/Target.ts @@ -19,7 +19,7 @@ import { WebWorker } from './WebWorker'; import { CDPSession } from './Connection'; import { Browser, BrowserContext } from './Browser'; import { Viewport } from './PuppeteerViewport'; -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; /** * @public diff --git a/src/common/WebWorker.ts b/src/common/WebWorker.ts index c74e14899f3..54d416ac542 100644 --- a/src/common/WebWorker.ts +++ b/src/common/WebWorker.ts @@ -18,7 +18,7 @@ import { debugError } from './helper'; import { ExecutionContext } from './ExecutionContext'; import { JSHandle } from './JSHandle'; import { CDPSession } from './Connection'; -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; import { EvaluateHandleFn, SerializableOrJSHandle } from './EvalTypes'; /** @@ -96,7 +96,7 @@ export class WebWorker extends EventEmitter { }); // This might fail if the target is closed before we recieve all execution contexts. - this._client.send('Runtime.enable', {}).catch(debugError); + this._client.send('Runtime.enable').catch(debugError); this._client.on('Runtime.consoleAPICalled', (event) => consoleAPICalled( event.type, diff --git a/src/common/helper.ts b/src/common/helper.ts index fddcc8ea374..b100ddf6604 100644 --- a/src/common/helper.ts +++ b/src/common/helper.ts @@ -18,7 +18,7 @@ import { debug } from './Debug'; import * as fs from 'fs'; import { CDPSession } from './Connection'; import { promisify } from 'util'; -import Protocol from '../protocol'; +import { Protocol } from 'devtools-protocol'; import { CommonEventEmitter } from './EventEmitter'; import { assert } from './assert'; diff --git a/src/protocol.d.ts b/src/protocol.d.ts deleted file mode 100644 index e14a1d62992..00000000000 --- a/src/protocol.d.ts +++ /dev/null @@ -1,15503 +0,0 @@ -// This is generated from /utils/protocol-types-generator/index.js - type binary = string; - -declare module Protocol { - export module Accessibility { - /** - * Unique accessibility node identifier. - */ - export type AXNodeId = string; - /** - * Enum of possible property types. - */ - export type AXValueType = "boolean"|"tristate"|"booleanOrUndefined"|"idref"|"idrefList"|"integer"|"node"|"nodeList"|"number"|"string"|"computedString"|"token"|"tokenList"|"domRelation"|"role"|"internalRole"|"valueUndefined"; - /** - * Enum of possible property sources. - */ - export type AXValueSourceType = "attribute"|"implicit"|"style"|"contents"|"placeholder"|"relatedElement"; - /** - * Enum of possible native property sources (as a subtype of a particular AXValueSourceType). - */ - export type AXValueNativeSourceType = "figcaption"|"label"|"labelfor"|"labelwrapped"|"legend"|"tablecaption"|"title"|"other"; - /** - * A single source for a computed AX property. - */ - export interface AXValueSource { - /** - * What type of source this is. - */ - type: AXValueSourceType; - /** - * The value of this property source. - */ - value?: AXValue; - /** - * The name of the relevant attribute, if any. - */ - attribute?: string; - /** - * The value of the relevant attribute, if any. - */ - attributeValue?: AXValue; - /** - * Whether this source is superseded by a higher priority source. - */ - superseded?: boolean; - /** - * The native markup source for this value, e.g. a