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 54c6043ef961a..758aeb91ddbf8 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 ac86d00e06ec7..1d50febba49e1 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 83dcc3d929ccf..45a784e6308c9 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 038b0bda54fd2..db75960e402b5 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 8fba8aa8ca60f..dce83b4983081 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 58522b41a81ce..edb0e6c4fb490 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 8a9c2b33d93d4..f0101afc7559f 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 0000000000000..f953844ce0b5d --- /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 d9a4b5fc25843..cc41c32516d7f 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 0ae871b0529e5..060e50f16f8d8 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 e59ec7bd85662..7765fad2b955e 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 5b590a0a2be8d..47fa003e3072f 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 87974ebdf9c35..3223936d3312e 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 3231aa1bc9c5e..17d77f382733d 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 df7d40246807d..b3473f0b5419d 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 22eed356569b8..cbd086d74db5b 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 f4ec1ab01e908..29a86fdd8cc26 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 d2a4548b1305c..a27b94a848745 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 c40ecb88feaac..575b684e31e9c 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 082d7d761b1e9..f5a0c18b2837a 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 68eda72bf3476..4eaf1e059fcc9 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 48c2e22fd62c9..257784a09bfcc 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 9b13db5caeba6..aceba1a3d0816 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 7d6988c05e4f3..b5b9ad11bf612 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 c74e14899f372..54d416ac542df 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 fddcc8ea374cd..b100ddf660432 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 e14a1d62992ba..0000000000000 --- 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