prasanaworld / puppeteer-screen-recorder

A powerful plugin for recording with Puppeteer.
https://prasanaworld.github.io/puppeteer-screen-recorder/classes/puppeteerscreenrecorder.html
MIT License
380 stars 63 forks source link

Add the option to stop recording without saving it. PuppeteerScreenRecorder.stop #21

Open nzyoni opened 2 years ago

nzyoni commented 2 years ago

Currently, I do something like that

  const recorder = new PuppeteerScreenRecorder(page);

  await recorder.start(path);
  /* test is running  */
  await recorder.stop()

  if(testPassedSuccessfully) {
     // remove the file
  }

I would like to pass a parameter to stop function, for example, save, to indicate if the recorder should save the file or not.

  await recorder.stop({ save: !testPassedSuccessfully })
ojamui commented 2 years ago

Sounds like a great idea! +1

prasanaworld commented 2 years ago

Hi @nzyoni,

Thanks for bring this up.

I will add this feature as part of the next release version planned.

Meanwhile, as a workaround you could achieve the same using the startStream method.

instead of passing a filePath, you could pass a stream as input and once the stop method is invoked, you could determine, whether to save the stream to a file or not.

  const recorder = new PuppeteerScreenRecorder(page);
  const passthrough = new PassThrough();

  await recorder. startStream(passthrough);
  /* test is running  */
  await recorder.stop()

  if(testPassedSuccessfully) {
    const fileWriteStream = fs.createWriteStream(path);
    passthrough.pipe(fileWriteStream);;
  }
minipunch commented 2 years ago

Does that method not work when starting recording in a beforeEach block and stopping the recording in an afterEach block?

Seems to be hanging at recorder.stop() for me in that case

I was able to get that to work but only when using the not-streaming method

MorpheusNephew commented 2 years ago

Does that method not work when starting recording in a beforeEach block and stopping the recording in an afterEach block?

Seems to be hanging at recorder.stop() for me in that case

I was able to get that to work but only when using the not-streaming method

I'm also having this issue starting using startStream then attempting to stop hangs. Works as expected when using start. The time of the video, based on the physical file, is roughly 3 seconds.

prasanaworld commented 2 years ago

Hi @minipunch & @MorpheusNephew,

I couldn't reproduce this issue. I've updated the example script for startStream method now.

Could you please try with the example script in pupper-screen-recorder and let me know you still face the same. https://github.com/prasanaworld/puppeteer-screen-recorder/blob/main/src/example/index.ts

lucassardois commented 1 year ago

Hi @nzyoni,

Thanks for bring this up.

I will add this feature as part of the next release version planned.

Meanwhile, as a workaround you could achieve the same using the startStream method.

instead of passing a filePath, you could pass a stream as input and once the stop method is invoked, you could determine, whether to save the stream to a file or not.

  const recorder = new PuppeteerScreenRecorder(page);
  const passthrough = new PassThrough();

  await recorder. startStream(passthrough);
  /* test is running  */
  await recorder.stop()

  if(testPassedSuccessfully) {
    const fileWriteStream = fs.createWriteStream(path);
    passthrough.pipe(fileWriteStream);;
  }

When trying that suggestion I get the following typescript error:

Argument of type 'internal' is not assignable to parameter of type 'Writable'.
  Type 'internal' is missing the following properties from type 'Writable': writable, writableEnded, writableFinished, writableHighWaterMark, and 16 more.ts(2345)

image

Edit: nevermind the above issue, when importing correctly from stream node core library it started to works. However I'm now experiencing the hang on stop issue with the following code:

    const recorder = new PuppeteerScreenRecorder(page);
    const passthrough = new PassThrough();
    await recorder.startStream(passthrough);

    try {
        await fn();
        console.log("1");
        const res = await recorder.stop();
        console.log("2");
    } catch (err: unknown) {
        await recorder.stop();
        const fileWriteStream = fs.createWriteStream("video.mp4");
        passthrough.pipe(fileWriteStream);
        throw err;
    }

Log 1 appears but not 2, the promise of the stop never resolves.

lucassardois commented 1 year ago

Hi @minipunch & @MorpheusNephew,

I couldn't reproduce this issue. I've updated the example script for startStream method now.

Could you please try with the example script in pupper-screen-recorder and let me know you still face the same. https://github.com/prasanaworld/puppeteer-screen-recorder/blob/main/src/example/index.ts

I ran the tests without issue on my end.

lucassardois commented 1 year ago

Okay I found a workaround:

    const recorder = new PuppeteerScreenRecorder(page);
    const passthrough = new PassThrough();
    await recorder.startStream(passthrough);

    try {
        await fn();
        passthrough.destroy(); // The important line
        await recorder.stop();
    } catch (err: unknown) {
        const fileWriteStream = fs.createWriteStream(`report/${testName}.mp4`);
        passthrough.pipe(fileWriteStream);
        await recorder.stop();
        throw err;
    }

By doing this the recorder.stop() call no longer hang.