From f9a89eb31371937cf51e8e50f3f5d3b69fecf775 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Wed, 20 Nov 2019 15:16:57 -0800 Subject: [PATCH] chore: split vendor APIs (#38) --- README.md | 2 +- docs/api.md | 8 -- src/api.ts | 101 ++------------------ src/chromium/Browser.ts | 2 +- src/chromium/Connection.ts | 5 +- src/chromium/Page.ts | 2 +- src/chromium/Target.ts | 2 +- src/chromium/api.ts | 24 +++++ src/{Events.ts => chromium/events.ts} | 1 - src/chromium/features/workers.ts | 2 +- src/firefox/Browser.ts | 2 +- src/firefox/Page.ts | 2 +- src/firefox/api.ts | 16 ++++ src/firefox/events.ts | 50 ++++++++++ src/webkit/Browser.ts | 9 +- src/webkit/FrameManager.ts | 2 +- src/webkit/Page.ts | 2 +- src/webkit/Target.ts | 8 +- src/webkit/api.ts | 13 +++ src/webkit/events.ts | 44 +++++++++ test/test.js | 2 +- utils/doclint/check_public_api/JSBuilder.js | 4 +- 22 files changed, 173 insertions(+), 130 deletions(-) create mode 100644 src/chromium/api.ts rename src/{Events.ts => chromium/events.ts} (98%) create mode 100644 src/firefox/api.ts create mode 100644 src/firefox/events.ts create mode 100644 src/webkit/api.ts create mode 100644 src/webkit/events.ts diff --git a/README.md b/README.md index a1cda4e6f5..5f9b73e99b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ |Firefox|Chromium|WebKit|all| |---|---|---|---| -|508/634|685/692|325/637|309/634| +|508/632|683/690|325/635|309/632| # Contributing diff --git a/docs/api.md b/docs/api.md index d400e982be..41172efb76 100644 --- a/docs/api.md +++ b/docs/api.md @@ -70,7 +70,6 @@ * [event: 'console'](#event-console) * [event: 'dialog'](#event-dialog) * [event: 'domcontentloaded'](#event-domcontentloaded) - * [event: 'error'](#event-error) * [event: 'frameattached'](#event-frameattached) * [event: 'framedetached'](#event-framedetached) * [event: 'framenavigated'](#event-framenavigated) @@ -995,13 +994,6 @@ Emitted when a JavaScript dialog appears, such as `alert`, `prompt`, `confirm` o Emitted when the JavaScript [`DOMContentLoaded`](https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded) event is dispatched. -#### event: 'error' -- <[Error]> - -Emitted when the page crashes. - -> **NOTE** `error` event has a special meaning in Node, see [error events](https://nodejs.org/api/events.html#events_error_events) for details. - #### event: 'frameattached' - <[Frame]> diff --git a/src/api.ts b/src/api.ts index a33d157443..bfceefe31c 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,91 +1,10 @@ -/** - * Copyright 2019 Google Inc. All rights reserved. - * Modifications 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. - */ -export = { - Chromium: { - Accessibility: require('./chromium/features/accessibility').Accessibility, - Browser: require('./chromium/Browser').Browser, - BrowserContext: require('./chromium/BrowserContext').BrowserContext, - BrowserFetcher: require('./chromium/BrowserFetcher').BrowserFetcher, - CDPSession: require('./chromium/Connection').CDPSession, - ConsoleMessage: require('./chromium/Page').ConsoleMessage, - Coverage: require('./chromium/features/coverage').Coverage, - Dialog: require('./chromium/Dialog').Dialog, - ElementHandle: require('./chromium/JSHandle').ElementHandle, - ExecutionContext: require('./chromium/ExecutionContext').ExecutionContext, - FileChooser: require('./chromium/Page').FileChooser, - Frame: require('./chromium/Frame').Frame, - Geolocation: require('./chromium/features/geolocation').Geolocation, - JSHandle: require('./chromium/JSHandle').JSHandle, - Keyboard: require('./chromium/Input').Keyboard, - Mouse: require('./chromium/Input').Mouse, - PDF: require('./chromium/features/pdf').PDF, - Page: require('./chromium/Page').Page, - Permissions: require('./chromium/features/permissions').Permissions, - Playwright: require('./chromium/Playwright').Playwright, - Request: require('./chromium/NetworkManager').Request, - Response: require('./chromium/NetworkManager').Response, - Target: require('./chromium/Target').Target, - TimeoutError: require('./Errors').TimeoutError, - Touchscreen: require('./chromium/Input').Touchscreen, - Tracing: require('./chromium/features/tracing').Tracing, - Worker: require('./chromium/features/workers').Worker, - Workers: require('./chromium/features/workers').Workers, - }, - Firefox: { - Accessibility: require('./firefox/features/accessibility').Accessibility, - Browser: require('./firefox/Browser').Browser, - BrowserContext: require('./firefox/Browser').BrowserContext, - BrowserFetcher: require('./firefox/BrowserFetcher').BrowserFetcher, - CDPSession: require('./firefox/Connection').CDPSession, - ConsoleMessage: require('./firefox/Page').ConsoleMessage, - Dialog: require('./firefox/Dialog').Dialog, - ElementHandle: require('./firefox/JSHandle').ElementHandle, - ExecutionContext: require('./firefox/ExecutionContext').ExecutionContext, - FileChooser: require('./firefox/Page').FileChooser, - Frame: require('./firefox/FrameManager').Frame, - JSHandle: require('./firefox/JSHandle').JSHandle, - Keyboard: require('./firefox/Input').Keyboard, - Mouse: require('./firefox/Input').Mouse, - Page: require('./firefox/Page').Page, - Permissions: require('./firefox/features/permissions').Permissions, - Playwright: require('./firefox/Playwright').Playwright, - Request: require('./firefox/NetworkManager').Request, - Response: require('./firefox/NetworkManager').Response, - Target: require('./firefox/Browser').Target, - TimeoutError: require('./Errors').TimeoutError, - Touchscreen: require('./firefox/Input').Touchscreen, - }, - WebKit: { - Browser: require('./webkit/Browser').Browser, - BrowserContext: require('./webkit/Browser').BrowserContext, - BrowserFetcher: require('./webkit/BrowserFetcher'), - ConsoleMessage: require('./webkit/Page').ConsoleMessage, - ElementHandle: require('./webkit/JSHandle').ElementHandle, - ExecutionContext: require('./webkit/ExecutionContext').ExecutionContext, - Frame: require('./webkit/FrameManager').Frame, - JSHandle: require('./webkit/JSHandle').JSHandle, - Keyboard: require('./webkit/Input').Keyboard, - Mouse: require('./webkit/Input').Mouse, - Page: require('./webkit/Page').Page, - Playwright: require('./webkit/Playwright').Playwright, - Request: require('./webkit/NetworkManager').Request, - Response: require('./webkit/NetworkManager').Response, - Target: require('./webkit/Browser').Target, - TimeoutError: require('./Errors').TimeoutError, - Touchscreen: require('./webkit/Input').Touchscreen, - } -}; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import * as chromium from './chromium/api'; +import * as firefox from './firefox/api'; +import * as webkit from './webkit/api'; + +export const Chromium = chromium; +export const Firefox = firefox; +export const WebKit = webkit; diff --git a/src/chromium/Browser.ts b/src/chromium/Browser.ts index e5ff1e65df..52deeb2a80 100644 --- a/src/chromium/Browser.ts +++ b/src/chromium/Browser.ts @@ -17,7 +17,7 @@ import * as childProcess from 'child_process'; import { EventEmitter } from 'events'; -import { Events } from '../Events'; +import { Events } from './events'; import { assert, helper } from '../helper'; import { BrowserContext } from './BrowserContext'; import { Connection, ConnectionEvents } from './Connection'; diff --git a/src/chromium/Connection.ts b/src/chromium/Connection.ts index 212ff016eb..9c97b675b0 100644 --- a/src/chromium/Connection.ts +++ b/src/chromium/Connection.ts @@ -15,11 +15,10 @@ * limitations under the License. */ -import {assert} from '../helper'; -import {Events} from '../Events'; import * as debug from 'debug'; -import {EventEmitter} from 'events'; +import { EventEmitter } from 'events'; import { ConnectionTransport } from '../ConnectionTransport'; +import { assert } from '../helper'; import { Protocol } from './protocol'; const debugProtocol = debug('playwright:protocol'); diff --git a/src/chromium/Page.ts b/src/chromium/Page.ts index cbb26c7462..b15dd0505b 100644 --- a/src/chromium/Page.ts +++ b/src/chromium/Page.ts @@ -19,7 +19,7 @@ import { EventEmitter } from 'events'; import * as fs from 'fs'; import * as mime from 'mime'; import * as path from 'path'; -import { Events } from '../Events'; +import { Events } from './events'; import { assert, debugError, helper } from '../helper'; import { TimeoutSettings } from '../TimeoutSettings'; import { Accessibility } from './features/accessibility'; diff --git a/src/chromium/Target.ts b/src/chromium/Target.ts index 6d12659b11..d3f4a05793 100644 --- a/src/chromium/Target.ts +++ b/src/chromium/Target.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { Events } from '../Events'; +import { Events } from './events'; import { Browser } from './Browser'; import { BrowserContext } from './BrowserContext'; import { CDPSession } from './Connection'; diff --git a/src/chromium/api.ts b/src/chromium/api.ts new file mode 100644 index 0000000000..40b1f4ea81 --- /dev/null +++ b/src/chromium/api.ts @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +export { TimeoutError } from '../Errors'; +export { Browser } from './Browser'; +export { BrowserContext } from './BrowserContext'; +export { BrowserFetcher } from './BrowserFetcher'; +export { CDPSession } from './Connection'; +export { Dialog } from './Dialog'; +export { ExecutionContext } from './ExecutionContext'; +export { Accessibility } from './features/accessibility'; +export { Coverage } from './features/coverage'; +export { Geolocation } from './features/geolocation'; +export { PDF } from './features/pdf'; +export { Permissions } from './features/permissions'; +export { Tracing } from './features/tracing'; +export { Worker, Workers } from './features/workers'; +export { Frame } from './Frame'; +export { Keyboard, Mouse, Touchscreen } from './Input'; +export { ElementHandle, JSHandle } from './JSHandle'; +export { Request, Response } from './NetworkManager'; +export { ConsoleMessage, FileChooser, Page } from './Page'; +export { Playwright } from './Playwright'; +export { Target } from './Target'; diff --git a/src/Events.ts b/src/chromium/events.ts similarity index 98% rename from src/Events.ts rename to src/chromium/events.ts index 3f18497bc2..a23f209b0e 100644 --- a/src/Events.ts +++ b/src/chromium/events.ts @@ -21,7 +21,6 @@ export const Events = { Console: 'console', Dialog: 'dialog', DOMContentLoaded: 'domcontentloaded', - Error: 'error', // Can't use just 'error' due to node.js special treatment of error events. // @see https://nodejs.org/api/events.html#events_error_events PageError: 'pageerror', diff --git a/src/chromium/features/workers.ts b/src/chromium/features/workers.ts index 654344707b..e5de3d7276 100644 --- a/src/chromium/features/workers.ts +++ b/src/chromium/features/workers.ts @@ -20,7 +20,7 @@ import { ExecutionContext } from '../ExecutionContext'; import { debugError } from '../../helper'; import { JSHandle } from '../JSHandle'; import { Protocol } from '../protocol'; -import { Events } from '../../Events'; +import { Events } from '../events'; type AddToConsoleCallback = (type: string, args: JSHandle[], stackTrace: Protocol.Runtime.StackTrace | undefined) => void; type HandleExceptionCallback = (exceptionDetails: Protocol.Runtime.ExceptionDetails) => void; diff --git a/src/firefox/Browser.ts b/src/firefox/Browser.ts index 009cd9e542..c292857834 100644 --- a/src/firefox/Browser.ts +++ b/src/firefox/Browser.ts @@ -16,7 +16,7 @@ */ import { EventEmitter } from 'events'; -import { Events } from '../Events'; +import { Events } from './events'; import { assert, helper, RegisteredListener } from '../helper'; import { Connection, ConnectionEvents } from './Connection'; import { Permissions } from './features/permissions'; diff --git a/src/firefox/Page.ts b/src/firefox/Page.ts index a9022b9afe..c577f87e22 100644 --- a/src/firefox/Page.ts +++ b/src/firefox/Page.ts @@ -15,7 +15,7 @@ import {TimeoutSettings} from '../TimeoutSettings'; import {NavigationWatchdog} from './NavigationWatchdog'; import {Accessibility} from './features/accessibility'; import { Target, BrowserContext } from './Browser'; -import { Events } from '../Events'; +import { Events } from './events'; const writeFileAsync = helper.promisify(fs.writeFile); diff --git a/src/firefox/api.ts b/src/firefox/api.ts new file mode 100644 index 0000000000..e8d528876a --- /dev/null +++ b/src/firefox/api.ts @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +export { TimeoutError } from '../Errors'; +export { Browser, BrowserContext, Target } from './Browser'; +export { BrowserFetcher } from './BrowserFetcher'; +export { Dialog } from './Dialog'; +export { ExecutionContext } from './ExecutionContext'; +export { Accessibility } from './features/accessibility'; +export { Permissions } from './features/permissions'; +export { Frame } from './FrameManager'; +export { Keyboard, Mouse, Touchscreen } from './Input'; +export { ElementHandle, JSHandle } from './JSHandle'; +export { Request, Response } from './NetworkManager'; +export { ConsoleMessage, Page } from './Page'; +export { Playwright } from './Playwright'; diff --git a/src/firefox/events.ts b/src/firefox/events.ts new file mode 100644 index 0000000000..276be50f7f --- /dev/null +++ b/src/firefox/events.ts @@ -0,0 +1,50 @@ +/** + * Copyright 2019 Google Inc. All rights reserved. + * Modifications 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. + */ + +export const Events = { + Page: { + Close: 'close', + Console: 'console', + Dialog: 'dialog', + DOMContentLoaded: 'domcontentloaded', + // Can't use just 'error' due to node.js special treatment of error events. + // @see https://nodejs.org/api/events.html#events_error_events + PageError: 'pageerror', + Request: 'request', + Response: 'response', + RequestFailed: 'requestfailed', + RequestFinished: 'requestfinished', + FrameAttached: 'frameattached', + FrameDetached: 'framedetached', + FrameNavigated: 'framenavigated', + Load: 'load', + Popup: 'popup', + }, + + Browser: { + TargetCreated: 'targetcreated', + TargetDestroyed: 'targetdestroyed', + TargetChanged: 'targetchanged', + Disconnected: 'disconnected' + }, + + BrowserContext: { + TargetCreated: 'targetcreated', + TargetDestroyed: 'targetdestroyed', + TargetChanged: 'targetchanged', + } +}; diff --git a/src/webkit/Browser.ts b/src/webkit/Browser.ts index de6777544a..802fc2a8c9 100644 --- a/src/webkit/Browser.ts +++ b/src/webkit/Browser.ts @@ -18,7 +18,7 @@ import * as childProcess from 'child_process'; import { EventEmitter } from 'events'; import { Connection } from './Connection'; -import { Events } from '../Events'; +import { Events } from './events'; import { RegisteredListener, assert, helper } from '../helper'; import { Page, Viewport } from './Page'; import { Target } from './Target'; @@ -157,13 +157,6 @@ export class Browser extends EventEmitter { context = this._defaultContext; const target = new Target(targetInfo, context); this._targets.set(targetInfo.targetId, target); - if (target.opener() && target.opener()._pagePromise) { - const openerPage = await target.opener()._pagePromise; - if (openerPage.listenerCount(Events.Page.Popup)) { - const popupPage = await target.page(); - openerPage.emit(Events.Page.Popup, popupPage); - } - } this.emit(Events.Browser.TargetCreated, target); context.emit(Events.BrowserContext.TargetCreated, target); } diff --git a/src/webkit/FrameManager.ts b/src/webkit/FrameManager.ts index d170632e3a..a0ea701f17 100644 --- a/src/webkit/FrameManager.ts +++ b/src/webkit/FrameManager.ts @@ -17,7 +17,7 @@ import * as EventEmitter from 'events'; import * as fs from 'fs'; import { TimeoutError } from '../Errors'; -import { Events } from '../Events'; +import { Events } from './events'; import { assert, debugError, helper, RegisteredListener } from '../helper'; import { TimeoutSettings } from '../TimeoutSettings'; import { TargetSession } from './Connection'; diff --git a/src/webkit/Page.ts b/src/webkit/Page.ts index 76cfe18d63..139bfd9022 100644 --- a/src/webkit/Page.ts +++ b/src/webkit/Page.ts @@ -19,7 +19,7 @@ import { EventEmitter } from 'events'; import * as fs from 'fs'; import * as mime from 'mime'; import { TargetSession, TargetSessionEvents } from './Connection'; -import { Events } from '../Events'; +import { Events } from './events'; import { Frame, FrameManager, FrameManagerEvents } from './FrameManager'; import { assert, debugError, helper, RegisteredListener } from '../helper'; import { valueFromRemoteObject } from './protocolHelper'; diff --git a/src/webkit/Target.ts b/src/webkit/Target.ts index c40ab8edc0..b494198342 100644 --- a/src/webkit/Target.ts +++ b/src/webkit/Target.ts @@ -25,7 +25,6 @@ export class Target { _targetId: string; private _type: 'page' | 'service-worker' | 'worker'; _pagePromise: Promise | null = null; - private _openerId?: string; private _url: string; _initializedPromise: Promise; _initializedCallback: (value?: unknown) => void; @@ -34,7 +33,7 @@ export class Target { _isInitialized: boolean; _eventListeners: RegisteredListener[]; - constructor(targetInfo: Protocol.Target.TargetInfo, browserContext: BrowserContext, openerId?: string) { + constructor(targetInfo: Protocol.Target.TargetInfo, browserContext: BrowserContext) { const {targetId, url, type} = targetInfo; this._browserContext = browserContext; this._targetId = targetId; @@ -42,7 +41,6 @@ export class Target { /** @type {?Promise} */ this._pagePromise = null; this._url = url; - this._openerId = openerId; this._isClosedPromise = new Promise(fulfill => this._closedCallback = fulfill); if (type === 'page') { const session = this._browserContext.browser()._connection.session(this._targetId); @@ -88,8 +86,4 @@ export class Target { browserContext(): BrowserContext { return this._browserContext; } - - opener(): Target | null { - return this._openerId ? this.browser()._targets.get(this._openerId) : null; - } } diff --git a/src/webkit/api.ts b/src/webkit/api.ts new file mode 100644 index 0000000000..7d903cd64f --- /dev/null +++ b/src/webkit/api.ts @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +export { TimeoutError } from '../Errors'; +export { Browser, BrowserContext } from './Browser'; +export { BrowserFetcher } from './BrowserFetcher'; +export { ExecutionContext } from './ExecutionContext'; +export { Frame } from './FrameManager'; +export { Keyboard, Mouse } from './Input'; +export { ElementHandle, JSHandle } from './JSHandle'; +export { Request, Response } from './NetworkManager'; +export { ConsoleMessage, Page } from './Page'; +export { Playwright } from './Playwright'; diff --git a/src/webkit/events.ts b/src/webkit/events.ts new file mode 100644 index 0000000000..6185fe61f4 --- /dev/null +++ b/src/webkit/events.ts @@ -0,0 +1,44 @@ +/** + * Copyright 2019 Google Inc. All rights reserved. + * Modifications 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. + */ + +export const Events = { + Page: { + Close: 'close', + Console: 'console', + DOMContentLoaded: 'domcontentloaded', + Request: 'request', + Response: 'response', + RequestFailed: 'requestfailed', + RequestFinished: 'requestfinished', + FrameAttached: 'frameattached', + FrameDetached: 'framedetached', + FrameNavigated: 'framenavigated', + Load: 'load', + }, + + Browser: { + TargetCreated: 'targetcreated', + TargetDestroyed: 'targetdestroyed', + TargetChanged: 'targetchanged', + }, + + BrowserContext: { + TargetCreated: 'targetcreated', + TargetDestroyed: 'targetdestroyed', + TargetChanged: 'targetchanged', + }, +}; diff --git a/test/test.js b/test/test.js index c9491bdb85..99d9c1e1ff 100644 --- a/test/test.js +++ b/test/test.js @@ -100,7 +100,7 @@ if (process.env.BROWSER === 'firefox') { testRunner, }); if (process.env.COVERAGE) - utils.recordAPICoverage(testRunner, require('../lib/api').Chromium, require('../lib/Events').Events, CHROMIUM_NO_COVERAGE); + utils.recordAPICoverage(testRunner, require('../lib/api').Chromium, require('../lib/chromium/events').Events, CHROMIUM_NO_COVERAGE); }); } diff --git a/utils/doclint/check_public_api/JSBuilder.js b/utils/doclint/check_public_api/JSBuilder.js index d524fb3141..6ecf54d9bf 100644 --- a/utils/doclint/check_public_api/JSBuilder.js +++ b/utils/doclint/check_public_api/JSBuilder.js @@ -27,9 +27,9 @@ module.exports = checkSources; function checkSources(sources) { // special treatment for Events.js const classEvents = new Map(); - const eventsSource = sources.find(source => source.name().startsWith('Events.')); + const eventsSource = sources.find(source => source.name().startsWith('events.')); if (eventsSource) { - const {Events} = eventsSource.filePath().endsWith('.js') ? require(eventsSource.filePath()) : require(path.join(eventsSource.filePath(), '..', '..', 'lib', 'Events.js')); + const {Events} = eventsSource.filePath().endsWith('.js') ? require(eventsSource.filePath()) : require(path.join(eventsSource.filePath(), '..', '..', '..', 'lib', 'chromium', 'events.js')); for (const [className, events] of Object.entries(Events)) classEvents.set(className, Array.from(Object.values(events)).filter(e => typeof e === 'string').map(e => Documentation.Member.createEvent(e))); }