feat: implement network condition simulation in NetworkSimulator

This commit is contained in:
张翔
2026-03-05 15:10:02 +08:00
parent dd9ccfe8b3
commit 01d966bed3
2 changed files with 115 additions and 13 deletions
@@ -0,0 +1,53 @@
import { test, expect } from '@playwright/test';
import { NetworkSimulator } from '../../utils/NetworkSimulator';
import { networkConfigs } from '../../config/network-configs';
test.describe('NetworkSimulator', () => {
test('should set 3G network condition', async ({ page, context }) => {
const simulator = new NetworkSimulator(context);
await simulator.setNetworkCondition(networkConfigs['3g-fast']);
await page.goto('/');
await expect(page.locator('header')).toBeVisible();
});
test('should switch to offline mode', async ({ page, context }) => {
const simulator = new NetworkSimulator(context);
await page.goto('/');
await simulator.goOffline();
await page.reload();
await expect(page.locator('header')).toBeVisible();
});
test('should switch back to online mode', async ({ page, context }) => {
const simulator = new NetworkSimulator(context);
await simulator.goOffline();
await page.goto('/');
await simulator.goOnline();
await page.reload();
await expect(page.locator('header')).toBeVisible();
});
test('should simulate network switch', async ({ page, context }) => {
const simulator = new NetworkSimulator(context);
await simulator.simulateNetworkSwitch(networkConfigs['4g'], networkConfigs['3g-slow']);
await page.goto('/');
await expect(page.locator('header')).toBeVisible();
});
test('should reset network condition', async ({ page, context }) => {
const simulator = new NetworkSimulator(context);
await simulator.setNetworkCondition(networkConfigs['3g-slow']);
await simulator.resetNetworkCondition();
await page.goto('/');
await expect(page.locator('header')).toBeVisible();
});
});
+62 -13
View File
@@ -35,25 +35,74 @@ export class NetworkSimulator {
} }
async setNetworkCondition(config: NetworkConfig): Promise<void> { async setNetworkCondition(config: NetworkConfig): Promise<void> {
const page = this.context.pages()[0];
if (!page) throw new Error('No page available');
const cdpSession = await this.context.newCDPSession(page);
if (config.offline) { if (config.offline) {
await this.context.setOffline(true); await cdpSession.send('Network.emulateNetworkConditions', {
offline: true,
downloadThroughput: 0,
uploadThroughput: 0,
latency: 0,
});
} else { } else {
await this.context.setOffline(false); await cdpSession.send('Network.emulateNetworkConditions', {
if (config.downloadThroughput && config.uploadThroughput && config.latency) { offline: false,
await this.context.route('**', (route) => { downloadThroughput: config.downloadThroughput,
route.continue({ uploadThroughput: config.uploadThroughput,
headers: { latency: config.latency,
...route.request().headers(), });
},
});
});
}
} }
} }
async goOffline(): Promise<void> {
const page = this.context.pages()[0];
if (!page) throw new Error('No page available');
const cdpSession = await this.context.newCDPSession(page);
await cdpSession.send('Network.emulateNetworkConditions', {
offline: true,
downloadThroughput: 0,
uploadThroughput: 0,
latency: 0,
});
}
async goOnline(): Promise<void> {
const page = this.context.pages()[0];
if (!page) throw new Error('No page available');
const cdpSession = await this.context.newCDPSession(page);
await cdpSession.send('Network.emulateNetworkConditions', {
offline: false,
downloadThroughput: -1,
uploadThroughput: -1,
latency: 0,
});
}
async simulateNetworkSwitch(fromConfig: NetworkConfig, toConfig: NetworkConfig): Promise<void> {
await this.setNetworkCondition(fromConfig);
const page = this.context.pages()[0];
if (page) {
await page.waitForTimeout(1000);
}
await this.setNetworkCondition(toConfig);
}
async resetNetworkCondition(): Promise<void> { async resetNetworkCondition(): Promise<void> {
await this.context.setOffline(false); const page = this.context.pages()[0];
await this.context.unrouteAll(); if (!page) throw new Error('No page available');
const cdpSession = await this.context.newCDPSession(page);
await cdpSession.send('Network.emulateNetworkConditions', {
offline: false,
downloadThroughput: -1,
uploadThroughput: -1,
latency: 0,
});
} }
getRequests(): NetworkRequest[] { getRequests(): NetworkRequest[] {