CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-playwright-chromium

A high-level API to automate Chromium

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

network-control.mddocs/

Network Control

Request and response interception, network monitoring, and request routing capabilities for comprehensive network testing and automation scenarios.

Capabilities

Request Interception

Monitor and inspect HTTP requests made by the page, including headers, body, and timing information.

/**
 * HTTP request representation and inspection
 */
interface Request {
  /** Get request URL */
  url(): string;
  /** Get HTTP method */
  method(): string;
  /** Get request headers */
  headers(): { [key: string]: string; };
  /** Get request body as string */
  postData(): string | null;
  /** Get request body as JSON */
  postDataJSON(): any | null;
  /** Get request body as buffer */
  postDataBuffer(): Buffer | null;
  /** Get frame that initiated request */
  frame(): Frame;
  /** Check if this is a navigation request */
  isNavigationRequest(): boolean;
  /** Get request that was redirected to this one */
  redirectedFrom(): Request | null;
  /** Get request this was redirected to */
  redirectedTo(): Request | null;
  /** Get failure details if request failed */
  failure(): { errorText: string; } | null;
  /** Get request timing information */
  timing(): RequestTiming;
  /** Get resource type */
  resourceType(): string;
  /** Get associated response */
  response(): Promise<Response | null>;
  /** Get request and response sizes */
  sizes(): Promise<RequestSizes>;
  /** Get all headers (including multiple values) */
  allHeaders(): Promise<{ [key: string]: string; }>;
  /** Get headers array */
  headersArray(): Promise<{ name: string; value: string; }[]>;
  /** Get header value */
  headerValue(name: string): Promise<string | null>;
}

Usage Examples:

// Monitor all requests
page.on('request', request => {
  console.log(`${request.method()} ${request.url()}`);
  console.log('Headers:', request.headers());
  
  if (request.postData()) {
    console.log('Body:', request.postData());
  }
});

// Filter specific requests
page.on('request', request => {
  if (request.url().includes('/api/')) {
    console.log('API request:', request.url());
    console.log('Resource type:', request.resourceType());
  }
});

// Check request properties
page.on('request', async request => {
  const timing = request.timing();
  const response = await request.response();
  
  if (response) {
    console.log(`Request took: ${timing.responseEnd - timing.requestStart}ms`);
  }
});

Response Handling

Access and analyze HTTP responses including status, headers, and body content.

/**
 * HTTP response representation and data access
 */
interface Response {
  /** Get response URL */
  url(): string;
  /** Get HTTP status code */
  status(): number;
  /** Get status text */
  statusText(): string;
  /** Get response headers */
  headers(): { [key: string]: string; };
  /** Get all headers (including multiple values) */
  allHeaders(): Promise<{ [key: string]: string; }>;
  /** Get headers array */
  headersArray(): Promise<{ name: string; value: string; }[]>;
  /** Get single header value */
  headerValue(name: string): Promise<string | null>;
  /** Get multiple header values */
  headerValues(name: string): Promise<string[]>;
  /** Parse response as JSON */
  json(): Promise<any>;
  /** Get response as text */
  text(): Promise<string>;
  /** Get response as buffer */
  body(): Promise<Buffer>;
  /** Check if status indicates success (200-299) */
  ok(): boolean;
  /** Get originating request */
  request(): Request;
  /** Get associated frame */
  frame(): Frame;
  /** Get TLS security details */
  securityDetails(): SecurityDetails | null;
  /** Get server address */
  serverAddr(): ServerAddr | null;
  /** Get response sizes */
  sizes(): Promise<ResponseSizes>;
}

Usage Examples:

// Monitor responses
page.on('response', async response => {
  console.log(`${response.status()} ${response.url()}`);
  
  if (!response.ok()) {
    console.log('Failed response:', response.statusText());
  }
  
  if (response.url().includes('/api/data')) {
    const data = await response.json();
    console.log('API data:', data);
  }
});

// Check response details
page.on('response', async response => {
  const headers = response.headers();
  const contentType = headers['content-type'];
  
  if (contentType?.includes('application/json')) {
    try {
      const json = await response.json();
      console.log('JSON response:', json);
    } catch (error) {
      console.log('Invalid JSON response');
    }
  }
});

// Security information
page.on('response', response => {
  const security = response.securityDetails();
  if (security) {
    console.log('TLS protocol:', security.protocol);
    console.log('Certificate issuer:', security.issuer);
  }
});

Request Routing

Intercept and modify network requests, provide custom responses, or block requests entirely.

/**
 * Route handler for intercepting and modifying requests
 */
interface Route {
  /** Fulfill request with custom response */
  fulfill(response: RouteFullfillResponse): Promise<void>;
  /** Continue request with optional modifications */
  continue(overrides?: RouteContinueOverrides): Promise<void>;
  /** Abort the request with error code */
  abort(errorCode?: string): Promise<void>;
  /** Fetch request and get response for inspection */
  fetch(overrides?: RouteFetchOverrides): Promise<APIResponse>;
  /** Fall back to default request handling */
  fallback(overrides?: RouteFallbackOverrides): Promise<void>;
  /** Get original request */
  request(): Request;
}

/**
 * Set up request routing
 * @param url - URL pattern to match
 * @param handler - Route handler function
 */
route(url: string | RegExp | ((url: URL) => boolean), handler: (route: Route) => void): Promise<void>;

/**
 * Remove request routing
 * @param url - URL pattern
 * @param handler - Handler to remove (optional)
 */
unroute(url: string | RegExp | ((url: URL) => boolean), handler?: (route: Route) => void): Promise<void>;

Usage Examples:

// Mock API responses
await page.route('**/api/users', route => {
  route.fulfill({
    status: 200,
    contentType: 'application/json',
    body: JSON.stringify([
      { id: 1, name: 'Alice' },
      { id: 2, name: 'Bob' }
    ])
  });
});

// Modify request headers
await page.route('**/api/**', route => {
  route.continue({
    headers: {
      ...route.request().headers(),
      'Authorization': 'Bearer fake-token'
    }
  });
});

// Block requests
await page.route('**/*.{png,jpg,jpeg}', route => route.abort());

// Conditional routing
await page.route('**/api/data', async route => {
  const request = route.request();
  
  if (request.method() === 'POST') {
    // Mock POST response
    route.fulfill({
      status: 201,
      body: JSON.stringify({ success: true })
    });
  } else {
    // Let GET requests through
    route.continue();
  }
});

// Fetch and modify response
await page.route('**/api/config', async route => {
  const response = await route.fetch();
  const body = await response.json();
  
  // Modify response data
  body.environment = 'test';
  
  route.fulfill({
    status: response.status(),
    headers: response.headers(),
    body: JSON.stringify(body)
  });
});

HAR (HTTP Archive) Support

Record and replay network traffic using HAR files for testing and debugging.

/**
 * Route requests using HAR file
 * @param har - Path to HAR file
 * @param options - HAR routing options
 */
routeFromHAR(har: string, options?: RouteFromHAROptions): Promise<void>;

Usage Examples:

// Route from HAR file
await context.routeFromHAR('recordings/api-calls.har', {
  url: '**/api/**',
  update: false // Use recorded responses
});

// Update HAR file with new responses
await context.routeFromHAR('recordings/api-calls.har', {
  url: '**/api/**',
  update: true // Record new responses
});

// Route specific URLs from HAR
await context.routeFromHAR('recordings/full-session.har', {
  url: /.*\.(css|js|png|jpg)$/,
  update: false
});

Event Handling

Network Events

// Page-level network events
page.on('request', (request: Request) => void);
page.on('response', (response: Response) => void);
page.on('requestfailed', (request: Request) => void);
page.on('requestfinished', (request: Request) => void);

// Context-level network events (for all pages)
context.on('request', (request: Request) => void);
context.on('response', (response: Response) => void);
context.on('requestfailed', (request: Request) => void);
context.on('requestfinished', (request: Request) => void);

Usage Examples:

// Track failed requests
page.on('requestfailed', request => {
  const failure = request.failure();
  console.log(`Request failed: ${request.url()}`);
  console.log(`Error: ${failure?.errorText}`);
});

// Monitor request completion
page.on('requestfinished', async request => {
  const response = await request.response();
  const timing = request.timing();
  
  console.log(`${request.method()} ${request.url()}`);
  console.log(`Status: ${response?.status()}`);
  console.log(`Duration: ${timing.responseEnd - timing.requestStart}ms`);
});

// Context-wide monitoring
context.on('request', request => {
  if (request.resourceType() === 'xhr') {
    console.log('AJAX request:', request.url());
  }
});

Configuration Types

Route Options

interface RouteFullfillResponse {
  /** HTTP status code */
  status?: number;
  /** Response headers */
  headers?: { [key: string]: string; };
  /** Response body */
  body?: string | Buffer;
  /** Content type header */
  contentType?: string;
  /** Response body as JSON (automatically serialized) */
  json?: any;
  /** Response body from file path */
  path?: string;
}

interface RouteContinueOverrides {
  /** Override request URL */
  url?: string;
  /** Override HTTP method */
  method?: string;
  /** Override request headers */
  headers?: { [key: string]: string; };
  /** Override request body */
  postData?: string | Buffer;
}

interface RouteFetchOverrides {
  /** Override request URL */
  url?: string;
  /** Override HTTP method */
  method?: string;
  /** Override request headers */
  headers?: { [key: string]: string; };
  /** Override request body */
  postData?: string | Buffer;
  /** Request timeout */
  timeout?: number;
}

interface RouteFromHAROptions {
  /** URL pattern to match */
  url?: string | RegExp;
  /** Whether to update HAR with new responses */
  update?: boolean;
  /** Update if missing in HAR */
  updateContent?: 'embed' | 'attach';
  /** Update mode for existing entries */
  updateMode?: 'full' | 'minimal';
}

Network Information Types

interface RequestTiming {
  /** Request start time */
  startTime: number;
  /** Domain lookup start */
  domainLookupStart: number;
  /** Domain lookup end */
  domainLookupEnd: number;
  /** Connect start */
  connectStart: number;
  /** Secure connection start */
  secureConnectionStart: number;
  /** Connect end */
  connectEnd: number;
  /** Request start */
  requestStart: number;
  /** Response start */
  responseStart: number;
  /** Response end */
  responseEnd: number;
}

interface RequestSizes {
  /** Request header bytes */
  requestHeadersSize: number;
  /** Request body bytes */
  requestBodySize: number;
  /** Response header bytes */
  responseHeadersSize: number;
  /** Response body bytes */
  responseBodySize: number;
}

interface ResponseSizes {
  /** Response header bytes */
  responseHeadersSize: number;
  /** Response body bytes */
  responseBodySize: number;
}

interface SecurityDetails {
  /** TLS protocol version */
  protocol: string;
  /** Certificate issuer */
  issuer: string;
  /** Certificate subject name */
  subjectName: string;
  /** Certificate valid from */
  validFrom: number;
  /** Certificate valid to */
  validTo: number;
}

interface ServerAddr {
  /** Server IP address */
  ipAddress: string;
  /** Server port */
  port: number;
}

Error Codes

type NetworkErrorCode = 
  | 'aborted'
  | 'accessdenied'
  | 'addressunreachable'
  | 'blockedbyclient'
  | 'blockedbyresponse'
  | 'connectionaborted'
  | 'connectionclosed'
  | 'connectionfailed'
  | 'connectionrefused'
  | 'connectionreset'
  | 'internetdisconnected'
  | 'namenotresolved'
  | 'timedout'
  | 'failed';

Usage Examples:

// Abort with specific error
await page.route('**/slow-api/**', route => {
  route.abort('timedout');
});

// Handle different error types
page.on('requestfailed', request => {
  const failure = request.failure();
  
  switch (failure?.errorText) {
    case 'net::ERR_INTERNET_DISCONNECTED':
      console.log('No internet connection');
      break;
    case 'net::ERR_CONNECTION_TIMED_OUT':
      console.log('Request timed out');
      break;
    default:
      console.log('Request failed:', failure?.errorText);
  }
});

Install with Tessl CLI

npx tessl i tessl/npm-playwright-chromium

docs

api-testing.md

browser-management.md

element-handling.md

index.md

input-simulation.md

network-control.md

page-interaction.md

tile.json