/** * Interaction Recorder * * Records user interactions (mouse, keyboard, navigation) from a browser page * for later replay or conversion to test scripts. * * Actions: * - recordInteraction: Start recording * - stopInteraction: Stop recording, keep in memory * - replayInteraction: Get recorded events by index * - clearInteraction: Clear recording from memory */ import type { Page } from 'puppeteer-core'; export interface ElementInfo { tag: string; id?: string; className?: string; text?: string; selector?: string; isCanvas?: boolean; isInteractive?: boolean; boundingBox?: { x: number; y: number; width: number; height: number; }; } export interface MouseEvent { type: 'mousemove' | 'mousedown' | 'mouseup' | 'wheel' | 'click' | 'dblclick'; x: number; y: number; timestamp: number; button?: number; buttons?: number; deltaX?: number; deltaY?: number; clickCount?: number; elementInfo?: ElementInfo; } export interface KeyboardEvent { type: 'keydown' | 'keyup'; key: string; code: string; timestamp: number; modifiers?: { ctrl?: boolean; alt?: boolean; shift?: boolean; meta?: boolean; }; repeat?: boolean; targetInfo?: { tag: string; id?: string; isInput?: boolean; selector?: string; }; } export interface PasteEvent { type: 'paste'; text: string; timestamp: number; targetInfo?: { tag: string; id?: string; isInput?: boolean; selector?: string; }; } export interface NavigationEvent { type: 'navigation' | 'reload'; url: string; timestamp: number; previousUrl?: string; } export type CommentCategory = 'narrative' | 'bug' | 'feature'; export interface CommentEvent { type: 'comment'; text: string; timestamp: number; category: CommentCategory; attachedToEventIndex?: number; } export type InputEvent = MouseEvent | KeyboardEvent | PasteEvent | NavigationEvent | CommentEvent; export interface RecordingOptions { showOverlay?: boolean; abortSignal?: AbortSignal; issueId?: number; } export interface RecordingSession { id: number; connectionReference: string; startTime: number; endTime?: number; startUrl: string; events: InputEvent[]; isRecording: boolean; isPaused: boolean; } export interface StoredRecording { id: number; connectionReference: string; startTime: number; endTime: number; startUrl: string; duration: number; events: InputEvent[]; summary: { clicks: number; drags: number; scrolls: number; keyPresses: number; navigations: number; comments: number; }; } /** * Cancel an active recording without saving */ export declare function cancelRecording(connectionReference: string): Promise; /** * Cancel all active recordings */ export declare function cancelAllRecordings(): Promise; export declare function isMouseEvent(event: InputEvent): event is MouseEvent; export declare function isKeyboardEvent(event: InputEvent): event is KeyboardEvent; export declare function isNavigationEvent(event: InputEvent): event is NavigationEvent; export declare function isCommentEvent(event: InputEvent): event is CommentEvent; export declare function isPasteEvent(event: InputEvent): event is PasteEvent; /** * Start recording interactions on a page. * Returns a promise that resolves when the recording is completed (via UI or stopRecording). */ export declare function startRecording(page: Page, connectionReference: string, options?: RecordingOptions): Promise<{ success: boolean; id?: number; recording?: StoredRecording; error?: string; cancelled?: boolean; closeTab?: boolean; }>; export declare function simplifyEvents(events: InputEvent[], options?: { distanceThreshold?: number; timeThreshold?: number; scrollTimeThreshold?: number; }): InputEvent[]; export interface CommandConversionOptions { simplify?: boolean; includeHovers?: boolean; preferCoordinates?: boolean; preferSelectors?: boolean; includeDelays?: boolean; startTime?: number; /** Maximum delay in ms (0 = no limit). Delays exceeding this are capped. */ maxDelayMs?: number; } export declare function eventsToCommands(events: InputEvent[], options?: CommandConversionOptions): Array<{ tool: string; params: Record; delay?: number; comment?: string; }>; /** * Generate a condensed timeline of events, grouping consecutive actions of the same type * but showing actual comment text inline. * Example: "3 clicks → 5 keys → 'testing this feature' → 2 clicks → 'done testing'" */ export declare function generateCondensedTimeline(events: InputEvent[]): string; export interface VerificationResult { resolved: boolean; comment?: string; } /** * Show a verification overlay on the page asking the user to confirm * whether an issue is resolved. */ export declare function showVerificationOverlay(page: Page, issueType: 'bug' | 'feature', issueDescription: string, issueId: number): Promise; export type TestReadyAction = 'cancel' | 'begin' | 'rerecord'; /** * Show a "Ready to begin?" overlay before starting a test replay * Uses DOM methods instead of innerHTML to support Trusted Types policies * Returns: 'cancel', 'begin', or 'rerecord' */ export declare function showTestReadyOverlay(page: Page, issueType: 'bug' | 'feature', issueDescription: string, issueId: number, hasSequence?: boolean): Promise; /** * Show a "Replay in progress" overlay that blocks user interaction * Returns a cleanup function to remove the overlay */ export declare function showReplayOverlay(page: Page, issueType: 'bug' | 'feature', issueDescription: string, issueId: number): Promise<() => Promise>; //# sourceMappingURL=interaction-recorder.d.ts.map