feat(types): make the template on BrowserType optional (#6142)

This makes it much nicer to use `BrowserType` because it no longer has a template.

Technically a breaking change because of the rare edge case where someone used their own non-browser type inside the template, but I don't consider that intended behavior and think this is fine.
This commit is contained in:
Joel Einbinder 2021-04-08 10:27:24 -07:00 committed by GitHub
parent 310692b101
commit 779355ad51
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 24 additions and 16 deletions

6
index.d.ts vendored
View file

@ -17,8 +17,8 @@
import * as types from './types/types'; import * as types from './types/types';
export * from './types/types'; export * from './types/types';
export const webkit: types.BrowserType<types.Browser>; export const webkit: types.BrowserType;
export const chromium: types.BrowserType<types.Browser>; export const chromium: types.BrowserType;
export const firefox: types.BrowserType<types.Browser>; export const firefox: types.BrowserType;
export const _electron: types.Electron; export const _electron: types.Electron;
export const _android: types.Android; export const _android: types.Android;

View file

@ -17,8 +17,8 @@
import * as types from './types/types'; import * as types from './types/types';
export * from './types/types'; export * from './types/types';
export const chromium: types.BrowserType<types.Browser>; export const chromium: types.BrowserType;
export const firefox: types.BrowserType<types.Browser>; export const firefox: types.BrowserType;
export const webkit: types.BrowserType<types.Browser>; export const webkit: types.BrowserType;
export const _electron: types.Electron; export const _electron: types.Electron;
export const _android: types.Android; export const _android: types.Android;

View file

@ -46,7 +46,7 @@ export interface BrowserServer extends api.BrowserServer {
kill(): Promise<void>; kill(): Promise<void>;
} }
export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel, channels.BrowserTypeInitializer> implements api.BrowserType<api.Browser> { export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel, channels.BrowserTypeInitializer> implements api.BrowserType {
private _timeoutSettings = new TimeoutSettings(); private _timeoutSettings = new TimeoutSettings();
_serverLauncher?: BrowserServerLauncher; _serverLauncher?: BrowserServerLauncher;

View file

@ -104,7 +104,7 @@ export class PlaywrightEnv implements Env<PlaywrightTestArgs> {
protected _options: LaunchOptions & TestOptions; protected _options: LaunchOptions & TestOptions;
protected _browserOptions: LaunchOptions; protected _browserOptions: LaunchOptions;
private _playwright: typeof import('../../index'); private _playwright: typeof import('../../index');
protected _browserType: BrowserType<Browser>; protected _browserType: BrowserType;
private _coverage: ReturnType<typeof installCoverageHooks> | undefined; private _coverage: ReturnType<typeof installCoverageHooks> | undefined;
private _userDataDirs: string[] = []; private _userDataDirs: string[] = [];
private _persistentContext: BrowserContext | undefined; private _persistentContext: BrowserContext | undefined;
@ -143,7 +143,7 @@ export class PlaywrightEnv implements Env<PlaywrightTestArgs> {
return dir; return dir;
} }
private async _launchPersistent(options?: Parameters<BrowserType<Browser>['launchPersistentContext']>[1]) { private async _launchPersistent(options?: Parameters<BrowserType['launchPersistentContext']>[1]) {
if (this._persistentContext) if (this._persistentContext)
throw new Error('can only launch one persitent context'); throw new Error('can only launch one persitent context');
const userDataDir = await this._createUserDataDir(); const userDataDir = await this._createUserDataDir();

View file

@ -15,17 +15,17 @@
*/ */
import { newTestType } from 'folio'; import { newTestType } from 'folio';
import type { Browser, BrowserType, LaunchOptions, BrowserContext, Page } from '../../index'; import type { BrowserType, LaunchOptions, BrowserContext, Page } from '../../index';
import { CommonTestArgs } from './pageTest'; import { CommonTestArgs } from './pageTest';
import type { ServerTestArgs } from './serverTest'; import type { ServerTestArgs } from './serverTest';
import { RemoteServer, RemoteServerOptions } from './remoteServer'; import { RemoteServer, RemoteServerOptions } from './remoteServer';
export { expect } from 'folio'; export { expect } from 'folio';
export type PlaywrightTestArgs = CommonTestArgs & { export type PlaywrightTestArgs = CommonTestArgs & {
browserType: BrowserType<Browser>; browserType: BrowserType;
browserOptions: LaunchOptions; browserOptions: LaunchOptions;
createUserDataDir: () => Promise<string>; createUserDataDir: () => Promise<string>;
launchPersistent: (options?: Parameters<BrowserType<Browser>['launchPersistentContext']>[1]) => Promise<{ context: BrowserContext, page: Page }>; launchPersistent: (options?: Parameters<BrowserType['launchPersistentContext']>[1]) => Promise<{ context: BrowserContext, page: Page }>;
startRemoteServer: (options?: RemoteServerOptions) => Promise<RemoteServer>; startRemoteServer: (options?: RemoteServerOptions) => Promise<RemoteServer>;
}; };

View file

@ -29,7 +29,7 @@ export type RemoteServerOptions = {
export class RemoteServer { export class RemoteServer {
_output: Map<any, any>; _output: Map<any, any>;
_outputCallback: Map<any, any>; _outputCallback: Map<any, any>;
_browserType: BrowserType<Browser>; _browserType: BrowserType;
_child: import('child_process').ChildProcess; _child: import('child_process').ChildProcess;
_exitPromise: Promise<unknown>; _exitPromise: Promise<unknown>;
_exitAndDisconnectPromise: Promise<any>; _exitAndDisconnectPromise: Promise<any>;
@ -37,7 +37,7 @@ export class RemoteServer {
_didExit: boolean; _didExit: boolean;
_wsEndpoint: string; _wsEndpoint: string;
async _start(browserType: BrowserType<Browser>, browserOptions: LaunchOptions, remoteServerOptions: RemoteServerOptions = {}) { async _start(browserType: BrowserType, browserOptions: LaunchOptions, remoteServerOptions: RemoteServerOptions = {}) {
this._output = new Map(); this._output = new Map();
this._outputCallback = new Map(); this._outputCallback = new Map();
this._didExit = false; this._didExit = false;

2
types/types.d.ts vendored
View file

@ -6459,7 +6459,7 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
* ``` * ```
* *
*/ */
export interface BrowserType<Browser> { export interface BrowserType<Unused = {}> {
/** /**
* This methods attaches Playwright to an existing browser instance. * This methods attaches Playwright to an existing browser instance.

View file

@ -140,7 +140,7 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
waitForSelector(selector: string, options: ElementHandleWaitForSelectorOptions): Promise<null|ElementHandle<SVGElement | HTMLElement>>; waitForSelector(selector: string, options: ElementHandleWaitForSelectorOptions): Promise<null|ElementHandle<SVGElement | HTMLElement>>;
} }
export interface BrowserType<Browser> { export interface BrowserType<Unused = {}> {
} }

View file

@ -799,6 +799,14 @@ playwright.chromium.launch().then(async browser => {
await browser.close(); await browser.close();
})(); })();
// for backwards compat, BrowserType is templated
(async () => {
const browserType = {} as playwright.BrowserType<playwright.Browser & {foo: 'string'}>;
const browser = await browserType.launch();
await browser.close();
})
// exported types // exported types
import { import {
LaunchOptions, LaunchOptions,