fix(streams): avoid leaking event listeners (#27291)

Fixes #26998.
This commit is contained in:
Dmitry Gozman 2023-09-25 10:59:14 -07:00 committed by GitHub
parent 66eb3043f5
commit 0f72ef0584
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 7 deletions

View file

@ -17,7 +17,7 @@
import type * as channels from '@protocol/channels';
import { Dispatcher } from './dispatcher';
import type * as stream from 'stream';
import { createGuid } from '../../utils';
import { ManualPromise, createGuid } from '../../utils';
import type { ArtifactDispatcher } from './artifactDispatcher';
export class StreamDispatcher extends Dispatcher<{ guid: string, stream: stream.Readable }, channels.StreamChannel, ArtifactDispatcher> implements channels.StreamChannel {
@ -36,11 +36,15 @@ export class StreamDispatcher extends Dispatcher<{ guid: string, stream: stream.
if (this._ended)
return { binary: Buffer.from('') };
if (!stream.readableLength) {
await new Promise((fulfill, reject) => {
stream.once('readable', fulfill);
stream.once('end', fulfill);
stream.once('error', reject);
});
const readyPromise = new ManualPromise<void>();
const done = () => readyPromise.resolve();
stream.on('readable', done);
stream.on('end', done);
stream.on('error', done);
await readyPromise;
stream.off('readable', done);
stream.off('end', done);
stream.off('error', done);
}
const buffer = stream.read(Math.min(stream.readableLength, params.size || stream.readableLength));
return { binary: buffer || Buffer.from('') };

View file

@ -19,13 +19,21 @@ import fs from 'fs';
import path from 'path';
it('should output a trace', async ({ browser, server }, testInfo) => {
let warning = null;
const warningHandler = w => warning = w;
process.on('warning', warningHandler);
const page = await browser.newPage();
const outputTraceFile = testInfo.outputPath(path.join(`trace.json`));
await browser.startTracing(page, { screenshots: true, path: outputTraceFile });
await page.goto(server.PREFIX + '/grid.html');
for (let i = 0; i < 20; i++)
await page.goto(server.PREFIX + '/grid.html');
await browser.stopTracing();
expect(fs.existsSync(outputTraceFile)).toBe(true);
await page.close();
process.off('warning', warningHandler);
expect(warning).toBe(null);
});
it('should create directories as needed', async ({ browser, server }, testInfo) => {