From dd9ccfe8b397df6521a152d6ded4950457963eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=BF=94?= Date: Thu, 5 Mar 2026 15:05:50 +0800 Subject: [PATCH] feat: create NetworkSimulator base structure --- e2e/src/utils/NetworkSimulator.ts | 74 +++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 e2e/src/utils/NetworkSimulator.ts diff --git a/e2e/src/utils/NetworkSimulator.ts b/e2e/src/utils/NetworkSimulator.ts new file mode 100644 index 0000000..ebc35bb --- /dev/null +++ b/e2e/src/utils/NetworkSimulator.ts @@ -0,0 +1,74 @@ +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 = response.timing().responseEnd - response.timing().startTime; + } + }); + } + + 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 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); + } +} \ No newline at end of file