import { BrowserContext, Page } from '@playwright/test'; import { NetworkConfig } from '../config/network-configs'; export interface NetworkRequest { url: string; method: string; status: number; duration: number; } export class NetworkSimulator { private requests: NetworkRequest[] = []; constructor(private context: BrowserContext) { this.setupRequestMonitoring(); } private setupRequestMonitoring(): void { this.context.on('request', (request) => { this.requests.push({ url: request.url(), method: request.method(), status: 0, duration: 0, }); }); this.context.on('response', (response) => { const request = this.requests.find(r => r.url === response.url()); if (request) { request.status = response.status(); request.duration = 0; } }); } async setNetworkCondition(config: NetworkConfig): Promise { if (config.offline) { await this.context.setOffline(true); } else { await this.context.setOffline(false); if (config.downloadThroughput && config.uploadThroughput && config.latency) { await this.context.route('**', (route) => { route.continue({ headers: { ...route.request().headers(), }, }); }); } } } async goOffline(): Promise { await this.context.setOffline(true); } async goOnline(): Promise { await this.context.setOffline(false); } async simulateNetworkSwitch(fromConfig: NetworkConfig, toConfig: NetworkConfig): Promise { await this.setNetworkCondition(fromConfig); await this.context.pages()[0]?.waitForTimeout(1000); await this.setNetworkCondition(toConfig); } async resetNetworkCondition(): Promise { await this.context.setOffline(false); await this.context.unrouteAll(); } getRequests(): NetworkRequest[] { return [...this.requests]; } clearRequests(): void { this.requests = []; } getFailedRequests(): NetworkRequest[] { return this.requests.filter(r => r.status >= 400); } getSlowRequests(threshold: number = 1000): NetworkRequest[] { return this.requests.filter(r => r.duration > threshold); } }