UNPKG

appium-remote-debugger

Version:
357 lines 15.9 kB
import { RemoteMessages } from './remote-messages'; import RpcMessageHandler from './rpc-message-handler'; import { EventEmitter } from 'node:events'; import AsyncLock from 'async-lock'; import type { StringRecord } from '@appium/types'; import type { AppIdKey, PageIdKey, TargetId, TargetInfo, ProvisionalTargetInfo, RemoteCommandOpts, RemoteCommand, RpcClientOptions } from '../types'; export declare const NEW_APP_CONNECTED_ERROR = "New application has connected"; export declare const EMPTY_PAGE_DICTIONARY_ERROR = "Empty page dictionary received"; /** * Details about a pending page target notification. */ interface PendingPageTargetDetails { appIdKey: AppIdKey; pageIdKey: PageIdKey; pageReadinessDetector?: PageReadinessDetector; } /** * Pages to targets mapping with optional provisional target info and lock. */ interface PagesToTargets { [key: string]: TargetId | ProvisionalTargetInfo | AsyncLock | undefined; provisional?: ProvisionalTargetInfo; lock: AsyncLock; } /** * Mapping of application IDs to their pages and targets. */ type AppToTargetsMap = Record<AppIdKey, PagesToTargets>; /** * Detector for determining when a page is ready. */ interface PageReadinessDetector { timeoutMs: number; readinessDetector: (readyState: string) => boolean; } /** * Base class for RPC clients that communicate with the Web Inspector. * Provides functionality for managing targets, sending commands, and handling * page initialization. Subclasses must implement device-specific connection logic. */ export declare class RpcClient { protected readonly messageHandler: RpcMessageHandler; protected readonly remoteMessages: RemoteMessages; protected connected: boolean; protected readonly isSafari: boolean; protected readonly connId: string; protected readonly senderId: string; protected msgId: number; protected readonly udid: string; protected readonly logAllCommunication?: boolean; protected readonly logAllCommunicationHexDump?: boolean; protected readonly socketChunkSize?: number; protected readonly webInspectorMaxFrameLength?: number; protected readonly fullPageInitialization?: boolean; protected readonly bundleId?: string; protected readonly pageLoadTimeoutMs?: number; protected readonly platformVersion: string; protected readonly _contexts: number[]; protected readonly _targets: AppToTargetsMap; protected readonly _targetSubscriptions: EventEmitter; protected _pendingTargetNotification?: PendingPageTargetDetails; protected readonly _targetCreationTimeoutMs: number; protected readonly _provisionedPages: Set<PageIdKey>; protected readonly _pageSelectionLock: AsyncLock; protected readonly _pageSelectionMonitor: EventEmitter; /** * @param opts - Options for configuring the RPC client. */ constructor(opts?: RpcClientOptions); /** * Gets the list of execution context IDs. * * @returns Array of execution context IDs. */ get contexts(): number[]; /** * Gets the mapping of applications to their pages and targets. * * @returns The targets mapping structure. */ get targets(): AppToTargetsMap; /** * Gets whether the client is currently connected. * * @returns True if connected, false otherwise. */ get isConnected(): boolean; /** * Sets the connection status. * * @param connected - The connection status to set. */ set isConnected(connected: boolean); /** * Gets the event emitter for target subscriptions. * * @returns The target subscriptions event emitter. */ get targetSubscriptions(): EventEmitter; /** * Registers an event listener on the message handler. * * Supported events include: * * **RPC-level events:** * - `_rpc_reportSetup:` - Emitted when the debugger setup is reported * - `_rpc_reportConnectedApplicationList:` - Emitted when the list of connected applications is reported * - `_rpc_forwardGetListing:` - Emitted when an application sends a page listing * - `_rpc_applicationConnected:` - Emitted when a new application connects * - `_rpc_applicationDisconnected:` - Emitted when an application disconnects * - `_rpc_applicationUpdated:` - Emitted when an application is updated * - `_rpc_reportConnectedDriverList:` - Emitted when the list of connected drivers is reported * - `_rpc_reportCurrentState:` - Emitted when the current state is reported * * **Target events:** * - `Target.targetCreated` - Emitted when a new target is created (args: error, appIdKey, targetInfo) * - `Target.targetDestroyed` - Emitted when a target is destroyed (args: error, appIdKey, targetInfo) * - `Target.didCommitProvisionalTarget` - Emitted when a provisional target commits (args: error, appIdKey, provisionalTargetInfo) * * **Page events:** * - `Page.frameStoppedLoading` - Emitted when a frame stops loading * - `Page.frameNavigated` - Emitted when a frame navigates * - `Page.frameDetached` - Emitted when a frame is detached * - `Page.loadEventFired` - Emitted when the page load event fires * * **Runtime events:** * - `Runtime.executionContextCreated` - Emitted when an execution context is created (args: error, context) * * **Console events:** * - `Console.messageAdded` - Emitted when a console message is added (args: error, message) * - `Console.messageRepeatCountUpdated` - Emitted when a console message repeat count is updated * - `ConsoleEvent` - Aggregate event for all Console.* events (args: error, params, methodName) * * **Network events:** * - `NetworkEvent` - Aggregate event for all Network.* events (args: error, params, methodName) * * **Timeline events:** * - `Timeline.eventRecorded` - Emitted when a timeline event is recorded (args: error, record) * * **Heap events:** * - `Heap.garbageCollected` - Emitted when garbage collection occurs * * **Message ID events:** * - Any numeric string (message ID) - Emitted for command responses (args: error, result) * * @param event - The event name to listen for. * @param listener - The listener function to call when the event is emitted. * The listener receives (error, ...args) where error may be null/undefined. * @returns This instance for method chaining. */ on(event: string, listener: (...args: any[]) => void): this; /** * Registers a one-time event listener on the message handler. * The listener will be automatically removed after being called once. * * See {@link RpcClient.on} for a list of supported events. * * @param event - The event name to listen for. * @param listener - The listener function to call when the event is emitted. * The listener receives (error, ...args) where error may be null/undefined. * @returns This instance for method chaining. */ once(event: string, listener: (...args: any[]) => void): this; /** * Removes an event listener from the message handler. * * See {@link RpcClient.on} for a list of supported events. * * @param event - The event name to stop listening for. * @param listener - The listener function to remove. * @returns This instance for method chaining. */ off(event: string, listener: (...args: any[]) => void): this; /** * Waits for a target to be created for the specified app and page. * If the target already exists, returns it immediately. Otherwise, * waits up to the configured timeout for the target to be created. * * @param appIdKey - The application identifier key. * @param pageIdKey - The page identifier key. * @returns A promise that resolves to the target ID if found, undefined otherwise. * @throws Error if no target is found after the timeout. */ waitForTarget(appIdKey: AppIdKey, pageIdKey: PageIdKey): Promise<TargetId | undefined>; /** * Sends a command to the remote debugger with automatic retry logic * for target-related errors. Handles cases where targets are not yet * available or not supported. * * @param command - The command name to send. * @param opts - Options for the command. * @param waitForResponse - Whether to wait for a response. Defaults to true. * @returns A promise that resolves to the command result or options. */ send(command: string, opts: RemoteCommandOpts, waitForResponse?: boolean): Promise<any>; /** * Sends a command directly to the device, handling message routing, * response waiting, and error handling. * * @template TWaitForResponse - Whether to wait for a response. * @param command - The command name to send. * @param opts - Options for the command. * @param waitForResponse - Whether to wait for a response. Defaults to true. * @returns A promise that resolves based on waitForResponse: * - If true: resolves to the response value * - If false: resolves to the full options object */ sendToDevice<TWaitForResponse extends boolean = true>(command: string, opts: RemoteCommandOpts, waitForResponse?: TWaitForResponse): Promise<TWaitForResponse extends true ? any : RemoteCommandOpts>; /** * Connects to the remote debugger. Must be implemented by subclasses. * * @throws Error indicating that subclasses must implement this method. */ connect(): Promise<void>; /** * Disconnects from the remote debugger and cleans up event listeners. */ disconnect(): Promise<void>; /** * Sends a message to the device. Must be implemented by subclasses. * * @param _command - The command to send. * @throws Error indicating that subclasses must implement this method. */ sendMessage(_command: RemoteCommand): Promise<void>; /** * Receives data from the device. Must be implemented by subclasses. * * @param _data - The data received from the device. * @throws Error indicating that subclasses must implement this method. */ receive(_data: any): Promise<void>; /** * Handles the creation of a new target for an application and page. * Initializes the page and waits for readiness if configured. * * @param err - Error if one occurred, undefined otherwise. * @param app - The application identifier key. * @param targetInfo - Information about the created target. */ addTarget(err: Error | undefined, app: AppIdKey, targetInfo: TargetInfo): Promise<void>; /** * Handles updates to provisional targets when they commit. * * @param err - Error if one occurred, undefined otherwise. * @param app - The application identifier key. * @param targetInfo - Information about the provisional target update. */ updateTarget(err: Error | undefined, app: AppIdKey, targetInfo: ProvisionalTargetInfo): Promise<void>; /** * Handles the destruction of a target, including cleanup of provisional targets. * * @param err - Error if one occurred, undefined otherwise. * @param app - The application identifier key. * @param targetInfo - Information about the destroyed target. */ removeTarget(err: Error | undefined, app: AppIdKey, targetInfo: TargetInfo): Promise<void>; /** * Gets the target ID for a specific app and page combination. * * @param appIdKey - The application identifier key. * @param pageIdKey - The page identifier key. * @returns The target ID if found, undefined otherwise. */ getTarget(appIdKey?: AppIdKey, pageIdKey?: PageIdKey): TargetId | undefined; /** * Selects a page within an application, setting up the Web Inspector session * and waiting for the page to be initialized. Mimics the steps that Desktop * Safari uses to initialize a Web Inspector session. * * @param appIdKey - The application identifier key. * @param pageIdKey - The page identifier key. * @param pageReadinessDetector - Optional detector for determining when the page is ready. */ selectPage(appIdKey: AppIdKey, pageIdKey: PageIdKey, pageReadinessDetector?: PageReadinessDetector): Promise<void>; /** * Initializes a page by enabling various Web Inspector domains. * Can perform either simple or full initialization based on configuration. * Mimics the steps that Desktop Safari Develop tools uses to initialize * a Web Inspector session. * * @param appIdKey - The application identifier key. * @param pageIdKey - The page identifier key. * @param targetId - Optional target ID. If not provided, will be retrieved from the targets map. * @returns A promise that resolves to true if initialization succeeded, false otherwise. */ private _initializePage; /** * Connects to a specific application and returns its page dictionary. * * @param appIdKey - The application identifier key to connect to. * @returns A promise that resolves to a tuple containing the connected app ID key * and the page dictionary. * @throws Error if a new application connects during the process or if the page * dictionary is empty. */ selectApp(appIdKey: AppIdKey): Promise<[string, StringRecord]>; /** * Handles execution context creation events by storing the context ID. * * @param err - Error if one occurred, undefined otherwise. * @param context - The execution context information. */ onExecutionContextCreated(err: Error | undefined, context: { id: number; }): void; /** * Handles garbage collection events by logging them. * Garbage collection can affect operation timing. */ onGarbageCollected(): void; /** * Handles script parsing events by logging script information. * * @param err - Error if one occurred, undefined otherwise. * @param scriptInfo - Information about the parsed script. */ onScriptParsed(err: Error | undefined, scriptInfo: StringRecord): void; /** * Resumes a paused target. * * @param appIdKey - The application identifier key. * @param pageIdKey - The page identifier key. * @param targetId - The target ID to resume. */ private _resumeTarget; /** * Waits for a page to be ready by periodically checking the document readyState. * Uses the provided readiness detector to determine when the page is ready. * * @param appIdKey - The application identifier key. * @param pageIdKey - The page identifier key. * @param targetId - The target ID. * @param pageReadinessDetector - The detector for determining page readiness. */ private _waitForPageReadiness; /** * Waits for a page to be initialized by acquiring locks on both the page * target lock and the page selection lock. * * @param appIdKey - The application identifier key. * @param pageIdKey - The page identifier key. * @throws Error if no targets are found for the application. */ waitForPage(appIdKey: AppIdKey, pageIdKey: PageIdKey): Promise<void>; /** * Gets the pending target details if there is a pending request for the given app. * Filters out non-page target types (e.g., 'frame'). * * @param appId - The application identifier key. * @param targetInfo - Information about the target. * @returns The pending page target details if there's a match, undefined otherwise. */ private _getPendingPageTargetDetails; } export {}; //# sourceMappingURL=rpc-client.d.ts.map