@puberty-labs/clits
Version:
CLiTS (Chrome Logging and Inspection Tool Suite) is a powerful Node.js library for automated Chrome browser testing, logging, and inspection. It provides a comprehensive suite of tools for monitoring network requests, console logs, DOM mutations, and more
221 lines (220 loc) • 6.99 kB
TypeScript
import { ExtractedLog } from './extractor.js';
import { RetryConfig } from './platform/chrome-error-handler.js';
import { SanitizationRule } from './utils/data-sanitizer.js';
type NetworkRequest = {
requestId: string;
url: string;
method: string;
headers: Record<string, string>;
timestamp: number;
postData?: string;
};
type NetworkResponse = {
requestId: string;
status: number;
headers: Record<string, string>;
timestamp: number;
};
type ConsoleMessage = {
source: string;
level: string;
text: string;
timestamp: number;
};
type DevToolsLogEntry = {
source: string;
level: string;
text: string;
timestamp: number;
};
type JwtTokenDetails = {
token: string;
decodedPayload?: any;
header?: any;
signatureVerified?: boolean;
expiresAt?: string;
issuedAt?: string;
};
type GraphQLEvent = {
requestId: string;
url: string;
requestBody?: any;
responseBody?: any;
graphqlQuery?: string;
graphqlVariables?: any;
graphqlOperationName?: string;
errors?: any[];
timestamp: number;
type: 'request' | 'response';
};
type CorrelatedNetworkEntry = {
request: NetworkRequest;
response: NetworkResponse;
};
type WebSocketFrame = {
opcode: number;
mask: boolean;
payloadData: string;
};
type WebSocketEvent = {
requestId: string;
timestamp: number;
url: string;
type: 'webSocketCreated' | 'webSocketClosed' | 'webSocketFrameReceived' | 'webSocketFrameSent';
frame?: WebSocketFrame;
message?: string;
};
type ReduxEvent = {
type: 'action' | 'stateChange';
action?: any;
prevState?: any;
newState?: any;
timestamp: number;
};
type PerformanceMetricEvent = {
name: string;
value: number;
timestamp: number;
title?: string;
};
type EventLoopMetricEvent = {
duration: number;
blockingDuration: number;
startTime: number;
scripts: Array<{
invoker?: string;
sourceURL?: string;
sourceFunctionName?: string;
duration: number;
}>;
entry: any;
};
type UserInteractionEvent = {
type: string;
target: string;
timestamp: number;
details: any;
};
type DomMutationEvent = {
type: string;
target: string;
details: any;
};
type CssChangeEvent = {
type: 'stylesheetAdded' | 'stylesheetRemoved' | 'stylesheetChanged';
styleSheetId: string;
header?: any;
change?: any;
timestamp: number;
};
type CredentialDetails = {
type: 'apiKey' | 'basicAuth' | 'jwt' | 'unknown';
value: string;
source: 'header' | 'body';
key?: string;
};
type ReactHookEvent = {
level: string;
text: string;
parameters?: Array<{
type: string;
value: any;
}>;
timestamp: string;
};
export interface ChromeExtractorOptions {
port?: number;
host?: string;
maxEntries?: number;
includeNetwork?: boolean;
includeConsole?: boolean;
retryConfig?: Partial<RetryConfig>;
reconnect?: {
enabled?: boolean;
maxAttempts?: number;
delayBetweenAttemptsMs?: number;
};
filters?: {
logLevels?: Array<'error' | 'warning' | 'info' | 'debug' | 'log'>;
sources?: Array<'network' | 'console' | 'devtools' | 'websocket' | 'jwt' | 'graphql' | 'redux' | 'performance' | 'eventloop' | 'userinteraction' | 'dommutation' | 'csschange' | 'reacthook'>;
domains?: string[];
keywords?: string[];
excludePatterns?: string[];
advancedFilter?: string;
};
format?: {
groupBySource?: boolean;
groupByLevel?: boolean;
includeTimestamp?: boolean;
includeStackTrace?: boolean;
};
enableReactHookMonitoring?: boolean;
includeWebSockets?: boolean;
includeJwtMonitoring?: boolean;
includeGraphqlMonitoring?: boolean;
includeReduxMonitoring?: boolean;
includePerformanceMonitoring?: boolean;
includeEventLoopMonitoring?: boolean;
includeUserInteractionRecording?: boolean;
includeDomMutationMonitoring?: boolean;
includeCssChangeMonitoring?: boolean;
headless?: boolean;
sanitizationRules?: SanitizationRule[];
}
export interface CollectedLogEntry {
type: 'network' | 'console' | 'log' | 'websocket' | 'jwt' | 'graphql' | 'redux' | 'performance' | 'eventloop' | 'userinteraction' | 'dommutation' | 'csschange' | 'credential' | 'reacthook';
timestamp: string;
content?: string;
level?: string;
details: NetworkRequest | NetworkResponse | ConsoleMessage | DevToolsLogEntry | CorrelatedNetworkEntry | WebSocketEvent | JwtTokenDetails | GraphQLEvent | ReduxEvent | PerformanceMetricEvent | EventLoopMetricEvent | UserInteractionEvent | DomMutationEvent | CssChangeEvent | CredentialDetails | ReactHookEvent;
}
export declare class ChromeExtractor {
private static readonly DEFAULT_PORT;
private static readonly DEFAULT_HOST;
private static readonly DEFAULT_MAX_ENTRIES;
private options;
private chromeErrorHandler;
private dataSanitizer;
private pendingNetworkRequests;
private pendingGraphqlRequests;
protected collectedLogs: CollectedLogEntry[];
constructor(options?: ChromeExtractorOptions);
getDebuggablePageTargets(): Promise<Array<{
id: string;
url: string;
title: string;
webSocketDebuggerUrl: string;
}>>;
private connectToDebugger;
private shouldIncludeLog;
/**
* Evaluates an advanced boolean filter expression against a log entry
* Supports AND, OR, NOT, and parentheses for grouping
* Example: "(React AND error) OR (network AND 404)"
*/
private evaluateAdvancedFilter;
/**
* Parses and evaluates a boolean filter expression
* This is a simple recursive descent parser for boolean expressions
*/
private parseAdvancedFilterExpression;
/**
* Helper to find the position of a boolean operator outside of parentheses
*/
private findOperatorPosition;
private formatLogs;
/**
* Helper to decode and parse JWT tokens.
* This is a basic decoder and does not verify the signature.
*/
private parseJwt;
extract(targetId?: string): Promise<ExtractedLog[]>;
/**
* Test hook: injects a simulated event into the log collection.
* @param type 'network' | 'console' | 'log' | 'reacthook' | 'dommutation' | 'csschange' | 'redux' | 'eventloop' | 'userinteraction' | 'websocket' | 'jwt' | 'graphql' | 'performance' | 'credential'
* @param payload The event payload (NetworkRequest, NetworkResponse, ConsoleMessage, DevToolsLogEntry)
* @param logsOverride (optional) logs array to use (for test injection)
*/
protected _injectTestEvent(type: 'network' | 'console' | 'log' | 'reacthook' | 'dommutation' | 'csschange' | 'redux' | 'eventloop' | 'userinteraction' | 'websocket' | 'jwt' | 'graphql' | 'performance' | 'credential', payload: any, logsOverride?: CollectedLogEntry[]): void;
}
export {};