UNPKG

@appium/types

Version:

Various type declarations used across Appium

486 lines (453 loc) 15.2 kB
import type {EventEmitter} from 'node:events'; import type {Merge} from 'type-fest'; import type {Capabilities, DriverCaps, W3CCapabilities} from './capabilities'; import type { BidiModuleMap, BiDiResultData, ExecuteMethodMap, MethodMap, } from './command-maps'; import type { DefaultCreateSessionResult, DefaultDeleteSessionResult, DriverData, EventHistory, IImplementedCommands, IWDClassicCommands, IAppiumCommands, IJSONWPCommands, IMJSONWPCommands, IOtherProtocolCommands, } from './commands'; import type {Constraints} from './constraints'; import type {ServerArgs} from './config'; import type {HTTPHeaders, HTTPMethod} from './http'; import type {AppiumLogger} from './logger'; import type {AppiumServer, UpdateServerCallback} from './server'; import type {Class, StringRecord} from './util'; import type internal from 'node:stream'; /** * Interface implemented by the `DeviceSettings` class in `@appium/base-driver` */ export interface IDeviceSettings<T extends StringRecord> { update(newSettings: T): Promise<void>; getSettings(): T; } export interface DriverHelpers { configureApp: ( app: string, supportedAppExtensions?: string | string[] | ConfigureAppOptions, ) => Promise<string>; isPackageOrBundle: (app: string) => boolean; duplicateKeys: <T>(input: T, firstKey: string, secondKey: string) => T; parseCapsArray: (cap: string | string[]) => string[]; generateDriverLogPrefix: (obj: object, sessionId?: string) => string; } export type SettingsUpdateListener<T extends Record<string, unknown> = Record<string, unknown>> = ( prop: keyof T, newValue: unknown, curValue: unknown, ) => Promise<void>; export type Protocol = 'MJSONWP' | 'W3C'; /** * Methods and properties which both `AppiumDriver` and `BaseDriver` inherit. * * This should not be used directly by external code. */ export interface Core<C extends Constraints, Settings extends StringRecord = StringRecord> { shouldValidateCaps: boolean; sessionId: string | null; sessionCreationTimestampMs: number; opts: DriverOpts<C>; initialOpts: InitialOpts; protocol?: Protocol; helpers: DriverHelpers; basePath: string; relaxedSecurityEnabled: boolean; allowInsecure: string[]; denyInsecure: string[]; newCommandTimeoutMs: number; implicitWaitMs: number; locatorStrategies: string[]; webLocatorStrategies: string[]; eventEmitter: EventEmitter; settings: IDeviceSettings<Settings>; log: AppiumLogger; driverData: DriverData; isCommandsQueueEnabled: boolean; eventHistory: EventHistory; bidiEventSubs: Record<string, string[]>; updateBidiCommands(cmds: BidiModuleMap): void; onUnexpectedShutdown(handler: () => any): void; /** * @summary Retrieve the server's current status. * @description * Returns information about whether a remote end is in a state in which it can create new sessions and can additionally include arbitrary meta information that is specific to the implementation. * * The readiness state is represented by the ready property of the body, which is false if an attempt to create a session at the current time would fail. However, the value true does not guarantee that a New Session command will succeed. * * Implementations may optionally include additional meta information as part of the body, but the top-level properties ready and message are reserved and must not be overwritten. * * @example * ```js * // webdriver.io example * await driver.status(); * ``` * * ```python * driver.get_status() * ``` * * ```java * driver.getStatus(); * ``` * * ```ruby * # ruby_lib example * remote_status * * # ruby_lib_core example * @driver.remote_status * ``` */ getStatus(): Promise<any>; sessionExists(sessionId?: string): boolean; isW3CProtocol(): boolean; isMjsonwpProtocol(): boolean; isFeatureEnabled(name: string): boolean; assertFeatureEnabled(name: string): void; validateLocatorStrategy(strategy: string, webContext?: boolean): void; proxyActive(sessionId?: string): boolean; get bidiProxyUrl(): string | null; getProxyAvoidList(sessionId?: string): RouteMatcher[]; canProxy(sessionId?: string): boolean; proxyRouteIsAvoided(sessionId: string, method: string, url: string, body?: any): boolean; addManagedDriver(driver: Driver): void; getManagedDrivers(): Driver<Constraints>[]; clearNewCommandTimeout(): Promise<void>; logEvent(eventName: string): void; driverForSession(sessionId: string): Core<Constraints> | null; } /** * `BaseDriver` implements this. It contains default behavior; * external drivers are expected to implement {@linkcode ExternalDriver} instead. * * `C` should be the constraints of the driver. * `CArgs` would be the shape of `cliArgs`. * `Settings` is the shape of the raw device settings object (see {@linkcode IDeviceSettings}) */ export interface Driver< C extends Constraints = Constraints, CArgs extends StringRecord = StringRecord, Settings extends StringRecord = StringRecord, CreateResult = DefaultCreateSessionResult<C>, DeleteResult = DefaultDeleteSessionResult, SessionData extends StringRecord = StringRecord, > extends IImplementedCommands<C, Settings, CreateResult, DeleteResult, SessionData>, Core<C, Settings> { /** * The set of command line arguments set for this driver */ cliArgs: CArgs; // The following properties are assigned by appium */ server?: AppiumServer; serverHost?: string; serverPort?: number; serverPath?: string; // The following methods are implemented by `BaseDriver`. /** * Execute a driver (WebDriver-protocol) command by its name as defined in the routes file * * @param cmd - the name of the command * @param args - arguments to pass to the command * * @returns The result of running the command */ executeCommand(cmd: string, ...args: any[]): Promise<any>; /** * A helper method to modify the command name before it's logged. * * Useful for resolving generic commands like 'execute' to a more specific * name based on arguments (e.g., identifying custom extensions). * * @param cmd - The original command name * @param args - Arguments passed to the command * @returns A potentially updated command name */ clarifyCommandName?(cmd: string, args: string[]): string; /** Execute a driver (WebDriver Bidi protocol) command by its name as defined in the bidi commands file * @param bidiCmd - the name of the command in the bidi spec * @param args - arguments to pass to the command */ executeBidiCommand(bidiCmd: string, ...args: any[]): Promise<BiDiResultData>; /** * Signify to any owning processes that this driver encountered an error which should cause the * session to terminate immediately (for example an upstream service failed) * * @param err - the Error object which is causing the shutdown */ startUnexpectedShutdown(err?: Error): Promise<void>; /** * Start the timer for the New Command Timeout, which when it runs out, will stop the current * session */ startNewCommandTimeout(): Promise<void>; /** * The processed capabilities used to start the session represented by the current driver instance */ caps?: Capabilities<C>; /** * The original capabilities used to start the session represented by the current driver instance */ originalCaps?: W3CCapabilities<C>; /** * The constraints object used to validate capabilities */ desiredCapConstraints: C; /** * Validate the capabilities used to start a session * * @param caps - the capabilities * * @internal * * @returns Whether or not the capabilities are valid */ validateDesiredCaps(caps: DriverCaps<C>): boolean; /** * A helper function to log unrecognized capabilities to the console * * @params caps - the capabilities * * @internal */ logExtraCaps(caps: DriverCaps<C>): void; /** * A helper function used to assign server information to the driver instance so the driver knows * where the server is Running * * @param server - the server object * @param host - the server hostname * @param port - the server port * @param path - the server base url */ assignServer?(server: AppiumServer, host: string, port: number, path: string): void; } /** * External drivers must subclass `BaseDriver`, and can implement any methods from this interface. * None of these methods are implemented within Appium itself. */ export interface ExternalDriver< C extends Constraints = Constraints, Ctx = string, CArgs extends StringRecord = StringRecord, Settings extends StringRecord = StringRecord, CreateResult = DefaultCreateSessionResult<C>, DeleteResult = DefaultDeleteSessionResult, SessionData extends StringRecord = StringRecord, > extends Driver<C, CArgs, Settings, CreateResult, DeleteResult, SessionData>, IWDClassicCommands, IAppiumCommands, IJSONWPCommands, IMJSONWPCommands<Ctx>, IOtherProtocolCommands { /** * Proxy a command to a connected WebDriver server * * @typeParam TReq - the type of the incoming body * @typeParam TRes - the type of the return value * @param url - the incoming URL * @param method - the incoming HTTP method * @param body - the incoming HTTP body * * @returns The return value of the proxied command */ proxyCommand?<TReq = any, TRes = unknown>( url: string, method: HTTPMethod, body?: TReq, ): Promise<TRes>; } /** * Static members of a {@linkcode DriverClass}. * * This is likely unusable by external consumers, but YMMV! */ export interface DriverStatic<T extends Driver> { baseVersion: string; updateServer?: UpdateServerCallback; newMethodMap?: MethodMap<T>; /** * Drivers can define new custom bidi commands and map them to driver methods. The format must * be the same as that used by Appium's bidi-commands.js file, for example: * @example * { * myNewBidiModule: { * myNewBidiCommand: { * command: 'driverMethodThatWillBeCalled', * params: { * required: ['requiredParam'], * optional: ['optionalParam'], * } * } * } * } */ newBidiCommands?: BidiModuleMap; executeMethodMap?: ExecuteMethodMap<T>; } /** * Represents a driver class, which is used internally by Appium. * * This is likely unusable by external consumers, but YMMV! */ export type DriverClass<T extends Driver = Driver> = Class< T, DriverStatic<T>, [] | [Partial<ServerArgs>] | [Partial<ServerArgs>, boolean] >; export interface ExtraDriverOpts { fastReset?: boolean; skipUninstall?: boolean; } /** * Options as set within {@linkcode ExternalDriver.createSession}, which is a union of {@linkcode InitialOpts} and {@linkcode DriverCaps}. */ export type DriverOpts<C extends Constraints> = InitialOpts & DriverCaps<C>; /** * Options as provided to the {@linkcode Driver} constructor. */ export type InitialOpts = Merge<ServerArgs, ExtraDriverOpts>; /** * An instance method of a driver class, whose name may be referenced by {@linkcode MethodDef.command}, and serves as an Appium command. * * Note that this signature differs from a `PluginCommand`. */ export type DriverCommand<TArgs extends readonly any[] = any[], TRetval = unknown> = ( ...args: TArgs ) => Promise<TRetval>; /** * Tuple of an HTTP method with a regex matching a request path */ export type RouteMatcher = [HTTPMethod, RegExp]; /** * Result of the {@linkcode onPostProcess ConfigureAppOptions.onPostProcess} callback. */ export interface PostProcessResult { /** * The full past to the post-processed application package on the local file system . * * This might be a file or a folder path. */ appPath: string; } /** * Information about a cached app instance. */ export interface CachedAppInfo { /** * SHA1 hash of the package if it is a file (and not a folder) */ packageHash: string; /** * Date instance; the value of the file's `Last-Modified` header */ lastModified?: Date|null; /** * The value of the file's `Etag` header */ etag?: string|null; /** * `true` if the file contains an `immutable` mark in `Cache-control` header */ immutable?: boolean; /** * Integer representation of `maxAge` parameter in `Cache-control` header */ maxAge?: number|null; /** * The timestamp this item has been added to the cache (measured in Unix epoch milliseconds) */ timestamp?: number; /** * An object containing either `file` property with SHA1 hash of the file or `folder` property * with total amount of cached files and subfolders */ integrity?: {file?: string} | {folder?: number}; /** * The full path to the cached app */ fullPath?: string; } /** * Options for the post-processing step * * The generic can be supplied if using `axios`, where `headers` is a fancy object. */ export interface PostProcessOptions<Headers = HTTPHeaders> { /** * The original application url or path */ originalAppLink: string; /** * The information about the previously cached app instance (if exists) */ cachedAppInfo?: CachedAppInfo; /** * Whether the app has been downloaded from a remote URL */ isUrl?: boolean; /** * Optional headers object. * * Only present if `isUrl` is `true` and if the server responds to `HEAD` requests. All header names are normalized to lowercase. */ headers?: Headers; /** * A string containing full path to the preprocessed application package (either downloaded or a local one) */ appPath?: string; } export interface DownloadAppOptions<Headers = HTTPHeaders> { /** * The original application url. */ url: string; /** * Response headers from the download url. */ headers: Headers; /** * Response stream. */ stream: internal.Readable; } export interface ConfigureAppOptions { /** * * Optional function, which should be applied to the application after it is * downloaded/preprocessed. * * This function may be async and is expected to accept single object parameter. The function is * expected to either return a falsy value, which means the app must not be cached and a fresh * copy of it is downloaded each time, _or_ if this function returns an object containing an * `appPath` property, then the integrity of it will be verified and stored into the cache. * @returns */ onPostProcess?: ( obj: PostProcessOptions, ) => Promise<PostProcessResult | undefined> | PostProcessResult | undefined; /** * Optional function, which should be applied to the application upon download * progress initialization instead of the standard download handler. * The callback does not get invoked if the original application is not a URL. * It is expected that `onPostProcess` is also provided if this callback is defined. * Otherwise, there is a possibility the app configuration flow could be broken. * * @returns The full path to the downloaded app */ onDownload?: ( obj: DownloadAppOptions, ) => Promise<string>; supportedExtensions: string[]; }