feat(types): simplify android and electron types (#4829)
These now follow the scheme for regular types.
This commit is contained in:
parent
34c1b338be
commit
905f28c339
|
|
@ -8,7 +8,6 @@ src/server/firefox/protocol.ts
|
||||||
src/server/webkit/protocol.ts
|
src/server/webkit/protocol.ts
|
||||||
/types/*
|
/types/*
|
||||||
/index.d.ts
|
/index.d.ts
|
||||||
/electron-types.d.ts
|
|
||||||
utils/generate_types/overrides.d.ts
|
utils/generate_types/overrides.d.ts
|
||||||
utils/generate_types/test/test.ts
|
utils/generate_types/test/test.ts
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
|
||||||
28
android-types.d.ts
vendored
28
android-types.d.ts
vendored
|
|
@ -1,28 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Page, BrowserContext, BrowserContextOptions } from './types/types';
|
|
||||||
import * as apiInternal from './android-types-internal';
|
|
||||||
import { EventEmitter } from 'events';
|
|
||||||
|
|
||||||
export { AndroidElementInfo, AndroidSelector } from './android-types-internal';
|
|
||||||
export type AndroidDevice = apiInternal.AndroidDevice<BrowserContextOptions, BrowserContext, Page>;
|
|
||||||
export type AndroidWebView = apiInternal.AndroidWebView<Page>;
|
|
||||||
|
|
||||||
export interface Android extends EventEmitter {
|
|
||||||
setDefaultTimeout(timeout: number): void;
|
|
||||||
devices(): Promise<AndroidDevice[]>;
|
|
||||||
}
|
|
||||||
|
|
@ -62,13 +62,13 @@ const PACKAGES = {
|
||||||
version: '0.4.0', // Manually manage playwright-electron version.
|
version: '0.4.0', // Manually manage playwright-electron version.
|
||||||
description: 'A high-level API to automate Electron',
|
description: 'A high-level API to automate Electron',
|
||||||
browsers: [],
|
browsers: [],
|
||||||
files: [...PLAYWRIGHT_CORE_FILES, ...FFMPEG_FILES, 'electron-types.d.ts'],
|
files: [...PLAYWRIGHT_CORE_FILES, ...FFMPEG_FILES],
|
||||||
},
|
},
|
||||||
'playwright-android': {
|
'playwright-android': {
|
||||||
version: '0.0.8', // Manually manage playwright-android version.
|
version: '0.0.8', // Manually manage playwright-android version.
|
||||||
description: 'A high-level API to automate Chrome for Android',
|
description: 'A high-level API to automate Chrome for Android',
|
||||||
browsers: [],
|
browsers: [],
|
||||||
files: [...PLAYWRIGHT_CORE_FILES, ...FFMPEG_FILES, 'android-types.d.ts', 'android-types-internal.d.ts', 'bin/android-driver.apk', 'bin/android-driver-target.apk'],
|
files: [...PLAYWRIGHT_CORE_FILES, ...FFMPEG_FILES, 'bin/android-driver.apk', 'bin/android-driver-target.apk'],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,6 @@ lib/server/injected/
|
||||||
# Include generated types and entrypoint.
|
# Include generated types and entrypoint.
|
||||||
!types/*
|
!types/*
|
||||||
!index.d.ts
|
!index.d.ts
|
||||||
# Include separate android types.
|
|
||||||
!android-types.d.ts
|
|
||||||
!android-types-internal.d.ts
|
|
||||||
# Include separate electron types.
|
|
||||||
!electron-types.d.ts
|
|
||||||
# Include main entrypoint.
|
# Include main entrypoint.
|
||||||
!index.js
|
!index.js
|
||||||
# Include main entrypoint for ES Modules.
|
# Include main entrypoint for ES Modules.
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ PLAYWRIGHT_CHROMIUM_TGZ="$(node ${PACKAGE_BUILDER} playwright-chromium ./playwri
|
||||||
PLAYWRIGHT_WEBKIT_TGZ="$(node ${PACKAGE_BUILDER} playwright-webkit ./playwright-webkit.tgz)"
|
PLAYWRIGHT_WEBKIT_TGZ="$(node ${PACKAGE_BUILDER} playwright-webkit ./playwright-webkit.tgz)"
|
||||||
PLAYWRIGHT_FIREFOX_TGZ="$(node ${PACKAGE_BUILDER} playwright-firefox ./playwright-firefox.tgz)"
|
PLAYWRIGHT_FIREFOX_TGZ="$(node ${PACKAGE_BUILDER} playwright-firefox ./playwright-firefox.tgz)"
|
||||||
PLAYWRIGHT_ELECTRON_TGZ="$(node ${PACKAGE_BUILDER} playwright-electron ./playwright-electron.tgz)"
|
PLAYWRIGHT_ELECTRON_TGZ="$(node ${PACKAGE_BUILDER} playwright-electron ./playwright-electron.tgz)"
|
||||||
|
PLAYWRIGHT_ANDROID_TGZ="$(node ${PACKAGE_BUILDER} playwright-android ./playwright-android.tgz)"
|
||||||
|
|
||||||
SCRIPTS_PATH="$(pwd -P)/.."
|
SCRIPTS_PATH="$(pwd -P)/.."
|
||||||
TEST_ROOT="$(pwd -P)"
|
TEST_ROOT="$(pwd -P)"
|
||||||
|
|
@ -52,6 +53,7 @@ function run_tests {
|
||||||
test_playwright_global_installation_cross_package
|
test_playwright_global_installation_cross_package
|
||||||
test_playwright_electron_should_work
|
test_playwright_electron_should_work
|
||||||
test_electron_types
|
test_electron_types
|
||||||
|
test_android_types
|
||||||
test_playwright_cli_should_work
|
test_playwright_cli_should_work
|
||||||
test_playwright_cli_install_should_work
|
test_playwright_cli_install_should_work
|
||||||
}
|
}
|
||||||
|
|
@ -316,6 +318,20 @@ function test_electron_types {
|
||||||
echo "${FUNCNAME[0]} success"
|
echo "${FUNCNAME[0]} success"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function test_android_types {
|
||||||
|
initialize_test "${FUNCNAME[0]}"
|
||||||
|
|
||||||
|
npm install ${PLAYWRIGHT_ANDROID_TGZ}
|
||||||
|
npm install -D typescript@3.8
|
||||||
|
npm install -D @types/node@10.17
|
||||||
|
echo "import { AndroidDevice, android, AndroidWebView, Page } from 'playwright-android';" > "test.ts"
|
||||||
|
|
||||||
|
echo "Running tsc"
|
||||||
|
npx tsc "test.ts"
|
||||||
|
|
||||||
|
echo "${FUNCNAME[0]} success"
|
||||||
|
}
|
||||||
|
|
||||||
function test_playwright_cli_should_work {
|
function test_playwright_cli_should_work {
|
||||||
initialize_test "${FUNCNAME[0]}"
|
initialize_test "${FUNCNAME[0]}"
|
||||||
|
|
||||||
|
|
|
||||||
4
packages/playwright-android/index.d.ts
vendored
4
packages/playwright-android/index.d.ts
vendored
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Android } from './android-types';
|
import { Android } from './types/android';
|
||||||
export * from './types/types';
|
export * from './types/types';
|
||||||
export * from './android-types';
|
export * from './types/android';
|
||||||
export const android: Android;
|
export const android: Android;
|
||||||
|
|
|
||||||
4
packages/playwright-electron/index.d.ts
vendored
4
packages/playwright-electron/index.d.ts
vendored
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ElectronLauncher } from './electron-types';
|
import { ElectronLauncher } from './types/electron';
|
||||||
export * from './types/types';
|
export * from './types/types';
|
||||||
export * from './electron-types';
|
export * from './types/electron';
|
||||||
export const electron: ElectronLauncher;
|
export const electron: ElectronLauncher;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import * as channels from '../protocol/channels';
|
||||||
import { Events } from './events';
|
import { Events } from './events';
|
||||||
import { BrowserContext, prepareBrowserContextOptions } from './browserContext';
|
import { BrowserContext, prepareBrowserContextOptions } from './browserContext';
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
import * as apiInternal from '../../android-types-internal';
|
import * as androidApi from '../../types/android';
|
||||||
import * as types from './types';
|
import * as types from './types';
|
||||||
import { Page } from './page';
|
import { Page } from './page';
|
||||||
import { TimeoutSettings } from '../utils/timeoutSettings';
|
import { TimeoutSettings } from '../utils/timeoutSettings';
|
||||||
|
|
@ -31,7 +31,7 @@ import { EventEmitter } from 'events';
|
||||||
type Direction = 'down' | 'up' | 'left' | 'right';
|
type Direction = 'down' | 'up' | 'left' | 'right';
|
||||||
type SpeedOptions = { speed?: number };
|
type SpeedOptions = { speed?: number };
|
||||||
|
|
||||||
export class Android extends ChannelOwner<channels.AndroidChannel, channels.AndroidInitializer> {
|
export class Android extends ChannelOwner<channels.AndroidChannel, channels.AndroidInitializer> implements androidApi.Android {
|
||||||
readonly _timeoutSettings: TimeoutSettings;
|
readonly _timeoutSettings: TimeoutSettings;
|
||||||
|
|
||||||
static from(android: channels.AndroidChannel): Android {
|
static from(android: channels.AndroidChannel): Android {
|
||||||
|
|
@ -56,7 +56,7 @@ export class Android extends ChannelOwner<channels.AndroidChannel, channels.Andr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AndroidDevice extends ChannelOwner<channels.AndroidDeviceChannel, channels.AndroidDeviceInitializer> implements apiInternal.AndroidDevice<types.BrowserContextOptions, BrowserContext, Page> {
|
export class AndroidDevice extends ChannelOwner<channels.AndroidDeviceChannel, channels.AndroidDeviceInitializer> implements androidApi.AndroidDevice {
|
||||||
readonly _timeoutSettings: TimeoutSettings;
|
readonly _timeoutSettings: TimeoutSettings;
|
||||||
private _webViews = new Map<number, AndroidWebView>();
|
private _webViews = new Map<number, AndroidWebView>();
|
||||||
|
|
||||||
|
|
@ -114,78 +114,78 @@ export class AndroidDevice extends ChannelOwner<channels.AndroidDeviceChannel, c
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async wait(selector: apiInternal.AndroidSelector, options?: { state?: 'gone' } & types.TimeoutOptions) {
|
async wait(selector: androidApi.AndroidSelector, options?: { state?: 'gone' } & types.TimeoutOptions) {
|
||||||
await this._wrapApiCall('androidDevice.wait', async () => {
|
await this._wrapApiCall('androidDevice.wait', async () => {
|
||||||
await this._channel.wait({ selector: toSelectorChannel(selector), ...options });
|
await this._channel.wait({ selector: toSelectorChannel(selector), ...options });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async fill(selector: apiInternal.AndroidSelector, text: string, options?: types.TimeoutOptions) {
|
async fill(selector: androidApi.AndroidSelector, text: string, options?: types.TimeoutOptions) {
|
||||||
await this._wrapApiCall('androidDevice.fill', async () => {
|
await this._wrapApiCall('androidDevice.fill', async () => {
|
||||||
await this._channel.fill({ selector: toSelectorChannel(selector), text, ...options });
|
await this._channel.fill({ selector: toSelectorChannel(selector), text, ...options });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async press(selector: apiInternal.AndroidSelector, key: apiInternal.AndroidKey, options?: types.TimeoutOptions) {
|
async press(selector: androidApi.AndroidSelector, key: androidApi.AndroidKey, options?: types.TimeoutOptions) {
|
||||||
await this.tap(selector, options);
|
await this.tap(selector, options);
|
||||||
await this.input.press(key);
|
await this.input.press(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
async tap(selector: apiInternal.AndroidSelector, options?: { duration?: number } & types.TimeoutOptions) {
|
async tap(selector: androidApi.AndroidSelector, options?: { duration?: number } & types.TimeoutOptions) {
|
||||||
await this._wrapApiCall('androidDevice.tap', async () => {
|
await this._wrapApiCall('androidDevice.tap', async () => {
|
||||||
await this._channel.tap({ selector: toSelectorChannel(selector), ...options });
|
await this._channel.tap({ selector: toSelectorChannel(selector), ...options });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async drag(selector: apiInternal.AndroidSelector, dest: types.Point, options?: SpeedOptions & types.TimeoutOptions) {
|
async drag(selector: androidApi.AndroidSelector, dest: types.Point, options?: SpeedOptions & types.TimeoutOptions) {
|
||||||
await this._wrapApiCall('androidDevice.drag', async () => {
|
await this._wrapApiCall('androidDevice.drag', async () => {
|
||||||
await this._channel.drag({ selector: toSelectorChannel(selector), dest, ...options });
|
await this._channel.drag({ selector: toSelectorChannel(selector), dest, ...options });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async fling(selector: apiInternal.AndroidSelector, direction: Direction, options?: SpeedOptions & types.TimeoutOptions) {
|
async fling(selector: androidApi.AndroidSelector, direction: Direction, options?: SpeedOptions & types.TimeoutOptions) {
|
||||||
await this._wrapApiCall('androidDevice.fling', async () => {
|
await this._wrapApiCall('androidDevice.fling', async () => {
|
||||||
await this._channel.fling({ selector: toSelectorChannel(selector), direction, ...options });
|
await this._channel.fling({ selector: toSelectorChannel(selector), direction, ...options });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async longTap(selector: apiInternal.AndroidSelector, options?: types.TimeoutOptions) {
|
async longTap(selector: androidApi.AndroidSelector, options?: types.TimeoutOptions) {
|
||||||
await this._wrapApiCall('androidDevice.longTap', async () => {
|
await this._wrapApiCall('androidDevice.longTap', async () => {
|
||||||
await this._channel.longTap({ selector: toSelectorChannel(selector), ...options });
|
await this._channel.longTap({ selector: toSelectorChannel(selector), ...options });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async pinchClose(selector: apiInternal.AndroidSelector, percent: number, options?: SpeedOptions & types.TimeoutOptions) {
|
async pinchClose(selector: androidApi.AndroidSelector, percent: number, options?: SpeedOptions & types.TimeoutOptions) {
|
||||||
await this._wrapApiCall('androidDevice.pinchClose', async () => {
|
await this._wrapApiCall('androidDevice.pinchClose', async () => {
|
||||||
await this._channel.pinchClose({ selector: toSelectorChannel(selector), percent, ...options });
|
await this._channel.pinchClose({ selector: toSelectorChannel(selector), percent, ...options });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async pinchOpen(selector: apiInternal.AndroidSelector, percent: number, options?: SpeedOptions & types.TimeoutOptions) {
|
async pinchOpen(selector: androidApi.AndroidSelector, percent: number, options?: SpeedOptions & types.TimeoutOptions) {
|
||||||
await this._wrapApiCall('androidDevice.pinchOpen', async () => {
|
await this._wrapApiCall('androidDevice.pinchOpen', async () => {
|
||||||
await this._channel.pinchOpen({ selector: toSelectorChannel(selector), percent, ...options });
|
await this._channel.pinchOpen({ selector: toSelectorChannel(selector), percent, ...options });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async scroll(selector: apiInternal.AndroidSelector, direction: Direction, percent: number, options?: SpeedOptions & types.TimeoutOptions) {
|
async scroll(selector: androidApi.AndroidSelector, direction: Direction, percent: number, options?: SpeedOptions & types.TimeoutOptions) {
|
||||||
await this._wrapApiCall('androidDevice.scroll', async () => {
|
await this._wrapApiCall('androidDevice.scroll', async () => {
|
||||||
await this._channel.scroll({ selector: toSelectorChannel(selector), direction, percent, ...options });
|
await this._channel.scroll({ selector: toSelectorChannel(selector), direction, percent, ...options });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async swipe(selector: apiInternal.AndroidSelector, direction: Direction, percent: number, options?: SpeedOptions & types.TimeoutOptions) {
|
async swipe(selector: androidApi.AndroidSelector, direction: Direction, percent: number, options?: SpeedOptions & types.TimeoutOptions) {
|
||||||
await this._wrapApiCall('androidDevice.swipe', async () => {
|
await this._wrapApiCall('androidDevice.swipe', async () => {
|
||||||
await this._channel.swipe({ selector: toSelectorChannel(selector), direction, percent, ...options });
|
await this._channel.swipe({ selector: toSelectorChannel(selector), direction, percent, ...options });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async info(selector: apiInternal.AndroidSelector): Promise<apiInternal.AndroidElementInfo> {
|
async info(selector: androidApi.AndroidSelector): Promise<androidApi.AndroidElementInfo> {
|
||||||
return await this._wrapApiCall('androidDevice.info', async () => {
|
return await this._wrapApiCall('androidDevice.info', async () => {
|
||||||
return (await this._channel.info({ selector: toSelectorChannel(selector) })).info;
|
return (await this._channel.info({ selector: toSelectorChannel(selector) })).info;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async tree(): Promise<apiInternal.AndroidElementInfo> {
|
async tree(): Promise<androidApi.AndroidElementInfo> {
|
||||||
return await this._wrapApiCall('androidDevice.tree', async () => {
|
return await this._wrapApiCall('androidDevice.tree', async () => {
|
||||||
return (await this._channel.tree()).tree;
|
return (await this._channel.tree()).tree;
|
||||||
});
|
});
|
||||||
|
|
@ -254,7 +254,7 @@ export class AndroidDevice extends ChannelOwner<channels.AndroidDeviceChannel, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AndroidSocket extends ChannelOwner<channels.AndroidSocketChannel, channels.AndroidSocketInitializer> {
|
export class AndroidSocket extends ChannelOwner<channels.AndroidSocketChannel, channels.AndroidSocketInitializer> implements androidApi.AndroidSocket {
|
||||||
static from(androidDevice: channels.AndroidSocketChannel): AndroidSocket {
|
static from(androidDevice: channels.AndroidSocketChannel): AndroidSocket {
|
||||||
return (androidDevice as any)._object;
|
return (androidDevice as any)._object;
|
||||||
}
|
}
|
||||||
|
|
@ -284,7 +284,7 @@ async function loadFile(file: string | Buffer): Promise<string> {
|
||||||
return file.toString('base64');
|
return file.toString('base64');
|
||||||
}
|
}
|
||||||
|
|
||||||
class Input implements apiInternal.AndroidInput {
|
class Input implements androidApi.AndroidInput {
|
||||||
private _device: AndroidDevice;
|
private _device: AndroidDevice;
|
||||||
|
|
||||||
constructor(device: AndroidDevice) {
|
constructor(device: AndroidDevice) {
|
||||||
|
|
@ -297,7 +297,7 @@ class Input implements apiInternal.AndroidInput {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async press(key: apiInternal.AndroidKey) {
|
async press(key: androidApi.AndroidKey) {
|
||||||
return this._device._wrapApiCall('androidDevice.inputPress', async () => {
|
return this._device._wrapApiCall('androidDevice.inputPress', async () => {
|
||||||
await this._device._channel.inputPress({ key });
|
await this._device._channel.inputPress({ key });
|
||||||
});
|
});
|
||||||
|
|
@ -322,7 +322,7 @@ class Input implements apiInternal.AndroidInput {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toSelectorChannel(selector: apiInternal.AndroidSelector): channels.AndroidSelector {
|
function toSelectorChannel(selector: androidApi.AndroidSelector): channels.AndroidSelector {
|
||||||
const {
|
const {
|
||||||
checkable,
|
checkable,
|
||||||
checked,
|
checked,
|
||||||
|
|
@ -372,7 +372,7 @@ function toSelectorChannel(selector: apiInternal.AndroidSelector): channels.Andr
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AndroidWebView extends EventEmitter {
|
export class AndroidWebView extends EventEmitter implements androidApi.AndroidWebView {
|
||||||
private _device: AndroidDevice;
|
private _device: AndroidDevice;
|
||||||
private _data: channels.AndroidWebView;
|
private _data: channels.AndroidWebView;
|
||||||
private _pagePromise: Promise<Page> | undefined;
|
private _pagePromise: Promise<Page> | undefined;
|
||||||
|
|
|
||||||
|
|
@ -24,14 +24,18 @@ import { Waiter } from './waiter';
|
||||||
import { Events } from './events';
|
import { Events } from './events';
|
||||||
import { WaitForEventOptions, Env, Logger } from './types';
|
import { WaitForEventOptions, Env, Logger } from './types';
|
||||||
import { envObjectToArray } from './clientHelper';
|
import { envObjectToArray } from './clientHelper';
|
||||||
|
import * as electronApi from '../../types/electron';
|
||||||
import * as structs from '../../types/structs';
|
import * as structs from '../../types/structs';
|
||||||
|
import type { ChromiumBrowserContext } from './chromiumBrowserContext';
|
||||||
|
|
||||||
type ElectronOptions = Omit<channels.ElectronLaunchOptions, 'env'> & {
|
type ElectronOptions = Omit<channels.ElectronLaunchOptions, 'env'> & {
|
||||||
env?: Env,
|
env?: Env,
|
||||||
logger?: Logger,
|
logger?: Logger,
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Electron extends ChannelOwner<channels.ElectronChannel, channels.ElectronInitializer> {
|
type ElectronAppType = typeof import('electron');
|
||||||
|
|
||||||
|
export class Electron extends ChannelOwner<channels.ElectronChannel, channels.ElectronInitializer> implements electronApi.ElectronLauncher {
|
||||||
static from(electron: channels.ElectronChannel): Electron {
|
static from(electron: channels.ElectronChannel): Electron {
|
||||||
return (electron as any)._object;
|
return (electron as any)._object;
|
||||||
}
|
}
|
||||||
|
|
@ -54,7 +58,7 @@ export class Electron extends ChannelOwner<channels.ElectronChannel, channels.El
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ElectronApplication extends ChannelOwner<channels.ElectronApplicationChannel, channels.ElectronApplicationInitializer> {
|
export class ElectronApplication extends ChannelOwner<channels.ElectronApplicationChannel, channels.ElectronApplicationInitializer> implements electronApi.ElectronApplication {
|
||||||
private _context?: BrowserContext;
|
private _context?: BrowserContext;
|
||||||
private _windows = new Set<Page>();
|
private _windows = new Set<Page>();
|
||||||
private _timeoutSettings = new TimeoutSettings();
|
private _timeoutSettings = new TimeoutSettings();
|
||||||
|
|
@ -76,23 +80,24 @@ export class ElectronApplication extends ChannelOwner<channels.ElectronApplicati
|
||||||
this._channel.on('close', () => this.emit(Events.ElectronApplication.Close));
|
this._channel.on('close', () => this.emit(Events.ElectronApplication.Close));
|
||||||
}
|
}
|
||||||
|
|
||||||
windows(): Page[] {
|
windows(): electronApi.ElectronPage[] {
|
||||||
return [...this._windows];
|
// TODO: add ElectronPage class inherting from Page.
|
||||||
|
return [...this._windows] as any as electronApi.ElectronPage[];
|
||||||
}
|
}
|
||||||
|
|
||||||
async firstWindow(): Promise<Page> {
|
async firstWindow(): Promise<electronApi.ElectronPage> {
|
||||||
if (this._windows.size)
|
if (this._windows.size)
|
||||||
return this._windows.values().next().value;
|
return this._windows.values().next().value;
|
||||||
return this.waitForEvent('window');
|
return this.waitForEvent('window');
|
||||||
}
|
}
|
||||||
|
|
||||||
async newBrowserWindow(options: any): Promise<Page> {
|
async newBrowserWindow(options: any): Promise<electronApi.ElectronPage> {
|
||||||
const result = await this._channel.newBrowserWindow({ arg: serializeArgument(options) });
|
const result = await this._channel.newBrowserWindow({ arg: serializeArgument(options) });
|
||||||
return Page.from(result.page);
|
return Page.from(result.page) as any as electronApi.ElectronPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
context(): BrowserContext {
|
context(): ChromiumBrowserContext {
|
||||||
return this._context!;
|
return this._context! as ChromiumBrowserContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
async close() {
|
async close() {
|
||||||
|
|
@ -111,12 +116,12 @@ export class ElectronApplication extends ChannelOwner<channels.ElectronApplicati
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async evaluate<R, Arg>(pageFunction: structs.PageFunctionOn<any, Arg, R>, arg: Arg): Promise<R> {
|
async evaluate<R, Arg>(pageFunction: structs.PageFunctionOn<ElectronAppType, Arg, R>, arg: Arg): Promise<R> {
|
||||||
const result = await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
|
const result = await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
|
||||||
return parseResult(result.value);
|
return parseResult(result.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
async evaluateHandle<R, Arg>(pageFunction: structs.PageFunctionOn<any, Arg, R>, arg: Arg): Promise<structs.SmartHandle<R>> {
|
async evaluateHandle<R, Arg>(pageFunction: structs.PageFunctionOn<ElectronAppType, Arg, R>, arg: Arg): Promise<structs.SmartHandle<R>> {
|
||||||
const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
|
const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) });
|
||||||
return JSHandle.from(result.handle) as any as structs.SmartHandle<R>;
|
return JSHandle.from(result.handle) as any as structs.SmartHandle<R>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Android, AndroidDevice } from '../../android-types';
|
import type { Android, AndroidDevice } from '../../types/android';
|
||||||
import { folio as baseFolio } from '../fixtures';
|
import { folio as baseFolio } from '../fixtures';
|
||||||
|
|
||||||
const fixtures = baseFolio.extend<{
|
const fixtures = baseFolio.extend<{
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { folio as base } from '../fixtures';
|
import { folio as base } from '../fixtures';
|
||||||
import type { ElectronApplication, ElectronPage } from '../../electron-types';
|
import type { ElectronApplication, ElectronPage } from '../../types/electron';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
const electronName = process.platform === 'win32' ? 'electron.cmd' : 'electron';
|
const electronName = process.platform === 'win32' ? 'electron.cmd' : 'electron';
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,8 @@ import { installCoverageHooks } from './coverage';
|
||||||
import { folio as httpFolio } from './http.fixtures';
|
import { folio as httpFolio } from './http.fixtures';
|
||||||
import { folio as playwrightFolio } from './playwright.fixtures';
|
import { folio as playwrightFolio } from './playwright.fixtures';
|
||||||
import { PlaywrightClient } from '../lib/remote/playwrightClient';
|
import { PlaywrightClient } from '../lib/remote/playwrightClient';
|
||||||
import type { Android } from '../android-types';
|
import type { Android } from '../types/android';
|
||||||
import type { ElectronLauncher } from '../electron-types';
|
import type { ElectronLauncher } from '../types/electron';
|
||||||
export { expect, config } from 'folio';
|
export { expect, config } from 'folio';
|
||||||
|
|
||||||
const removeFolderAsync = util.promisify(require('rimraf'));
|
const removeFolderAsync = util.promisify(require('rimraf'));
|
||||||
|
|
|
||||||
20
android-types-internal.d.ts → types/android.d.ts
vendored
20
android-types-internal.d.ts → types/android.d.ts
vendored
|
|
@ -15,18 +15,24 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
|
import { BrowserContextOptions, BrowserContext, Page } from './types';
|
||||||
|
|
||||||
export interface AndroidDevice<BrowserContextOptions, BrowserContext, Page> extends EventEmitter {
|
export interface Android extends EventEmitter {
|
||||||
|
setDefaultTimeout(timeout: number): void;
|
||||||
|
devices(): Promise<AndroidDevice[]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AndroidDevice extends EventEmitter {
|
||||||
input: AndroidInput;
|
input: AndroidInput;
|
||||||
|
|
||||||
setDefaultTimeout(timeout: number): void;
|
setDefaultTimeout(timeout: number): void;
|
||||||
on(event: 'webview', handler: (webView: AndroidWebView<Page>) => void): this;
|
on(event: 'webview', handler: (webView: AndroidWebView) => void): this;
|
||||||
waitForEvent(event: string, optionsOrPredicate?: (data: any) => boolean | { timeout?: number, predicate?: (data: any) => boolean }): Promise<any>;
|
waitForEvent(event: string, optionsOrPredicate?: (data: any) => boolean | { timeout?: number, predicate?: (data: any) => boolean }): Promise<any>;
|
||||||
|
|
||||||
serial(): string;
|
serial(): string;
|
||||||
model(): string;
|
model(): string;
|
||||||
webViews(): AndroidWebView<Page>[];
|
webViews(): AndroidWebView[];
|
||||||
webView(selector: { pkg: string }, options?: { timeout?: number }): Promise<AndroidWebView<Page>>;
|
webView(selector: { pkg: string }, options?: { timeout?: number }): Promise<AndroidWebView>;
|
||||||
shell(command: string): Promise<Buffer>;
|
shell(command: string): Promise<Buffer>;
|
||||||
open(command: string): Promise<AndroidSocket>;
|
open(command: string): Promise<AndroidSocket>;
|
||||||
installApk(file: string | Buffer, options?: { args?: string[] }): Promise<void>;
|
installApk(file: string | Buffer, options?: { args?: string[] }): Promise<void>;
|
||||||
|
|
@ -53,8 +59,8 @@ export interface AndroidDevice<BrowserContextOptions, BrowserContext, Page> exte
|
||||||
export interface AndroidSocket extends EventEmitter {
|
export interface AndroidSocket extends EventEmitter {
|
||||||
on(event: 'data', handler: (data: Buffer) => void): this;
|
on(event: 'data', handler: (data: Buffer) => void): this;
|
||||||
on(event: 'close', handler: () => void): this;
|
on(event: 'close', handler: () => void): this;
|
||||||
write(data: Buffer): Promise<void>
|
write(data: Buffer): Promise<void>;
|
||||||
close(): Promise<void>
|
close(): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AndroidInput {
|
export interface AndroidInput {
|
||||||
|
|
@ -65,7 +71,7 @@ export interface AndroidInput {
|
||||||
drag(from: { x: number, y: number }, to: { x: number, y: number }, steps: number): Promise<void>;
|
drag(from: { x: number, y: number }, to: { x: number, y: number }, steps: number): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AndroidWebView<Page> extends EventEmitter {
|
export interface AndroidWebView extends EventEmitter {
|
||||||
on(event: 'close', handler: () => void): this;
|
on(event: 'close', handler: () => void): this;
|
||||||
pid(): number;
|
pid(): number;
|
||||||
pkg(): string;
|
pkg(): string;
|
||||||
11
electron-types.d.ts → types/electron.d.ts
vendored
11
electron-types.d.ts → types/electron.d.ts
vendored
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Logger, Page, JSHandle, ChromiumBrowserContext } from './types/types';
|
import { Logger, Page, JSHandle, ChromiumBrowserContext } from './types';
|
||||||
import { BrowserWindow, BrowserWindowConstructorOptions } from 'electron';
|
import { BrowserWindow, BrowserWindowConstructorOptions } from 'electron';
|
||||||
|
|
||||||
export type ElectronLaunchOptions = {
|
export type ElectronLaunchOptions = {
|
||||||
|
|
@ -27,9 +27,11 @@ export type ElectronLaunchOptions = {
|
||||||
timeout?: number,
|
timeout?: number,
|
||||||
logger?: Logger,
|
logger?: Logger,
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface ElectronLauncher {
|
export interface ElectronLauncher {
|
||||||
launch(executablePath: string, options?: ElectronLaunchOptions): Promise<ElectronApplication>;
|
launch(executablePath: string, options?: ElectronLaunchOptions): Promise<ElectronApplication>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ElectronApplication {
|
export interface ElectronApplication {
|
||||||
on(event: 'window', listener: (page : ElectronPage) => void): this;
|
on(event: 'window', listener: (page : ElectronPage) => void): this;
|
||||||
addListener(event: 'window', listener: (page : ElectronPage) => void): this;
|
addListener(event: 'window', listener: (page : ElectronPage) => void): this;
|
||||||
|
|
@ -44,9 +46,12 @@ export interface ElectronApplication {
|
||||||
firstWindow(): Promise<ElectronPage>;
|
firstWindow(): Promise<ElectronPage>;
|
||||||
newBrowserWindow(options?: BrowserWindowConstructorOptions): Promise<ElectronPage>;
|
newBrowserWindow(options?: BrowserWindowConstructorOptions): Promise<ElectronPage>;
|
||||||
close(): Promise<void>;
|
close(): Promise<void>;
|
||||||
evaluate: JSHandle<typeof import('electron')>['evaluate'];
|
evaluate: HandleToElectron['evaluate'];
|
||||||
evaluateHandle: JSHandle<typeof import('electron')>['evaluateHandle'];
|
evaluateHandle: HandleToElectron['evaluateHandle'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ElectronPage extends Page {
|
export interface ElectronPage extends Page {
|
||||||
browserWindow: JSHandle<BrowserWindow>;
|
browserWindow: JSHandle<BrowserWindow>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type HandleToElectron = JSHandle<typeof import('electron')>;
|
||||||
|
|
@ -99,7 +99,7 @@ function checkSources(sources) {
|
||||||
parent = parent.parent;
|
parent = parent.parent;
|
||||||
className = path.basename(parent.fileName, '.js');
|
className = path.basename(parent.fileName, '.js');
|
||||||
}
|
}
|
||||||
if (className && !excludeClasses.has(className) && !fileName.endsWith('/protocol.ts') && !fileName.endsWith('/protocol.d.ts') && !fileName.endsWith('/types.d.ts')) {
|
if (className && !excludeClasses.has(className) && !fileName.endsWith('/protocol.ts') && !fileName.endsWith('/protocol.d.ts') && !fileName.endsWith('/types.d.ts') && !fileName.endsWith('node_modules/electron/electron.d.ts')) {
|
||||||
excludeClasses.add(className);
|
excludeClasses.add(className);
|
||||||
classes.push(serializeClass(className, symbol, node));
|
classes.push(serializeClass(className, symbol, node));
|
||||||
inheritance.set(className, parentClasses(node));
|
inheritance.set(className, parentClasses(node));
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue