64 lines
2.3 KiB
TypeScript
64 lines
2.3 KiB
TypeScript
import type { CDPSession, Page } from '@playwright/test';
|
|
import { createWriteStream, mkdirSync, writeFileSync } from 'node:fs';
|
|
import path from 'node:path';
|
|
|
|
const sessions = new WeakMap<Page, CDPSession>();
|
|
|
|
async function cdp(page: Page): Promise<CDPSession> {
|
|
let s = sessions.get(page);
|
|
if (!s) {
|
|
s = await page.context().newCDPSession(page);
|
|
sessions.set(page, s);
|
|
}
|
|
return s;
|
|
}
|
|
|
|
/** CPU throttling: rate=1 — без замедления, 4 — в 4 раза медленнее. */
|
|
export async function throttle(page: Page, rate: number): Promise<void> {
|
|
await (await cdp(page)).send('Emulation.setCPUThrottlingRate', { rate });
|
|
}
|
|
|
|
export async function startTrace(page: Page): Promise<void> {
|
|
await page.context().browser()!.startTracing(page, {
|
|
categories: ['devtools.timeline', 'disabled-by-default-devtools.timeline', 'v8.execute', 'blink.user_timing'],
|
|
screenshots: false,
|
|
});
|
|
}
|
|
|
|
export async function stopTrace(page: Page, file: string): Promise<void> {
|
|
mkdirSync(path.dirname(file), { recursive: true });
|
|
const buf = await page.context().browser()!.stopTracing();
|
|
writeFileSync(file, buf);
|
|
}
|
|
|
|
export async function gc(page: Page): Promise<void> {
|
|
const s = await cdp(page);
|
|
await s.send('HeapProfiler.enable');
|
|
await s.send('HeapProfiler.collectGarbage');
|
|
}
|
|
|
|
export async function domCounters(page: Page): Promise<{ documents: number; nodes: number; jsEventListeners: number }> {
|
|
return (await (await cdp(page)).send('Memory.getDOMCounters')) as any;
|
|
}
|
|
|
|
/** Размер JS-кучи после GC, байты. */
|
|
export async function heapUsed(page: Page): Promise<number> {
|
|
await gc(page);
|
|
const s = await cdp(page);
|
|
await s.send('Runtime.enable');
|
|
const r = (await s.send('Runtime.getHeapUsage')) as { usedSize: number };
|
|
return r.usedSize;
|
|
}
|
|
|
|
export async function heapSnapshot(page: Page, file: string): Promise<void> {
|
|
mkdirSync(path.dirname(file), { recursive: true });
|
|
const s = await cdp(page);
|
|
const out = createWriteStream(file);
|
|
const onChunk = (e: { chunk: string }) => { out.write(e.chunk); };
|
|
s.on('HeapProfiler.addHeapSnapshotChunk', onChunk);
|
|
await s.send('HeapProfiler.enable');
|
|
await s.send('HeapProfiler.takeHeapSnapshot', { reportProgress: false });
|
|
s.off('HeapProfiler.addHeapSnapshotChunk', onChunk);
|
|
await new Promise<void>((res) => out.end(res));
|
|
}
|