mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
chore: migrate src/Puppeteer to TypeScript (#5789)
* chore: migrate src/Puppeteer to TypeScript. * fix api js
This commit is contained in:
parent
209e25c0e1
commit
890c215142
2
index.js
2
index.js
@ -25,7 +25,7 @@ for (const className in api) {
|
||||
// Expose alias for deprecated method.
|
||||
Page.prototype.emulateMedia = Page.prototype.emulateMediaType;
|
||||
|
||||
const Puppeteer = require('./lib/Puppeteer');
|
||||
const {Puppeteer} = require('./lib/Puppeteer');
|
||||
const packageJson = require('./package.json');
|
||||
let preferredRevision = packageJson.puppeteer.chromium_revision;
|
||||
const isPuppeteerCore = packageJson.name === 'puppeteer-core';
|
||||
|
@ -20,18 +20,19 @@ import * as EventEmitter from 'events';
|
||||
import {TaskQueue} from './TaskQueue';
|
||||
import {Events} from './Events';
|
||||
import {Connection} from './Connection';
|
||||
import {ChildProcess} from 'child_process';
|
||||
|
||||
type BrowserCloseCallback = () => Promise<void> | void;
|
||||
|
||||
export class Browser extends EventEmitter {
|
||||
static async create(connection: Connection, contextIds: string[], ignoreHTTPSErrors: boolean, defaultViewport?: Puppeteer.Viewport, process?: Puppeteer.ChildProcess, closeCallback?: BrowserCloseCallback): Promise<Browser> {
|
||||
static async create(connection: Connection, contextIds: string[], ignoreHTTPSErrors: boolean, defaultViewport?: Puppeteer.Viewport, process?: ChildProcess, closeCallback?: BrowserCloseCallback): Promise<Browser> {
|
||||
const browser = new Browser(connection, contextIds, ignoreHTTPSErrors, defaultViewport, process, closeCallback);
|
||||
await connection.send('Target.setDiscoverTargets', {discover: true});
|
||||
return browser;
|
||||
}
|
||||
_ignoreHTTPSErrors: boolean;
|
||||
_defaultViewport?: Puppeteer.Viewport;
|
||||
_process?: Puppeteer.ChildProcess;
|
||||
_process?: ChildProcess;
|
||||
_screenshotTaskQueue = new TaskQueue();
|
||||
_connection: Connection;
|
||||
_closeCallback: BrowserCloseCallback;
|
||||
@ -40,7 +41,7 @@ export class Browser extends EventEmitter {
|
||||
// TODO: once Target is in TypeScript we can type this properly.
|
||||
_targets: Map<string, Target>;
|
||||
|
||||
constructor(connection: Connection, contextIds: string[], ignoreHTTPSErrors: boolean, defaultViewport?: Puppeteer.Viewport, process?: Puppeteer.ChildProcess, closeCallback?: BrowserCloseCallback) {
|
||||
constructor(connection: Connection, contextIds: string[], ignoreHTTPSErrors: boolean, defaultViewport?: Puppeteer.Viewport, process?: ChildProcess, closeCallback?: BrowserCloseCallback) {
|
||||
super();
|
||||
this._ignoreHTTPSErrors = ignoreHTTPSErrors;
|
||||
this._defaultViewport = defaultViewport;
|
||||
@ -61,7 +62,7 @@ export class Browser extends EventEmitter {
|
||||
this._connection.on('Target.targetInfoChanged', this._targetInfoChanged.bind(this));
|
||||
}
|
||||
|
||||
process(): Puppeteer.ChildProcess | null {
|
||||
process(): ChildProcess | null {
|
||||
return this._process;
|
||||
}
|
||||
|
||||
|
@ -99,10 +99,6 @@ function existsAsync(filePath: string): Promise<boolean> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} BrowserFetcher.Options
|
||||
*/
|
||||
|
||||
export interface BrowserFetcherOptions {
|
||||
platform?: Platform;
|
||||
product?: string;
|
||||
|
@ -882,7 +882,7 @@ const devices: Device[] = [
|
||||
}
|
||||
];
|
||||
|
||||
type DevicesMap = {
|
||||
export type DevicesMap = {
|
||||
[name: string]: Device;
|
||||
};
|
||||
|
||||
@ -891,5 +891,4 @@ const devicesMap: DevicesMap = {};
|
||||
for (const device of devices)
|
||||
devicesMap[device.name] = device;
|
||||
|
||||
|
||||
export = devicesMap;
|
||||
export {devicesMap};
|
||||
|
@ -23,3 +23,9 @@ class CustomError extends Error {
|
||||
}
|
||||
|
||||
export class TimeoutError extends CustomError {}
|
||||
|
||||
export type PuppeteerErrors = Record<string, typeof CustomError>;
|
||||
|
||||
export const puppeteerErrors: PuppeteerErrors = {
|
||||
TimeoutError,
|
||||
};
|
||||
|
@ -375,9 +375,6 @@ class ChromeLauncher implements ProductLauncher {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @implements {!Puppeteer.ProductLauncher}
|
||||
*/
|
||||
class FirefoxLauncher implements ProductLauncher {
|
||||
_projectRoot: string;
|
||||
_preferredRevision: string;
|
||||
@ -738,7 +735,7 @@ class FirefoxLauncher implements ProductLauncher {
|
||||
}
|
||||
|
||||
|
||||
function waitForWSEndpoint(browserProcess: Puppeteer.ChildProcess, timeout: number, preferredRevision: string): Promise<string> {
|
||||
function waitForWSEndpoint(browserProcess: childProcess.ChildProcess, timeout: number, preferredRevision: string): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const rl = readline.createInterface({input: browserProcess.stderr});
|
||||
let stderr = '';
|
||||
|
174
src/Puppeteer.js
174
src/Puppeteer.js
@ -1,174 +0,0 @@
|
||||
/**
|
||||
* Copyright 2017 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const {default: Launcher} = require('./Launcher');
|
||||
const {BrowserFetcher} = require('./BrowserFetcher');
|
||||
const Errors = require('./Errors');
|
||||
const DeviceDescriptors = require('./DeviceDescriptors');
|
||||
// Import used as typedef
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {Browser} = require('./Browser');
|
||||
const QueryHandler = require('./QueryHandler');
|
||||
|
||||
module.exports = class {
|
||||
/**
|
||||
* @param {string} projectRoot
|
||||
* @param {string} preferredRevision
|
||||
* @param {boolean} isPuppeteerCore
|
||||
* @param {string} productName
|
||||
*/
|
||||
constructor(projectRoot, preferredRevision, isPuppeteerCore, productName) {
|
||||
this._projectRoot = projectRoot;
|
||||
this._preferredRevision = preferredRevision;
|
||||
this._isPuppeteerCore = isPuppeteerCore;
|
||||
// track changes to Launcher configuration via options or environment variables
|
||||
this.__productName = productName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!(Puppeteer.LaunchOptions & Puppeteer.ChromeArgOptions & Puppeteer.BrowserOptions & {product?: string, extraPrefsFirefox?: !object})=} options
|
||||
* @return {!Promise<!Browser>}
|
||||
*/
|
||||
launch(options = {}) {
|
||||
if (options.product)
|
||||
this._productName = options.product;
|
||||
return this._launcher.launch(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!(Puppeteer.BrowserOptions & {browserWSEndpoint?: string, browserURL?: string, transport?: !Puppeteer.ConnectionTransport}) & {product?: string}=} options
|
||||
* @return {!Promise<!Browser>}
|
||||
*/
|
||||
connect(options) {
|
||||
if (options.product)
|
||||
this._productName = options.product;
|
||||
return this._launcher.connect(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
*/
|
||||
set _productName(name) {
|
||||
if (this.__productName !== name)
|
||||
this._changedProduct = true;
|
||||
this.__productName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
get _productName() {
|
||||
return this.__productName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
executablePath() {
|
||||
return this._launcher.executablePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Puppeteer.ProductLauncher}
|
||||
*/
|
||||
get _launcher() {
|
||||
if (!this._lazyLauncher || this._lazyLauncher.product !== this._productName || this._changedProduct) {
|
||||
// @ts-ignore
|
||||
const packageJson = require('../package.json');
|
||||
switch (this._productName) {
|
||||
case 'firefox':
|
||||
this._preferredRevision = packageJson.puppeteer.firefox_revision;
|
||||
break;
|
||||
case 'chrome':
|
||||
default:
|
||||
this._preferredRevision = packageJson.puppeteer.chromium_revision;
|
||||
}
|
||||
this._changedProduct = false;
|
||||
this._lazyLauncher = Launcher(this._projectRoot, this._preferredRevision, this._isPuppeteerCore, this._productName);
|
||||
}
|
||||
return this._lazyLauncher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
get product() {
|
||||
return this._launcher.product;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Object}
|
||||
*/
|
||||
get devices() {
|
||||
return DeviceDescriptors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Object}
|
||||
*/
|
||||
get errors() {
|
||||
return Errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Puppeteer.ChromeArgOptions=} options
|
||||
* @return {!Array<string>}
|
||||
*/
|
||||
defaultArgs(options) {
|
||||
return this._launcher.defaultArgs(options);
|
||||
}
|
||||
|
||||
/** TODO(jacktfranklin@): Once this file is TS we can type this
|
||||
* using the BrowserFectcherOptions interface.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} BrowserFetcherOptions
|
||||
* @property {('linux'|'mac'|'win32'|'win64')=} platform
|
||||
* @property {('chrome'|'firefox')=} product
|
||||
* @property {string=} path
|
||||
* @property {string=} host
|
||||
*/
|
||||
/**
|
||||
* @param {!BrowserFetcherOptions} options
|
||||
* @return {!BrowserFetcher}
|
||||
*/
|
||||
createBrowserFetcher(options) {
|
||||
return new BrowserFetcher(this._projectRoot, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {!Function} queryHandler
|
||||
*/
|
||||
__experimental_registerCustomQueryHandler(name, queryHandler) {
|
||||
QueryHandler.registerCustomQueryHandler(name, queryHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
*/
|
||||
__experimental_unregisterCustomQueryHandler(name) {
|
||||
QueryHandler.unregisterCustomQueryHandler(name);
|
||||
}
|
||||
|
||||
__experimental_customQueryHandlers() {
|
||||
return QueryHandler.customQueryHandlers();
|
||||
}
|
||||
|
||||
__experimental_clearQueryHandlers() {
|
||||
QueryHandler.clearQueryHandlers();
|
||||
}
|
||||
};
|
131
src/Puppeteer.ts
Normal file
131
src/Puppeteer.ts
Normal file
@ -0,0 +1,131 @@
|
||||
/**
|
||||
* Copyright 2017 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import Launcher from './Launcher';
|
||||
import type {LaunchOptions, ChromeArgOptions, BrowserOptions, ProductLauncher} from './Launcher';
|
||||
import {BrowserFetcher, BrowserFetcherOptions} from './BrowserFetcher';
|
||||
import {puppeteerErrors, PuppeteerErrors} from './Errors';
|
||||
|
||||
import {devicesMap} from './DeviceDescriptors';
|
||||
import type {DevicesMap} from './/DeviceDescriptors';
|
||||
import {Browser} from './Browser';
|
||||
import * as QueryHandler from './QueryHandler';
|
||||
|
||||
export class Puppeteer {
|
||||
_projectRoot: string;
|
||||
_preferredRevision: string;
|
||||
_isPuppeteerCore: boolean;
|
||||
_changedProduct = false;
|
||||
__productName: string;
|
||||
_lazyLauncher: ProductLauncher;
|
||||
|
||||
constructor(projectRoot: string, preferredRevision: string, isPuppeteerCore: boolean, productName: string) {
|
||||
this._projectRoot = projectRoot;
|
||||
this._preferredRevision = preferredRevision;
|
||||
this._isPuppeteerCore = isPuppeteerCore;
|
||||
// track changes to Launcher configuration via options or environment variables
|
||||
this.__productName = productName;
|
||||
}
|
||||
|
||||
launch(options: LaunchOptions & ChromeArgOptions & BrowserOptions & {product?: string; extraPrefsFirefox?: {}} = {}): Promise<Browser> {
|
||||
if (options.product)
|
||||
this._productName = options.product;
|
||||
return this._launcher.launch(options);
|
||||
}
|
||||
|
||||
connect(options: BrowserOptions & {
|
||||
browserWSEndpoint?: string;
|
||||
browserURL?: string;
|
||||
transport?: Puppeteer.ConnectionTransport;
|
||||
product?: string;
|
||||
}): Promise<Browser> {
|
||||
if (options.product)
|
||||
this._productName = options.product;
|
||||
return this._launcher.connect(options);
|
||||
}
|
||||
|
||||
set _productName(name: string) {
|
||||
if (this.__productName !== name)
|
||||
this._changedProduct = true;
|
||||
this.__productName = name;
|
||||
}
|
||||
|
||||
get _productName(): string {
|
||||
return this.__productName;
|
||||
}
|
||||
|
||||
executablePath(): string {
|
||||
return this._launcher.executablePath();
|
||||
}
|
||||
|
||||
get _launcher(): ProductLauncher {
|
||||
if (!this._lazyLauncher || this._lazyLauncher.product !== this._productName || this._changedProduct) {
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const packageJson = require('../package.json');
|
||||
switch (this._productName) {
|
||||
case 'firefox':
|
||||
this._preferredRevision = packageJson.puppeteer.firefox_revision;
|
||||
break;
|
||||
case 'chrome':
|
||||
default:
|
||||
this._preferredRevision = packageJson.puppeteer.chromium_revision;
|
||||
}
|
||||
this._changedProduct = false;
|
||||
this._lazyLauncher = Launcher(this._projectRoot, this._preferredRevision, this._isPuppeteerCore, this._productName);
|
||||
}
|
||||
return this._lazyLauncher;
|
||||
}
|
||||
|
||||
get product(): string {
|
||||
return this._launcher.product;
|
||||
}
|
||||
|
||||
get devices(): DevicesMap {
|
||||
return devicesMap;
|
||||
}
|
||||
|
||||
get errors(): PuppeteerErrors {
|
||||
return puppeteerErrors;
|
||||
}
|
||||
|
||||
defaultArgs(options: ChromeArgOptions): string[] {
|
||||
return this._launcher.defaultArgs(options);
|
||||
}
|
||||
|
||||
createBrowserFetcher(options: BrowserFetcherOptions): BrowserFetcher {
|
||||
return new BrowserFetcher(this._projectRoot, options);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/camelcase
|
||||
__experimental_registerCustomQueryHandler(name: string, queryHandler: QueryHandler.QueryHandler): void {
|
||||
QueryHandler.registerCustomQueryHandler(name, queryHandler);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/camelcase
|
||||
__experimental_unregisterCustomQueryHandler(name: string): void {
|
||||
QueryHandler.unregisterCustomQueryHandler(name);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/camelcase
|
||||
__experimental_customQueryHandlers(): Map<string, QueryHandler.QueryHandler> {
|
||||
return QueryHandler.customQueryHandlers();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/camelcase
|
||||
__experimental_clearQueryHandlers(): void {
|
||||
QueryHandler.clearQueryHandlers();
|
||||
}
|
||||
}
|
@ -31,7 +31,7 @@ module.exports = {
|
||||
Keyboard: require('./Input').Keyboard,
|
||||
Mouse: require('./Input').Mouse,
|
||||
Page: require('./Page').Page,
|
||||
Puppeteer: require('./Puppeteer'),
|
||||
Puppeteer: require('./Puppeteer').Puppeteer,
|
||||
Request: require('./NetworkManager').Request,
|
||||
Response: require('./NetworkManager').Response,
|
||||
SecurityDetails: require('./NetworkManager').SecurityDetails,
|
||||
|
42
src/externs.d.ts
vendored
42
src/externs.d.ts
vendored
@ -1,10 +1,9 @@
|
||||
import {Page as RealPage} from './Page.js';
|
||||
import * as child_process from 'child_process';
|
||||
|
||||
declare global {
|
||||
module Puppeteer {
|
||||
export class Page extends RealPage { }
|
||||
|
||||
|
||||
/* TODO(jacktfranklin@): once DOMWorld, Page, and FrameManager are in TS
|
||||
* we can remove this and instead use the type defined in LifeCycleWatcher
|
||||
*/
|
||||
@ -17,45 +16,6 @@ declare global {
|
||||
onclose?: () => void,
|
||||
}
|
||||
|
||||
/* TODO(jacktfranklin@): these are duplicated from Launcher.ts.
|
||||
* Once src/Puppeteer is migrated to TypeScript it can use those defs
|
||||
* and we can delete these.
|
||||
*/
|
||||
export interface ProductLauncher {
|
||||
launch(object)
|
||||
connect(object)
|
||||
executablePath: () => string,
|
||||
defaultArgs(object)
|
||||
product:string,
|
||||
}
|
||||
|
||||
export interface ChromeArgOptions {
|
||||
headless?: boolean;
|
||||
args?: string[];
|
||||
userDataDir?: string;
|
||||
devtools?: boolean;
|
||||
}
|
||||
|
||||
export interface LaunchOptions {
|
||||
executablePath?: string;
|
||||
ignoreDefaultArgs?: boolean | string[];
|
||||
handleSIGINT?: boolean;
|
||||
handleSIGTERM?: boolean;
|
||||
handleSIGHUP?: boolean;
|
||||
timeout?: number;
|
||||
dumpio?: boolean;
|
||||
env?: Record<string, string | undefined>;
|
||||
pipe?: boolean;
|
||||
}
|
||||
|
||||
export interface BrowserOptions {
|
||||
ignoreHTTPSErrors?: boolean;
|
||||
defaultViewport?: Puppeteer.Viewport;
|
||||
slowMo?: number;
|
||||
}
|
||||
|
||||
export interface ChildProcess extends child_process.ChildProcess { }
|
||||
|
||||
export type Viewport = {
|
||||
width: number;
|
||||
height: number;
|
||||
|
@ -496,8 +496,8 @@ describe('Launcher specs', function() {
|
||||
});
|
||||
it('should require top-level DeviceDescriptors', async() => {
|
||||
const {puppeteer, puppeteerPath} = getTestState();
|
||||
const Devices = require(path.join(puppeteerPath, '/DeviceDescriptors'));
|
||||
expect(Devices['iPhone 6']).toBe(puppeteer.devices['iPhone 6']);
|
||||
const {devicesMap} = require(path.join(puppeteerPath, '/DeviceDescriptors'));
|
||||
expect(devicesMap['iPhone 6']).toBe(puppeteer.devices['iPhone 6']);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -355,6 +355,10 @@ function compareDocumentations(actual, expected) {
|
||||
actualName: 'Array<string>',
|
||||
expectedName: 'Array<PermissionType>'
|
||||
}],
|
||||
['Method Puppeteer.createBrowserFetcher() options', {
|
||||
actualName: 'Object',
|
||||
expectedName: 'BrowserFetcherOptions'
|
||||
}],
|
||||
]);
|
||||
|
||||
const expectedForSource = expectedNamingMismatches.get(source);
|
||||
|
Loading…
Reference in New Issue
Block a user