appium-remote-debugger
Version:
Appium proxy for Remote Debugger protocol
357 lines • 15.9 kB
TypeScript
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