UNPKG

playwright-performance-reporter

Version:

Measure and publish performance metrics from browser dev-tools when running playwright

104 lines (103 loc) 3.27 kB
import { nativeChromiumPlugins, } from '../plugins/index.js'; import { enhanceGarbageCollectionPlugin, } from '../../../helpers/index.js'; export class HeapDump { options; name = 'heapDump'; plugins = [ nativeChromiumPlugins.heapProfilerDomainPlugin, ]; /** * Options to call `HeapProfiler.takeHeapSnapshot` which are mandatory to collect * * @private */ takeHeapSnapshotOptions = { captureNumericValue: true, reportProgress: true, treatGlobalObjectsAsRoots: true, }; constructor(options) { this.options = options; enhanceGarbageCollectionPlugin(nativeChromiumPlugins.heapGarbageCollectorPlugin, this, this.options); } /** * @inheritdoc */ async onStart(accumulator, developmentTools) { await this.common(accumulator, developmentTools); } /** * @inheritdoc */ async onSampling(accumulator, developmentTools) { await this.common(accumulator, developmentTools); } /** * @inheritdoc */ async onStop(accumulator, developmentTools) { await this.common(accumulator, developmentTools); } /** * Common function for onStart and onStop hook */ async common(accumulator, client) { return new Promise(async (resolve) => { const subscriptions = []; const chunks = []; try { subscriptions.push(this.listenForNextChunk(client, chunks)); await Promise.all([ this.waitForHeapDumpCompletion(client), this.takeHeapSnapshot(client), ]); accumulator.heap = chunks.join(''); } catch { resolve(false); } finally { for (const subscription of subscriptions) { subscription(); } } resolve(true); }); } /** * Wrapper for `HeapProfiler.takeHeapSnapshot` and check if request was successful */ async takeHeapSnapshot(client) { return new Promise(async (resolve, reject) => { try { await client.HeapProfiler.takeHeapSnapshot(this.takeHeapSnapshotOptions); resolve(true); } catch { reject(new Error('HeapProfiler.takeHeapSnapshot command failed')); } }); } /** * Wrapper for `HeapProfiler.addHeapSnapshotChunk` and report response continuously */ listenForNextChunk(client, chunkAggregation) { const unsubscribe = client.HeapProfiler.addHeapSnapshotChunk(cdpResponse => { chunkAggregation.push(cdpResponse.chunk); }); return unsubscribe; } /** * Wrapper for `HeapProfiler.reportHeapSnapshotProgress` and report response continuously */ async waitForHeapDumpCompletion(client) { return new Promise(resolve => { const unsubscribe = client.HeapProfiler.reportHeapSnapshotProgress(cdpResponse => { if (cdpResponse.finished) { unsubscribe(); resolve(true); } }); }); } }