From 68c4f79b021accd4465fbbb4db2981958c84c481 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Wed, 22 Jul 2020 19:38:19 -0700 Subject: [PATCH] feat(rpc): convert protocol to yaml (#3102) --- package-lock.json | 6 + package.json | 3 +- src/rpc/channels.ts | 16 +- src/rpc/client/validator.ts | 12 +- src/rpc/protocol.pdl | 1482 --------------------------- src/rpc/protocol.yml | 1926 +++++++++++++++++++++++++++++++++++ utils/generate_channels.js | 357 +++---- 7 files changed, 2078 insertions(+), 1724 deletions(-) delete mode 100644 src/rpc/protocol.pdl create mode 100644 src/rpc/protocol.yml diff --git a/package-lock.json b/package-lock.json index 43361550a6..4226b1e857 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11413,6 +11413,12 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "dev": true + }, "yargs": { "version": "13.2.4", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", diff --git a/package.json b/package.json index 1c1bcb6b8b..9164c3e75e 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,7 @@ "ts-loader": "^6.1.2", "typescript": "^3.8.3", "webpack": "^4.41.0", - "webpack-cli": "^3.3.9" + "webpack-cli": "^3.3.9", + "yaml": "^1.10.0" } } diff --git a/src/rpc/channels.ts b/src/rpc/channels.ts index a1cb3feef3..4a136428a3 100644 --- a/src/rpc/channels.ts +++ b/src/rpc/channels.ts @@ -352,6 +352,8 @@ export interface BrowserContextChannel extends Channel { on(event: 'close', callback: (params: BrowserContextCloseEvent) => void): this; on(event: 'page', callback: (params: BrowserContextPageEvent) => void): this; on(event: 'route', callback: (params: BrowserContextRouteEvent) => void): this; + on(event: 'crBackgroundPage', callback: (params: BrowserContextCrBackgroundPageEvent) => void): this; + on(event: 'crServiceWorker', callback: (params: BrowserContextCrServiceWorkerEvent) => void): this; addCookies(params: BrowserContextAddCookiesParams): Promise; addInitScript(params: BrowserContextAddInitScriptParams): Promise; clearCookies(params?: BrowserContextClearCookiesParams): Promise; @@ -368,8 +370,6 @@ export interface BrowserContextChannel extends Channel { setHTTPCredentials(params: BrowserContextSetHTTPCredentialsParams): Promise; setNetworkInterceptionEnabled(params: BrowserContextSetNetworkInterceptionEnabledParams): Promise; setOffline(params: BrowserContextSetOfflineParams): Promise; - on(event: 'crBackgroundPage', callback: (params: BrowserContextCrBackgroundPageEvent) => void): this; - on(event: 'crServiceWorker', callback: (params: BrowserContextCrServiceWorkerEvent) => void): this; crNewCDPSession(params: BrowserContextCrNewCDPSessionParams): Promise; } export type BrowserContextBindingCallEvent = { @@ -383,6 +383,12 @@ export type BrowserContextRouteEvent = { route: RouteChannel, request: RequestChannel, }; +export type BrowserContextCrBackgroundPageEvent = { + page: PageChannel, +}; +export type BrowserContextCrServiceWorkerEvent = { + worker: WorkerChannel, +}; export type BrowserContextAddCookiesParams = { cookies: { name: string, @@ -473,12 +479,6 @@ export type BrowserContextSetOfflineParams = { offline: boolean, }; export type BrowserContextSetOfflineResult = void; -export type BrowserContextCrBackgroundPageEvent = { - page: PageChannel, -}; -export type BrowserContextCrServiceWorkerEvent = { - worker: WorkerChannel, -}; export type BrowserContextCrNewCDPSessionParams = { page: PageChannel, }; diff --git a/src/rpc/client/validator.ts b/src/rpc/client/validator.ts index 1589184849..557fba3472 100644 --- a/src/rpc/client/validator.ts +++ b/src/rpc/client/validator.ts @@ -314,6 +314,12 @@ scheme.BrowserContextRouteEvent = tObject({ route: tChannel('Route'), request: tChannel('Request'), }); +scheme.BrowserContextCrBackgroundPageEvent = tObject({ + page: tChannel('Page'), +}); +scheme.BrowserContextCrServiceWorkerEvent = tObject({ + worker: tChannel('Worker'), +}); scheme.BrowserContextAddCookiesParams = tObject({ cookies: tArray(tObject({ name: tString, @@ -404,12 +410,6 @@ scheme.BrowserContextSetOfflineParams = tObject({ offline: tBoolean, }); scheme.BrowserContextSetOfflineResult = tUndefined; -scheme.BrowserContextCrBackgroundPageEvent = tObject({ - page: tChannel('Page'), -}); -scheme.BrowserContextCrServiceWorkerEvent = tObject({ - worker: tChannel('Worker'), -}); scheme.BrowserContextCrNewCDPSessionParams = tObject({ page: tChannel('Page'), }); diff --git a/src/rpc/protocol.pdl b/src/rpc/protocol.pdl deleted file mode 100644 index 281290d760..0000000000 --- a/src/rpc/protocol.pdl +++ /dev/null @@ -1,1482 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# -# 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. - -# Exactly one of the optional fields must be present. -type SerializedValue - n?: number - b?: boolean - s?: string - v?: enum - null - undefined - NaN - Infinity - -Infinity - -0 - # String representation of the Date. - d?: string - # Regular expression pattern and flags. - r?: object - p: string - f: string - a?: SerializedValue[] - # Object with keys and values. - o?: object[] - k: string - v: SerializedValue - # An index in the handles array from SerializedArgument. - h?: number - -# Represents a value with handle references. -type SerializedArgument - value: SerializedValue - handles: Channel[] - -type AXNode - role: string - name: string - valueString?: string - valueNumber?: number - description?: string - keyshortcuts?: string - roledescription?: string - valuetext?: string - disabled?: boolean - expanded?: boolean - focused?: boolean - modal?: boolean - multiline?: boolean - multiselectable?: boolean - readonly?: boolean - required?: boolean - selected?: boolean - checked?: enum - checked - unchecked - mixed - pressed?: enum - pressed - released - mixed - level?: number - valuemin?: number - valuemax?: number - autocomplete?: string - haspopup?: string - invalid?: string - orientation?: string - children?: AXNode[] - -type SerializedError - error?: object - message: string - name: string - stack?: string - value?: SerializedValue - -interface Playwright - initializer - chromium: BrowserType - firefox: BrowserType - webkit: BrowserType - electron?: Electron - deviceDescriptors: object[] - name: string - descriptor: object - userAgent: string - viewport: object - width: number - height: number - deviceScaleFactor: number - isMobile: boolean - hasTouch: boolean - selectors: Selectors - -interface Selectors - command register - parameters - name: string - source: string - contentScript?: boolean - - command createSelector - parameters - name: string - handle: ElementHandle - returns - value?: string - -interface BrowserType - initializer - executablePath: string - name: string - - command connect - parameters - wsEndpoint: string - slowMo?: number - timeout?: number - returns - browser: Browser - - command launch - parameters - executablePath?: string - args?: string[] - ignoreAllDefaultArgs?: boolean - ignoreDefaultArgs?: string[] - handleSIGINT?: boolean - handleSIGTERM?: boolean - handleSIGHUP?: boolean - timeout?: number - env?: object[] - name: string - value: string - headless?: boolean - devtools?: boolean - proxy?: object - server: string - bypass?: string - username?: string - password?: string - downloadsPath?: string - firefoxUserPrefs?: SerializedValue - slowMo?: number - returns - browser: Browser - - command launchServer - parameters - executablePath?: string - args?: string[] - ignoreAllDefaultArgs?: boolean - ignoreDefaultArgs?: string[] - handleSIGINT?: boolean - handleSIGTERM?: boolean - handleSIGHUP?: boolean - timeout?: number - env?: object[] - name: string - value: string - headless?: boolean - devtools?: boolean - proxy?: object - server: string - bypass?: string - username?: string - password?: string - downloadsPath?: string - firefoxUserPrefs?: SerializedValue - port?: number - returns - server: BrowserServer - - command launchPersistentContext - parameters - userDataDir: string - executablePath?: string - args?: string[] - ignoreAllDefaultArgs?: boolean - ignoreDefaultArgs?: string[] - handleSIGINT?: boolean - handleSIGTERM?: boolean - handleSIGHUP?: boolean - timeout?: number - env?: object[] - name: string - value: string - headless?: boolean - devtools?: boolean - proxy?: object - server: string - bypass?: string - username?: string - password?: string - downloadsPath?: string - slowMo?: number - noDefaultViewport?: boolean - viewport?: object - width: number - height: number - ignoreHTTPSErrors?: boolean - javaScriptEnabled?: boolean - bypassCSP?: boolean - userAgent?: string - locale?: string - timezoneId?: string - geolocation?: object - longitude: number - latitude: number - accuracy?: number - permissions?: string[] - extraHTTPHeaders?: object[] - name: string - value: string - offline?: boolean - httpCredentials?: object - username: string - password: string - deviceScaleFactor?: number - isMobile?: boolean - hasTouch?: boolean - colorScheme?: enum - dark - light - no-preference - acceptDownloads?: boolean - returns - context: BrowserContext - -interface BrowserServer - initializer - wsEndpoint: string - pid: number - - event close - - command close - - command kill - -interface Browser - event close - - command close - - command newContext - parameters - noDefaultViewport?: boolean - viewport?: object - width: number - height: number - ignoreHTTPSErrors?: boolean - javaScriptEnabled?: boolean - bypassCSP?: boolean - userAgent?: string - locale?: string - timezoneId?: string - geolocation?: object - longitude: number - latitude: number - accuracy?: number - permissions?: string[] - extraHTTPHeaders?: object[] - name: string - value: string - offline?: boolean - httpCredentials?: object - username: string - password: string - deviceScaleFactor?: number - isMobile?: boolean - hasTouch?: boolean - colorScheme?: enum - dark - light - no-preference - acceptDownloads?: boolean - returns - context: BrowserContext - - command crNewBrowserCDPSession - returns - session: CDPSession - - command crStartTracing - parameters - page?: Page - path?: string - screenshots?: boolean - categories?: string[] - - command crStopTracing - returns - binary: binary - -interface BrowserContext - event bindingCall - parameters - binding: BindingCall - - event close - - event page - parameters - page: Page - - event route - parameters - route: Route - request: Request - - command addCookies - parameters - cookies: object[] - name: string - value: string - url?: string - domain?: string - path?: string - expires?: number - httpOnly?: boolean - secure?: boolean - sameSite?: enum - Strict - Lax - None - - command addInitScript - parameters - source: string - - command clearCookies - - command clearPermissions - - command close - - command cookies - parameters - urls: string[] - returns - cookies: object[] - name: string - value: string - domain: string - path: string - expires: number - httpOnly: boolean - secure: boolean - sameSite: enum - Strict - Lax - None - - command exposeBinding - parameters - name: string - - command grantPermissions - parameters - permissions: string[] - origin?: string - - command newPage - returns - page: Page - - command setDefaultNavigationTimeoutNoReply - parameters - timeout: number - - command setDefaultTimeoutNoReply - parameters - timeout: number - - command setExtraHTTPHeaders - parameters - headers: object[] - name: string - value: string - - command setGeolocation - parameters - geolocation?: object - longitude: number - latitude: number - accuracy?: number - - command setHTTPCredentials - parameters - httpCredentials?: object - username: string - password: string - - command setNetworkInterceptionEnabled - parameters - enabled: boolean - - command setOffline - parameters - offline: boolean - - event crBackgroundPage - parameters - page: Page - - event crServiceWorker - parameters - worker: Worker - - command crNewCDPSession - parameters - page: Page - returns - session: CDPSession - -interface Page - initializer - mainFrame: Frame - viewportSize?: object - width: number - height: number - isClosed: boolean - - event bindingCall - parameters - binding: BindingCall - - event close - - event console - parameters - message: ConsoleMessage - - event crash - - event dialog - parameters - dialog: Dialog - - event download - parameters - download: Download - - event domcontentloaded - - event fileChooser - parameters - element: ElementHandle - isMultiple: boolean - - event frameAttached - parameters - frame: Frame - - event frameDetached - parameters - frame: Frame - - event load - - event pageError - parameters - error: SerializedError - - event popup - parameters - page: Page - - event request - parameters - request: Request - - event requestFailed - parameters - request: Request - failureText?: string - - event requestFinished - parameters - request: Request - - event response - parameters - response: Response - - event route - parameters - route: Route - request: Request - - event worker - parameters - worker: Worker - - command setDefaultNavigationTimeoutNoReply - parameters - timeout: number - - command setDefaultTimeoutNoReply - parameters - timeout: number - - command setFileChooserInterceptedNoReply - parameters - intercepted: boolean - - command addInitScript - parameters - source: string - - command close - parameters - runBeforeUnload?: boolean - - command emulateMedia - parameters - media?: enum - screen - print - # Reset emulated value to the system default. - null - colorScheme?: enum - dark - light - no-preference - # Reset emulated value to the system default. - null - - command exposeBinding - parameters - name: string - - command goBack - parameters - timeout?: number - waitUntil?: enum - load - domcontentloaded - networkidle - returns - response?: Response - - command goForward - parameters - timeout?: number - waitUntil?: enum - load - domcontentloaded - networkidle - returns - response?: Response - - command opener - returns - page?: Page - - command reload - parameters - timeout?: number - waitUntil?: enum - load - domcontentloaded - networkidle - returns - response?: Response - - command screenshot - parameters - timeout?: number - type?: enum - png - jpeg - path?: string - quality?: number - omitBackground?: boolean - fullPage?: boolean - clip?: object - width: number - height: number - x: number - y: number - returns - binary: binary - - command setExtraHTTPHeaders - parameters - headers: object[] - name: string - value: string - - command setNetworkInterceptionEnabled - parameters - enabled: boolean - - command setViewportSize - parameters - viewportSize: object - width: number - height: number - - command keyboardDown - parameters - key: string - - command keyboardUp - parameters - key: string - - command keyboardInsertText - parameters - text: string - - command keyboardType - parameters - text: string - delay?: number - - command keyboardPress - parameters - key: string - delay?: number - - command mouseMove - parameters - x: number - y: number - steps?: number - - command mouseDown - parameters - button?: enum - left - right - middle - clickCount?: number - - command mouseUp - parameters - button?: enum - left - right - middle - clickCount?: number - - command mouseClick - parameters - x: number - y: number - delay?: number - button?: enum - left - right - middle - clickCount?: number - - command accessibilitySnapshot - parameters - interestingOnly?: boolean - root?: ElementHandle - returns - rootAXNode?: AXNode - - command pdf - parameters - scale?: number - displayHeaderFooter?: boolean - headerTemplate?: string - footerTemplate?: string - printBackground?: boolean - landscape?: boolean - pageRanges?: string - format?: string - width?: string - height?: string - preferCSSPageSize?: boolean - margin?: object - top?: string - bottom?: string - left?: string - right?: string - returns - pdf: binary - - command crStartJSCoverage - parameters - resetOnNavigation?: boolean - reportAnonymousScripts?: boolean - - command crStopJSCoverage - returns - entries: object[] - url: string - scriptId: string - source?: string - functions: object[] - functionName: string - isBlockCoverage: boolean - ranges: object[] - startOffset: number - endOffset: number - count: number - - command crStartCSSCoverage - parameters - resetOnNavigation?: boolean - - command crStopCSSCoverage - returns - entries: object[] - url: string - text?: string - ranges: object[] - start: number - end: number - - command bringToFront - -interface Frame - initializer - url: string - name: string - parentFrame?: Frame - loadStates: enum[] - load - domcontentloaded - networkidle - - event loadstate - parameters - add?: enum - load - domcontentloaded - networkidle - remove?: enum - load - domcontentloaded - networkidle - - event navigated - parameters - url: string - name: string - newDocument?: object - request?: Request - error?: string - - command evalOnSelector - parameters - selector: string - expression: string - isFunction: boolean - arg: SerializedArgument - returns - value: SerializedValue - - command evalOnSelectorAll - parameters - selector: string - expression: string - isFunction: boolean - arg: SerializedArgument - returns - value: SerializedValue - - command addScriptTag - parameters - url?: string - content?: string - type?: string - returns - element: ElementHandle - - command addStyleTag - parameters - url?: string - content?: string - returns - element: ElementHandle - - command check - parameters - selector: string - force?: boolean - noWaitAfter?: boolean - timeout?: number - - command click - parameters - selector: string - force?: boolean - noWaitAfter?: boolean - modifiers?: enum[] - Alt - Control - Meta - Shift - position?: object - x: number - y: number - delay?: number - button?: enum - left - right - middle - clickCount?: number - timeout?: number - - command content - returns - value: string - - command dblclick - parameters - selector: string - force?: boolean - modifiers?: enum[] - Alt - Control - Meta - Shift - position?: object - x: number - y: number - delay?: number - button?: enum - left - right - middle - timeout?: number - - command dispatchEvent - parameters - selector: string - type: string - eventInit: SerializedArgument - timeout?: number - - command evaluateExpression - parameters - expression: string - isFunction: boolean - arg: SerializedArgument - returns - value: SerializedValue - - command evaluateExpressionHandle - parameters - expression: string - isFunction: boolean - arg: SerializedArgument - returns - handle: JSHandle - - command fill - parameters - selector: string - value: string - timeout?: number - noWaitAfter?: boolean - - command focus - parameters - selector: string - timeout?: number - - command frameElement - returns - element: ElementHandle - - command getAttribute - parameters - selector: string - name: string - timeout?: number - returns - value?: string - - command goto - parameters - url: string - timeout?: number - waitUntil?: enum - load - domcontentloaded - networkidle - referer?: string - returns - response?: Response - - command hover - parameters - selector: string - force?: boolean - modifiers?: enum[] - Alt - Control - Meta - Shift - position?: object - x: number - y: number - timeout?: number - - command innerHTML - parameters - selector: string - timeout?: number - returns - value: string - - command innerText - parameters - selector: string - timeout?: number - returns - value: string - - command press - parameters - selector: string - key: string - delay?: number - noWaitAfter?: boolean - timeout?: number - - command querySelector - parameters - selector: string - returns - element?: ElementHandle - - command querySelectorAll - parameters - selector: string - returns - elements: ElementHandle[] - - command selectOption - parameters - selector: string - elements?: ElementHandle[] - options?: object[] - value?: string - label?: string - index?: number - timeout?: number - noWaitAfter?: boolean - returns - values: string[] - - command setContent - parameters - html: string - timeout?: number - waitUntil?: enum - load - domcontentloaded - networkidle - - command setInputFiles - parameters - selector: string - files: object[] - name: string - mimeType: string - buffer: string - timeout?: number - noWaitAfter?: boolean - - command textContent - parameters - selector: string - timeout?: number - returns - value?: string - - command title - returns - value: string - - command type - parameters - selector: string - text: string - delay?: number - noWaitAfter?: boolean - timeout?: number - - command uncheck - parameters - selector: string - force?: boolean - noWaitAfter?: boolean - timeout?: number - - command waitForFunction - parameters - expression: string - isFunction: boolean - arg: SerializedArgument - timeout?: number - # When present, polls on interval. Otherwise, polls on raf. - pollingInterval?: number - returns - handle: JSHandle - - command waitForSelector - parameters - selector: string - timeout?: number - state?: enum - attached - detached - visible - hidden - returns - element?: ElementHandle - -interface Worker - initializer - url: string - - command evaluateExpression - parameters - expression: string - isFunction: boolean - arg: SerializedArgument - returns - value: SerializedValue - - command evaluateExpressionHandle - parameters - expression: string - isFunction: boolean - arg: SerializedArgument - returns - handle: JSHandle - -interface JSHandle - initializer - preview: string - - event previewUpdated - parameters - preview: string - - command dispose - - command evaluateExpression - parameters - expression: string - isFunction: boolean - arg: SerializedArgument - returns - value: SerializedValue - - command evaluateExpressionHandle - parameters - expression: string - isFunction: boolean - arg: SerializedArgument - returns - handle: JSHandle - - command getPropertyList - returns - properties: object[] - name: string - value: JSHandle - - command getProperty - parameters - name: string - returns - handle: JSHandle - - command jsonValue - returns - value: SerializedValue - -interface ElementHandle extends JSHandle - command evalOnSelector - parameters - selector: string - expression: string - isFunction: boolean - arg: SerializedArgument - returns - value: SerializedValue - - command evalOnSelectorAll - parameters - selector: string - expression: string - isFunction: boolean - arg: SerializedArgument - returns - value: SerializedValue - - command boundingBox - returns - value?: object - width: number - height: number - x: number - y: number - - command check - parameters - force?: boolean - noWaitAfter?: boolean - timeout?: number - - command click - parameters - force?: boolean - noWaitAfter?: boolean - modifiers?: enum[] - Alt - Control - Meta - Shift - position?: object - x: number - y: number - delay?: number - button?: enum - left - right - middle - clickCount?: number - timeout?: number - - command contentFrame - returns - frame?: Frame - - command dblclick - parameters - force?: boolean - noWaitAfter?: boolean - modifiers?: enum[] - Alt - Control - Meta - Shift - position?: object - x: number - y: number - delay?: number - button?: enum - left - right - middle - timeout?: number - - command dispatchEvent - parameters - type: string - eventInit: SerializedArgument - - command fill - parameters - value: string - timeout?: number - noWaitAfter?: boolean - - command focus - - command getAttribute - parameters - name: string - returns - value?: string - - command hover - parameters - force?: boolean - modifiers?: enum[] - Alt - Control - Meta - Shift - position?: object - x: number - y: number - timeout?: number - - command innerHTML - returns - value: string - - command innerText - returns - value: string - - command ownerFrame - returns - frame?: Frame - - command press - parameters - key: string - delay?: number - timeout?: number - noWaitAfter?: boolean - - command querySelector - parameters - selector: string - returns - element?: ElementHandle - - command querySelectorAll - parameters - selector: string - returns - elements: ElementHandle[] - - command screenshot - parameters - timeout?: number - type?: enum - png - jpeg - path?: string - quality?: number - omitBackground?: boolean - returns - binary: binary - - command scrollIntoViewIfNeeded - parameters - timeout?: number - - command selectOption - parameters - elements?: ElementHandle[] - options?: object[] - value?: string - label?: string - index?: number - timeout?: number - noWaitAfter?: boolean - returns - values: string[] - - command selectText - parameters - timeout?: number - - command setInputFiles - parameters - files: object[] - name: string - mimeType: string - buffer: string - timeout?: number - noWaitAfter?: boolean - - command textContent - returns - value?: string - - command type - parameters - text: string - delay?: number - noWaitAfter?: boolean - timeout?: number - - command uncheck - parameters - force?: boolean - noWaitAfter?: boolean - timeout?: number - -interface Request - initializer - frame: Frame - url: string - resourceType: string - method: string - postData?: binary - headers: object[] - name: string - value: string - isNavigationRequest: boolean - redirectedFrom?: Request - - command response - returns - response?: Response - -interface Route - initializer - request: Request - - command abort - parameters - errorCode: string - - command continue - parameters - method?: string - headers?: object[] - name: string - value: string - postData?: string - - command fulfill - parameters - status: number - headers: object[] - name: string - value: string - body: string - isBase64: boolean - -interface Response - initializer - request: Request - url: string - status: number - statusText: string - headers: object[] - name: string - value: string - - command body - returns - binary: binary - - command finished - returns - error?: string - -interface ConsoleMessage - initializer - type: string - text: string - args: JSHandle[] - location: object - url?: string - lineNumber?: number - columnNumber?: number - -interface BindingCall - initializer - frame: Frame - name: string - args: SerializedValue[] - - command reject - parameters - error: SerializedError - - command resolve - parameters - result: SerializedArgument - -interface Dialog - initializer - type: string - message: string - defaultValue: string - - command accept - parameters - promptText?: string - - command dismiss - -interface Download - initializer - url: string - suggestedFilename: string - - command path - returns - value?: string - - command saveAs - parameters - path: string - - command failure - returns - error?: string - - command stream - returns - stream?: Stream - - command delete - -interface Stream - command read - parameters - size?: number - returns - binary: binary - -interface CDPSession - event event - parameters - method: string - params?: SerializedValue - - event disconnected - - command send - parameters - method: string - params?: SerializedValue - returns - result: SerializedValue - - command detach - -interface Electron - command launch - parameters - executablePath: string - args?: string[] - cwd?: string - env?: object[] - name: string - value: string - handleSIGINT?: boolean - handleSIGTERM?: boolean - handleSIGHUP?: boolean - timeout?: number - returns - electronApplication: ElectronApplication - -interface ElectronApplication - initializer - context: BrowserContext - - event close - - event window - parameters - page: Page - browserWindow: JSHandle - - command newBrowserWindow - parameters - arg: SerializedArgument - returns - page: Page - - command evaluateExpression - parameters - expression: string - isFunction: boolean - arg: SerializedArgument - returns - value: SerializedValue - - command evaluateExpressionHandle - parameters - expression: string - isFunction: boolean - arg: SerializedArgument - returns - handle: JSHandle - - command close diff --git a/src/rpc/protocol.yml b/src/rpc/protocol.yml new file mode 100644 index 0000000000..51e2ce6e59 --- /dev/null +++ b/src/rpc/protocol.yml @@ -0,0 +1,1926 @@ +# Copyright (c) Microsoft Corporation. +# +# 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. + +SerializedValue: + type: object + # Exactly one of the properties must be present. + properties: + n: number? + b: boolean? + s: string? + v: + type: enum? + literals: + - null + - undefined + - NaN + - Infinity + - -Infinity + - "-0" + # String representation of the Date. + d: string? + # Regular expression pattern and flags. + r: + type: object? + properties: + p: string + f: string + a: + type: array? + items: SerializedValue + # Object with keys and values. + o: + type: array? + items: + type: object + properties: + k: string + v: SerializedValue + # An index in the handles array from SerializedArgument. + h: number? + + +# Represents a value with handle references. +SerializedArgument: + type: object + properties: + value: SerializedValue + handles: + type: array + items: Channel + + +AXNode: + type: object + properties: + role: string + name: string + valueString: string? + valueNumber: number? + description: string? + keyshortcuts: string? + roledescription: string? + valuetext: string? + disabled: boolean? + expanded: boolean? + focused: boolean? + modal: boolean? + multiline: boolean? + multiselectable: boolean? + readonly: boolean? + required: boolean? + selected: boolean? + checked: + type: enum? + literals: + - checked + - unchecked + - mixed + pressed: + type: enum? + literals: + - pressed + - released + - mixed + level: number? + valuemin: number? + valuemax: number? + autocomplete: string? + haspopup: string? + invalid: string? + orientation: string? + children: + type: array? + items: AXNode + + +SerializedError: + type: object + properties: + error: + type: object? + properties: + message: string + name: string + stack: string? + value: SerializedValue? + + +Playwright: + type: interface + + initializer: + chromium: BrowserType + firefox: BrowserType + webkit: BrowserType + electron: Electron? + deviceDescriptors: + type: array + items: + type: object + properties: + name: string + descriptor: + type: object + properties: + userAgent: string + viewport: + type: object + properties: + width: number + height: number + deviceScaleFactor: number + isMobile: boolean + hasTouch: boolean + selectors: Selectors + + + +Selectors: + type: interface + + commands: + + register: + parameters: + name: string + source: string + contentScript: boolean? + + createSelector: + parameters: + name: string + handle: ElementHandle + returns: + value: string? + + + +BrowserType: + type: interface + + initializer: + executablePath: string + name: string + + commands: + + connect: + parameters: + wsEndpoint: string + slowMo: number? + timeout: number? + returns: + browser: Browser + + launch: + parameters: + executablePath: string? + args: + type: array? + items: string + ignoreAllDefaultArgs: boolean? + ignoreDefaultArgs: + type: array? + items: string + handleSIGINT: boolean? + handleSIGTERM: boolean? + handleSIGHUP: boolean? + timeout: number? + env: + type: array? + items: + type: object + properties: + name: string + value: string + headless: boolean? + devtools: boolean? + proxy: + type: object? + properties: + server: string + bypass: string? + username: string? + password: string? + downloadsPath: string? + firefoxUserPrefs: SerializedValue? + slowMo: number? + returns: + browser: Browser + + launchServer: + parameters: + executablePath: string? + args: + type: array? + items: string + ignoreAllDefaultArgs: boolean? + ignoreDefaultArgs: + type: array? + items: string + handleSIGINT: boolean? + handleSIGTERM: boolean? + handleSIGHUP: boolean? + timeout: number? + env: + type: array? + items: + type: object + properties: + name: string + value: string + headless: boolean? + devtools: boolean? + proxy: + type: object? + properties: + server: string + bypass: string? + username: string? + password: string? + downloadsPath: string? + firefoxUserPrefs: SerializedValue? + port: number? + returns: + server: BrowserServer + + launchPersistentContext: + parameters: + userDataDir: string + executablePath: string? + args: + type: array? + items: string + ignoreAllDefaultArgs: boolean? + ignoreDefaultArgs: + type: array? + items: string + handleSIGINT: boolean? + handleSIGTERM: boolean? + handleSIGHUP: boolean? + timeout: number? + env: + type: array? + items: + type: object + properties: + name: string + value: string + headless: boolean? + devtools: boolean? + proxy: + type: object? + properties: + server: string + bypass: string? + username: string? + password: string? + downloadsPath: string? + slowMo: number? + noDefaultViewport: boolean? + viewport: + type: object? + properties: + width: number + height: number + ignoreHTTPSErrors: boolean? + javaScriptEnabled: boolean? + bypassCSP: boolean? + userAgent: string? + locale: string? + timezoneId: string? + geolocation: + type: object? + properties: + longitude: number + latitude: number + accuracy: number? + permissions: + type: array? + items: string + extraHTTPHeaders: + type: array? + items: + type: object + properties: + name: string + value: string + offline: boolean? + httpCredentials: + type: object? + properties: + username: string + password: string + deviceScaleFactor: number? + isMobile: boolean? + hasTouch: boolean? + colorScheme: + type: enum? + literals: + - dark + - light + - no-preference + acceptDownloads: boolean? + returns: + context: BrowserContext + + + +BrowserServer: + type: interface + + initializer: + wsEndpoint: string + pid: number + + commands: + + close: + + kill: + + events: + + close: + + + +Browser: + type: interface + + commands: + + close: + + newContext: + parameters: + noDefaultViewport: boolean? + viewport: + type: object? + properties: + width: number + height: number + ignoreHTTPSErrors: boolean? + javaScriptEnabled: boolean? + bypassCSP: boolean? + userAgent: string? + locale: string? + timezoneId: string? + geolocation: + type: object? + properties: + longitude: number + latitude: number + accuracy: number? + permissions: + type: array? + items: string + extraHTTPHeaders: + type: array? + items: + type: object + properties: + name: string + value: string + offline: boolean? + httpCredentials: + type: object? + properties: + username: string + password: string + deviceScaleFactor: number? + isMobile: boolean? + hasTouch: boolean? + colorScheme: + type: enum? + literals: + - dark + - light + - no-preference + acceptDownloads: boolean? + returns: + context: BrowserContext + + crNewBrowserCDPSession: + returns: + session: CDPSession + + crStartTracing: + parameters: + page: Page? + path: string? + screenshots: boolean? + categories: + type: array? + items: string + + crStopTracing: + returns: + binary: binary + + events: + + close: + + + +BrowserContext: + type: interface + + commands: + + addCookies: + parameters: + cookies: + type: array + items: + type: object + properties: + name: string + value: string + url: string? + domain: string? + path: string? + expires: number? + httpOnly: boolean? + secure: boolean? + sameSite: + type: enum? + literals: + - Strict + - Lax + - None + + addInitScript: + parameters: + source: string + + clearCookies: + + clearPermissions: + + close: + + cookies: + parameters: + urls: + type: array + items: string + returns: + cookies: + type: array + items: + type: object + properties: + name: string + value: string + domain: string + path: string + expires: number + httpOnly: boolean + secure: boolean + sameSite: + type: enum + literals: + - Strict + - Lax + - None + + exposeBinding: + parameters: + name: string + + grantPermissions: + parameters: + permissions: + type: array + items: string + origin: string? + + newPage: + returns: + page: Page + + setDefaultNavigationTimeoutNoReply: + parameters: + timeout: number + + setDefaultTimeoutNoReply: + parameters: + timeout: number + + setExtraHTTPHeaders: + parameters: + headers: + type: array + items: + type: object + properties: + name: string + value: string + + setGeolocation: + parameters: + geolocation: + type: object? + properties: + longitude: number + latitude: number + accuracy: number? + + setHTTPCredentials: + parameters: + httpCredentials: + type: object? + properties: + username: string + password: string + + setNetworkInterceptionEnabled: + parameters: + enabled: boolean + + setOffline: + parameters: + offline: boolean + + crNewCDPSession: + parameters: + page: Page + returns: + session: CDPSession + + events: + + bindingCall: + parameters: + binding: BindingCall + + close: + + page: + parameters: + page: Page + + route: + parameters: + route: Route + request: Request + + crBackgroundPage: + parameters: + page: Page + + crServiceWorker: + parameters: + worker: Worker + + + +Page: + type: interface + + initializer: + mainFrame: Frame + viewportSize: + type: object? + properties: + width: number + height: number + isClosed: boolean + + commands: + + setDefaultNavigationTimeoutNoReply: + parameters: + timeout: number + + setDefaultTimeoutNoReply: + parameters: + timeout: number + + setFileChooserInterceptedNoReply: + parameters: + intercepted: boolean + + addInitScript: + parameters: + source: string + + close: + parameters: + runBeforeUnload: boolean? + + emulateMedia: + parameters: + media: + type: enum? + literals: + - screen + - print + # Reset emulated value to the system default. + - null + colorScheme: + type: enum? + literals: + - dark + - light + - no-preference + # Reset emulated value to the system default. + - null + + exposeBinding: + parameters: + name: string + + goBack: + parameters: + timeout: number? + waitUntil: + type: enum? + literals: + - load + - domcontentloaded + - networkidle + returns: + response: Response? + + goForward: + parameters: + timeout: number? + waitUntil: + type: enum? + literals: + - load + - domcontentloaded + - networkidle + returns: + response: Response? + + opener: + returns: + page: Page? + + reload: + parameters: + timeout: number? + waitUntil: + type: enum? + literals: + - load + - domcontentloaded + - networkidle + returns: + response: Response? + + screenshot: + parameters: + timeout: number? + type: + type: enum? + literals: + - png + - jpeg + path: string? + quality: number? + omitBackground: boolean? + fullPage: boolean? + clip: + type: object? + properties: + width: number + height: number + x: number + y: number + returns: + binary: binary + + setExtraHTTPHeaders: + parameters: + headers: + type: array + items: + type: object + properties: + name: string + value: string + + setNetworkInterceptionEnabled: + parameters: + enabled: boolean + + setViewportSize: + parameters: + viewportSize: + type: object + properties: + width: number + height: number + + keyboardDown: + parameters: + key: string + + keyboardUp: + parameters: + key: string + + keyboardInsertText: + parameters: + text: string + + keyboardType: + parameters: + text: string + delay: number? + + keyboardPress: + parameters: + key: string + delay: number? + + mouseMove: + parameters: + x: number + y: number + steps: number? + + mouseDown: + parameters: + button: + type: enum? + literals: + - left + - right + - middle + clickCount: number? + + mouseUp: + parameters: + button: + type: enum? + literals: + - left + - right + - middle + clickCount: number? + + mouseClick: + parameters: + x: number + y: number + delay: number? + button: + type: enum? + literals: + - left + - right + - middle + clickCount: number? + + accessibilitySnapshot: + parameters: + interestingOnly: boolean? + root: ElementHandle? + returns: + rootAXNode: AXNode? + + pdf: + parameters: + scale: number? + displayHeaderFooter: boolean? + headerTemplate: string? + footerTemplate: string? + printBackground: boolean? + landscape: boolean? + pageRanges: string? + format: string? + width: string? + height: string? + preferCSSPageSize: boolean? + margin: + type: object? + properties: + top: string? + bottom: string? + left: string? + right: string? + returns: + pdf: binary + + crStartJSCoverage: + parameters: + resetOnNavigation: boolean? + reportAnonymousScripts: boolean? + + crStopJSCoverage: + returns: + entries: + type: array + items: + type: object + properties: + url: string + scriptId: string + source: string? + functions: + type: array + items: + type: object + properties: + functionName: string + isBlockCoverage: boolean + ranges: + type: array + items: + type: object + properties: + startOffset: number + endOffset: number + count: number + + crStartCSSCoverage: + parameters: + resetOnNavigation: boolean? + + crStopCSSCoverage: + returns: + entries: + type: array + items: + type: object + properties: + url: string + text: string? + ranges: + type: array + items: + type: object + properties: + start: number + end: number + + bringToFront: + + events: + + bindingCall: + parameters: + binding: BindingCall + + close: + + console: + parameters: + message: ConsoleMessage + + crash: + + dialog: + parameters: + dialog: Dialog + + download: + parameters: + download: Download + + domcontentloaded: + + fileChooser: + parameters: + element: ElementHandle + isMultiple: boolean + + frameAttached: + parameters: + frame: Frame + + frameDetached: + parameters: + frame: Frame + + load: + + pageError: + parameters: + error: SerializedError + + popup: + parameters: + page: Page + + request: + parameters: + request: Request + + requestFailed: + parameters: + request: Request + failureText: string? + + requestFinished: + parameters: + request: Request + + response: + parameters: + response: Response + + route: + parameters: + route: Route + request: Request + + worker: + parameters: + worker: Worker + + + +Frame: + type: interface + + initializer: + url: string + name: string + parentFrame: Frame? + loadStates: + type: array + items: + type: enum + literals: + - load + - domcontentloaded + - networkidle + + commands: + + evalOnSelector: + parameters: + selector: string + expression: string + isFunction: boolean + arg: SerializedArgument + returns: + value: SerializedValue + + evalOnSelectorAll: + parameters: + selector: string + expression: string + isFunction: boolean + arg: SerializedArgument + returns: + value: SerializedValue + + addScriptTag: + parameters: + url: string? + content: string? + type: string? + returns: + element: ElementHandle + + addStyleTag: + parameters: + url: string? + content: string? + returns: + element: ElementHandle + + check: + parameters: + selector: string + force: boolean? + noWaitAfter: boolean? + timeout: number? + + click: + parameters: + selector: string + force: boolean? + noWaitAfter: boolean? + modifiers: + type: array? + items: + type: enum + literals: + - Alt + - Control + - Meta + - Shift + position: + type: object? + properties: + x: number + y: number + delay: number? + button: + type: enum? + literals: + - left + - right + - middle + clickCount: number? + timeout: number? + + content: + returns: + value: string + + dblclick: + parameters: + selector: string + force: boolean? + modifiers: + type: array? + items: + type: enum + literals: + - Alt + - Control + - Meta + - Shift + position: + type: object? + properties: + x: number + y: number + delay: number? + button: + type: enum? + literals: + - left + - right + - middle + timeout: number? + + dispatchEvent: + parameters: + selector: string + type: string + eventInit: SerializedArgument + timeout: number? + + evaluateExpression: + parameters: + expression: string + isFunction: boolean + arg: SerializedArgument + returns: + value: SerializedValue + + evaluateExpressionHandle: + parameters: + expression: string + isFunction: boolean + arg: SerializedArgument + returns: + handle: JSHandle + + fill: + parameters: + selector: string + value: string + timeout: number? + noWaitAfter: boolean? + + focus: + parameters: + selector: string + timeout: number? + + frameElement: + returns: + element: ElementHandle + + getAttribute: + parameters: + selector: string + name: string + timeout: number? + returns: + value: string? + + goto: + parameters: + url: string + timeout: number? + waitUntil: + type: enum? + literals: + - load + - domcontentloaded + - networkidle + referer: string? + returns: + response: Response? + + hover: + parameters: + selector: string + force: boolean? + modifiers: + type: array? + items: + type: enum + literals: + - Alt + - Control + - Meta + - Shift + position: + type: object? + properties: + x: number + y: number + timeout: number? + + innerHTML: + parameters: + selector: string + timeout: number? + returns: + value: string + + innerText: + parameters: + selector: string + timeout: number? + returns: + value: string + + press: + parameters: + selector: string + key: string + delay: number? + noWaitAfter: boolean? + timeout: number? + + querySelector: + parameters: + selector: string + returns: + element: ElementHandle? + + querySelectorAll: + parameters: + selector: string + returns: + elements: + type: array + items: ElementHandle + + selectOption: + parameters: + selector: string + elements: + type: array? + items: ElementHandle + options: + type: array? + items: + type: object + properties: + value: string? + label: string? + index: number? + timeout: number? + noWaitAfter: boolean? + returns: + values: + type: array + items: string + + setContent: + parameters: + html: string + timeout: number? + waitUntil: + type: enum? + literals: + - load + - domcontentloaded + - networkidle + + setInputFiles: + parameters: + selector: string + files: + type: array + items: + type: object + properties: + name: string + mimeType: string + buffer: string + timeout: number? + noWaitAfter: boolean? + + textContent: + parameters: + selector: string + timeout: number? + returns: + value: string? + + title: + returns: + value: string + + type: + parameters: + selector: string + text: string + delay: number? + noWaitAfter: boolean? + timeout: number? + + uncheck: + parameters: + selector: string + force: boolean? + noWaitAfter: boolean? + timeout: number? + + waitForFunction: + parameters: + expression: string + isFunction: boolean + arg: SerializedArgument + timeout: number? + # When present, polls on interval. Otherwise, polls on raf. + pollingInterval: number? + returns: + handle: JSHandle + + waitForSelector: + parameters: + selector: string + timeout: number? + state: + type: enum? + literals: + - attached + - detached + - visible + - hidden + returns: + element: ElementHandle? + + events: + + loadstate: + parameters: + add: + type: enum? + literals: + - load + - domcontentloaded + - networkidle + remove: + type: enum? + literals: + - load + - domcontentloaded + - networkidle + + navigated: + parameters: + url: string + name: string + newDocument: + type: object? + properties: + request: Request? + error: string? + + + +Worker: + type: interface + + initializer: + url: string + + commands: + + evaluateExpression: + parameters: + expression: string + isFunction: boolean + arg: SerializedArgument + returns: + value: SerializedValue + + evaluateExpressionHandle: + parameters: + expression: string + isFunction: boolean + arg: SerializedArgument + returns: + handle: JSHandle + + + +JSHandle: + type: interface + + initializer: + preview: string + + commands: + + dispose: + + evaluateExpression: + parameters: + expression: string + isFunction: boolean + arg: SerializedArgument + returns: + value: SerializedValue + + evaluateExpressionHandle: + parameters: + expression: string + isFunction: boolean + arg: SerializedArgument + returns: + handle: JSHandle + + getPropertyList: + returns: + properties: + type: array + items: + type: object + properties: + name: string + value: JSHandle + + getProperty: + parameters: + name: string + returns: + handle: JSHandle + + jsonValue: + returns: + value: SerializedValue + + events: + + previewUpdated: + parameters: + preview: string + + + +ElementHandle: + type: interface + + extends: JSHandle + + commands: + + evalOnSelector: + parameters: + selector: string + expression: string + isFunction: boolean + arg: SerializedArgument + returns: + value: SerializedValue + + evalOnSelectorAll: + parameters: + selector: string + expression: string + isFunction: boolean + arg: SerializedArgument + returns: + value: SerializedValue + + boundingBox: + returns: + value: + type: object? + properties: + width: number + height: number + x: number + y: number + + check: + parameters: + force: boolean? + noWaitAfter: boolean? + timeout: number? + + click: + parameters: + force: boolean? + noWaitAfter: boolean? + modifiers: + type: array? + items: + type: enum + literals: + - Alt + - Control + - Meta + - Shift + position: + type: object? + properties: + x: number + y: number + delay: number? + button: + type: enum? + literals: + - left + - right + - middle + clickCount: number? + timeout: number? + + contentFrame: + returns: + frame: Frame? + + dblclick: + parameters: + force: boolean? + noWaitAfter: boolean? + modifiers: + type: array? + items: + type: enum + literals: + - Alt + - Control + - Meta + - Shift + position: + type: object? + properties: + x: number + y: number + delay: number? + button: + type: enum? + literals: + - left + - right + - middle + timeout: number? + + dispatchEvent: + parameters: + type: string + eventInit: SerializedArgument + + fill: + parameters: + value: string + timeout: number? + noWaitAfter: boolean? + + focus: + + getAttribute: + parameters: + name: string + returns: + value: string? + + hover: + parameters: + force: boolean? + modifiers: + type: array? + items: + type: enum + literals: + - Alt + - Control + - Meta + - Shift + position: + type: object? + properties: + x: number + y: number + timeout: number? + + innerHTML: + returns: + value: string + + innerText: + returns: + value: string + + ownerFrame: + returns: + frame: Frame? + + press: + parameters: + key: string + delay: number? + timeout: number? + noWaitAfter: boolean? + + querySelector: + parameters: + selector: string + returns: + element: ElementHandle? + + querySelectorAll: + parameters: + selector: string + returns: + elements: + type: array + items: ElementHandle + + screenshot: + parameters: + timeout: number? + type: + type: enum? + literals: + - png + - jpeg + path: string? + quality: number? + omitBackground: boolean? + returns: + binary: binary + + scrollIntoViewIfNeeded: + parameters: + timeout: number? + + selectOption: + parameters: + elements: + type: array? + items: ElementHandle + options: + type: array? + items: + type: object + properties: + value: string? + label: string? + index: number? + timeout: number? + noWaitAfter: boolean? + returns: + values: + type: array + items: string + + selectText: + parameters: + timeout: number? + + setInputFiles: + parameters: + files: + type: array + items: + type: object + properties: + name: string + mimeType: string + buffer: string + timeout: number? + noWaitAfter: boolean? + + textContent: + returns: + value: string? + + type: + parameters: + text: string + delay: number? + noWaitAfter: boolean? + timeout: number? + + uncheck: + parameters: + force: boolean? + noWaitAfter: boolean? + timeout: number? + + + +Request: + type: interface + + initializer: + frame: Frame + url: string + resourceType: string + method: string + postData: binary? + headers: + type: array + items: + type: object + properties: + name: string + value: string + isNavigationRequest: boolean + redirectedFrom: Request? + + commands: + + response: + returns: + response: Response? + + + +Route: + type: interface + + initializer: + request: Request + + commands: + + abort: + parameters: + errorCode: string + + continue: + parameters: + method: string? + headers: + type: array? + items: + type: object + properties: + name: string + value: string + postData: string? + + fulfill: + parameters: + status: number + headers: + type: array + items: + type: object + properties: + name: string + value: string + body: string + isBase64: boolean + + + +Response: + type: interface + + initializer: + request: Request + url: string + status: number + statusText: string + headers: + type: array + items: + type: object + properties: + name: string + value: string + + commands: + + body: + returns: + binary: binary + + finished: + returns: + error: string? + + + +ConsoleMessage: + type: interface + + initializer: + type: string + text: string + args: + type: array + items: JSHandle + location: + type: object + properties: + url: string? + lineNumber: number? + columnNumber: number? + + + +BindingCall: + type: interface + + initializer: + frame: Frame + name: string + args: + type: array + items: SerializedValue + + commands: + + reject: + parameters: + error: SerializedError + + resolve: + parameters: + result: SerializedArgument + + + +Dialog: + type: interface + + initializer: + type: string + message: string + defaultValue: string + + commands: + + accept: + parameters: + promptText: string? + + dismiss: + + + +Download: + type: interface + + initializer: + url: string + suggestedFilename: string + + commands: + + path: + returns: + value: string? + + saveAs: + parameters: + path: string + + failure: + returns: + error: string? + + stream: + returns: + stream: Stream? + + delete: + + + +Stream: + type: interface + + commands: + + read: + parameters: + size: number? + returns: + binary: binary + + + +CDPSession: + type: interface + + commands: + + send: + parameters: + method: string + params: SerializedValue? + returns: + result: SerializedValue + + detach: + + events: + + event: + parameters: + method: string + params: SerializedValue? + + disconnected: + + + +Electron: + type: interface + + commands: + + launch: + parameters: + executablePath: string + args: + type: array? + items: string + cwd: string? + env: + type: array? + items: + type: object + properties: + name: string + value: string + handleSIGINT: boolean? + handleSIGTERM: boolean? + handleSIGHUP: boolean? + timeout: number? + returns: + electronApplication: ElectronApplication + + + +ElectronApplication: + type: interface + + initializer: + context: BrowserContext + + commands: + + newBrowserWindow: + parameters: + arg: SerializedArgument + returns: + page: Page + + evaluateExpression: + parameters: + expression: string + isFunction: boolean + arg: SerializedArgument + returns: + value: SerializedValue + + evaluateExpressionHandle: + parameters: + expression: string + isFunction: boolean + arg: SerializedArgument + returns: + handle: JSHandle + + close: + + events: + + close: + + window: + parameters: + page: Page + browserWindow: JSHandle + + diff --git a/utils/generate_channels.js b/utils/generate_channels.js index 329381b75e..8daf58c7d5 100755 --- a/utils/generate_channels.js +++ b/utils/generate_channels.js @@ -17,145 +17,76 @@ const fs = require('fs'); const path = require('path'); +const yaml = require('yaml'); const channels = new Set(); -function tokenize(source) { - const lines = source.split('\n').filter(line => { - const trimmed = line.trim(); - return !!trimmed && trimmed[0] != '#'; - }); - - const stack = [{ indent: -1, list: [], words: '' }]; - for (const line of lines) { - const indent = line.length - line.trimLeft().length; - const o = { indent, list: [], words: line.split(' ').filter(word => !!word) }; - - let current = stack[stack.length - 1]; - while (indent <= current.indent) { - stack.pop(); - current = stack[stack.length - 1]; - } - - current.list.push(o); - stack.push(o); - } - return stack[0].list; -} - function raise(item) { - throw new Error(item.words.join(' ')); + throw new Error('Invalid item: ' + JSON.stringify(item, null, 2)); } function titleCase(name) { return name[0].toUpperCase() + name.substring(1); } -function inlineType(item, indent) { - let type = item.words[1]; - const array = type.endsWith('[]'); - if (array) - type = type.substring(0, type.length - 2); - let inner = ''; - if (type === 'enum') { - const literals = item.list.map(literal => { - if (literal.words.length > 1 || literal.list.length) - raise(literal); - return literal.words[0]; - }); - inner = literals.map(literal => `'${literal}'`).join(' | '); - if (array) - inner = `(${inner})`; - } else if (['string', 'boolean', 'number', 'undefined'].includes(type)) { - inner = type; - } else if (type === 'object') { - inner = `{\n${properties(item, indent + ' ')}\n${indent}}`; - } else if (type === 'binary') { - inner = 'Binary'; - } else if (channels.has(type)) { - inner = type + 'Channel'; - } else { - inner = type; - } - return inner + (array ? '[]' : ''); -} - -function inlineTypeScheme(item, indent) { - let type = item.words[1]; - const array = type.endsWith('[]'); - if (array) - type = type.substring(0, type.length - 2); - let inner = ''; - if (type === 'enum') { - const literals = item.list.map(literal => { - if (literal.words.length > 1 || literal.list.length) - raise(literal); - return literal.words[0]; - }); - inner = `tEnum([${literals.map(literal => `'${literal}'`).join(', ')}])`; - } else if (['string', 'boolean', 'number', 'undefined'].includes(type)) { - inner = `t${titleCase(type)}`; - } else if (type === 'object') { - inner = `tObject({\n${propertiesScheme(item, indent + ' ')}\n${indent}})`; - } else if (type === 'binary') { - inner = 'tBinary'; - } else if (channels.has(type)) { - inner = `tChannel('${type}')`; - } else if (type === 'Channel') { - inner = `tChannel('*')`; - } else { - inner = `tType('${type}')`; - } - return array ? `tArray(${inner})` : inner; -} - -function properties(item, indent) { - const result = []; - for (const prop of item.list) { - if (prop.words.length !== 2) - raise(prop); - let name = prop.words[0]; - if (!name.endsWith(':')) - raise(item); - name = name.substring(0, name.length - 1); - const optional = name.endsWith('?'); +function inlineType(type, indent, wrapEnums = false) { + if (typeof type === 'string') { + const optional = type.endsWith('?'); if (optional) - name = name.substring(0, name.length - 1); - result.push(`${indent}${name}${optional ? '?' : ''}: ${inlineType(prop, indent)},`); + type = type.substring(0, type.length - 1); + if (type === 'binary') + return { ts: 'Binary', scheme: 'tBinary', optional }; + if (['string', 'boolean', 'number', 'undefined'].includes(type)) + return { ts: type, scheme: `t${titleCase(type)}`, optional }; + if (channels.has(type)) + return { ts: `${type}Channel`, scheme: `tChannel('${type}')` , optional }; + if (type === 'Channel') + return { ts: `Channel`, scheme: `tChannel('*')`, optional }; + return { ts: type, scheme: `tType('${type}')`, optional }; } - return result.join('\n'); -} - -function propertiesScheme(item, indent) { - const result = []; - for (const prop of item.list) { - if (prop.words.length !== 2) - raise(prop); - let name = prop.words[0]; - if (!name.endsWith(':')) - raise(item); - name = name.substring(0, name.length - 1); - const optional = name.endsWith('?'); - if (optional) - name = name.substring(0, name.length - 1); - let type = inlineTypeScheme(prop, indent); - if (optional) - type = `tOptional(${type})`; - result.push(`${indent}${name}: ${type},`); + if (type.type.startsWith('array')) { + const optional = type.type.endsWith('?'); + const inner = inlineType(type.items, indent, true); + return { ts: `${inner.ts}[]`, scheme: `tArray(${inner.scheme})`, optional }; } - return result.join('\n'); + if (type.type.startsWith('enum')) { + const optional = type.type.endsWith('?'); + const ts = type.literals.map(literal => `'${literal}'`).join(' | '); + return { + ts: wrapEnums ? `(${ts})` : ts, + scheme: `tEnum([${type.literals.map(literal => `'${literal}'`).join(', ')}])`, + optional + }; + } + if (type.type.startsWith('object')) { + const optional = type.type.endsWith('?'); + const inner = properties(type.properties, indent + ' '); + return { + ts: `{\n${inner.ts}\n${indent}}`, + scheme: `tObject({\n${inner.scheme}\n${indent}})`, + optional + }; + } + raise(type); } -function objectType(name, item, indent) { - if (!item.list.length) - return `export type ${name} = {};`; - return `export type ${name} = {\n${properties(item, indent)}\n};` +function properties(props, indent) { + const ts = []; + const scheme = []; + for (const [name, value] of Object.entries(props)) { + const inner = inlineType(value, indent); + ts.push(`${indent}${name}${inner.optional ? '?' : ''}: ${inner.ts},`); + const wrapped = inner.optional ? `tOptional(${inner.scheme})` : inner.scheme; + scheme.push(`${indent}${name}: ${wrapped},`); + } + return { ts: ts.join('\n'), scheme: scheme.join('\n') }; } -function objectTypeScheme(item, indent) { - if (!item.list.length) - return `tObject({})`; - return `tObject({\n${propertiesScheme(item, indent)}\n})` +function objectType(props, indent) { + if (!Object.entries(props).length) + return { ts: `{}`, scheme: `tObject({})` }; + const inner = properties(props, indent + ' '); + return { ts: `{\n${inner.ts}\n${indent}}`, scheme: `tObject({\n${inner.scheme}\n${indent}})` }; } const channels_ts = [ @@ -185,108 +116,6 @@ export interface Channel extends EventEmitter { } `]; -const pdl = fs.readFileSync(path.join(__dirname, '..', 'src', 'rpc', 'protocol.pdl'), 'utf-8'); -const list = tokenize(pdl); -const scheme = new Map(); -const inherits = new Map(); - -function addScheme(name, s) { - if (scheme.has(name)) - throw new Error('Duplicate scheme name ' + name); - scheme.set(name, s); -} - -for (const item of list) { - if (item.words[0] === 'interface') { - channels.add(item.words[1]); - if (item.words[2] === 'extends') - inherits.set(item.words[1], item.words[3]); - } -} - -for (const item of list) { - if (item.words[0] === 'type') { - if (item.words.length !== 2) - raise(item); - channels_ts.push(`export type ${item.words[1]} = {`); - channels_ts.push(properties(item, ' ')); - channels_ts.push(`};`); - addScheme(item.words[1], objectTypeScheme(item, ' ')); - } else if (item.words[0] === 'interface') { - const channelName = item.words[1]; - channels_ts.push(`// ----------- ${channelName} -----------`); - const init = item.list.find(i => i.words[0] === 'initializer'); - if (init && init.words.length > 1) - raise(init); - channels_ts.push(objectType(channelName + 'Initializer', init || { list: [] }, ' ')); - addScheme(channelName + 'Initializer', objectTypeScheme(init || { list: [] }, ' ')); - - let extendsName = 'Channel'; - if (item.words.length === 4 && item.words[2] === 'extends') - extendsName = item.words[3] + 'Channel'; - else if (item.words.length !== 2) - raise(item); - channels_ts.push(`export interface ${channelName}Channel extends ${extendsName} {`); - - const types = new Map(); - for (const method of item.list) { - if (method === init) - continue; - if (method.words[0] === 'command') { - if (method.words.length !== 2) - raise(method); - const methodName = method.words[1]; - - const parameters = method.list.find(i => i.words[0] === 'parameters'); - const paramsName = `${channelName}${titleCase(methodName)}Params`; - types.set(paramsName, parameters || { list: [] }); - addScheme(paramsName, parameters ? objectTypeScheme(parameters, ' ') : `tOptional(tObject({}))`); - - const returns = method.list.find(i => i.words[0] === 'returns'); - const resultName = `${channelName}${titleCase(methodName)}Result`; - types.set(resultName, returns); - addScheme(resultName, returns ? objectTypeScheme(returns, ' ') : `tUndefined`); - - channels_ts.push(` ${methodName}(params${parameters ? '' : '?'}: ${paramsName}): Promise<${resultName}>;`); - for (const key of inherits.keys()) { - if (inherits.get(key) === channelName) { - addScheme(`${key}${titleCase(methodName)}Params`, `tType('${paramsName}')`); - addScheme(`${key}${titleCase(methodName)}Result`, `tType('${resultName}')`); - } - } - } else if (method.words[0] === 'event') { - if (method.words.length !== 2) - raise(method); - const eventName = method.words[1]; - - const parameters = method.list.find(i => i.words[0] === 'parameters'); - const paramsName = `${channelName}${titleCase(eventName)}Event`; - types.set(paramsName, parameters || { list: [] }); - addScheme(paramsName, objectTypeScheme(parameters || { list: [] }, ' ')); - - channels_ts.push(` on(event: '${eventName}', callback: (params: ${paramsName}) => void): this;`); - for (const key of inherits.keys()) { - if (inherits.get(key) === channelName) - addScheme(`${key}${titleCase(eventName)}Event`, `tType('${paramsName}')`); - } - } else { - raise(method); - } - } - channels_ts.push(`}`); - for (const [name, item] of types) { - if (!item) - channels_ts.push(`export type ${name} = void;`); - else - channels_ts.push(objectType(name, item, ' ')); - } - } else { - raise(item); - } - channels_ts.push(``); -} - - const client_validator_ts = [ `/** * Copyright (c) Microsoft Corporation. @@ -309,9 +138,83 @@ const client_validator_ts = [ import { scheme, tOptional, tObject, tBoolean, tNumber, tString, tType, tEnum, tArray, tChannel, tUndefined, tBinary } from './validatorPrimitives'; export { validateParams } from './validatorPrimitives'; `]; -for (const [name, value] of scheme) - client_validator_ts.push(`scheme.${name} = ${value};`); -client_validator_ts.push(``); +const yml = fs.readFileSync(path.join(__dirname, '..', 'src', 'rpc', 'protocol.yml'), 'utf-8'); +const protocol = yaml.parse(yml); + +function addScheme(name, s) { + client_validator_ts.push(`scheme.${name} = ${s};`); +} + +const inherits = new Map(); +for (const [name, value] of Object.entries(protocol)) { + if (value.type === 'interface') { + channels.add(name); + if (value.extends) + inherits.set(name, value.extends); + } +} + +for (const [name, item] of Object.entries(protocol)) { + if (item.type === 'interface') { + const channelName = name; + channels_ts.push(`// ----------- ${channelName} -----------`); + const init = objectType(item.initializer || {}, ''); + const initializerName = channelName + 'Initializer'; + channels_ts.push(`export type ${initializerName} = ${init.ts};`); + addScheme(initializerName, init.scheme); + + channels_ts.push(`export interface ${channelName}Channel extends ${(item.extends || '') + 'Channel'} {`); + const ts_types = new Map(); + + for (let [eventName, event] of Object.entries(item.events || {})) { + if (event === null) + event = {}; + const parameters = objectType(event.parameters || {}, ''); + const paramsName = `${channelName}${titleCase(eventName)}Event`; + ts_types.set(paramsName, parameters.ts); + addScheme(paramsName, parameters.scheme); + + channels_ts.push(` on(event: '${eventName}', callback: (params: ${paramsName}) => void): this;`); + for (const key of inherits.keys()) { + if (inherits.get(key) === channelName) + addScheme(`${key}${titleCase(eventName)}Event`, `tType('${paramsName}')`); + } + } + + for (let [methodName, method] of Object.entries(item.commands || {})) { + if (method === null) + method = {}; + const parameters = objectType(method.parameters || {}, ''); + const paramsName = `${channelName}${titleCase(methodName)}Params`; + ts_types.set(paramsName, parameters.ts); + addScheme(paramsName, method.parameters ? parameters.scheme : `tOptional(tObject({}))`); + + const resultName = `${channelName}${titleCase(methodName)}Result`; + const returns = objectType(method.returns || {}, ''); + ts_types.set(resultName, method.returns ? returns.ts : 'void'); + addScheme(resultName, method.returns ? returns.scheme : `tUndefined`); + + channels_ts.push(` ${methodName}(params${method.parameters ? '' : '?'}: ${paramsName}): Promise<${resultName}>;`); + for (const key of inherits.keys()) { + if (inherits.get(key) === channelName) { + addScheme(`${key}${titleCase(methodName)}Params`, `tType('${paramsName}')`); + addScheme(`${key}${titleCase(methodName)}Result`, `tType('${resultName}')`); + } + } + } + + channels_ts.push(`}`); + for (const [typeName, typeValue] of ts_types) + channels_ts.push(`export type ${typeName} = ${typeValue};`); + } else if (item.type === 'object') { + const inner = objectType(item.properties, ''); + channels_ts.push(`export type ${name} = ${inner.ts};`); + addScheme(name, inner.scheme); + } + channels_ts.push(``); +} + +client_validator_ts.push(``); fs.writeFileSync(path.join(__dirname, '..', 'src', 'rpc', 'channels.ts'), channels_ts.join('\n'), 'utf-8'); fs.writeFileSync(path.join(__dirname, '..', 'src', 'rpc', 'client', 'validator.ts'), client_validator_ts.join('\n'), 'utf-8');