Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] How to record video / take screenshot with multiple windows #5633

Closed
louis57 opened this issue Feb 26, 2021 · 3 comments
Closed

Comments

@louis57
Copy link

louis57 commented Feb 26, 2021

The app I am writing tests, has multiple windows. For example, first I need to login on MainPage, click button Edit, then second page EditPage will be opened, and the rest of actions happen on second page EditPage

I have written method to take video with chromium of the whole test flow from begin to end, but when the EditPage opens, the video is still focused on MainPage. The same goes for screenshot, when test fails on EditPage, the screenshot is still taken on MainPage

Below is part of my code:

// definition of take video and take screenshot functions
export async function recordeVideo(page: Page, name: string) {
  return await saveVideo(page, videoDir + name + "_" + Date.now() + ".mp4");
}

export async function takeScreenshot(
  page: Page,
  name: string,
  fullPage: boolean = true
): Promise<Buffer> {
  return await page.screenshot({
    fullPage: fullPage,
    path: screenshotsDir + name + "_" + Date.now() + ".png",
  });
}

// definition of test
beforeAll(async () => {
  browser = await _.getBrowser();
  context = await browser.newContext(_.contextOptions);
  page = await context.newPage();
  capture = await _.recordeVideo(page, "test_video");
  await page.goto(URL, { waitUntil: "networkidle" });
});

describe("E2E Tests", () => {
  // here are all defined test steps, 
 // just example how to handle multiple windows:
const editBtn = await page.$(editButton);
await editBtn.click();
// Get EditPage after clicking button
[editPage] = await Promise.all([
    context.waitForEvent('page')
]);
await editPage.waitForLoadState();
// then the tests go on on editPage
});

afterEach(async () => {
  if (jasmine.currentTest.failedExpectations.length > 0) {
    await _.takeScreenshot(page, jasmine.currentTest.id);
    success = false;
  }
});

afterAll(async (done) => {
  await capture.stop();
  await page.close();
  await browser.close();
});

As I see the problem is, page is the input of function recordeVideo and takeScreenshot, that's why they don't take video or screenshot on editPage.

How can I record or take screenshot with multiple windows?

Thanks in advance.

@pavelfeldman
Copy link
Member

I'm not sure what helper functions you are using and what is in saveVideo. But the video can be recorded as follows:

// Create context that saves videos
const context = await browser.newContext({ recordVideo: { dir: 'videos/' } });

// Create page and log path where video is saved
const page = await context.newPage();
console.log('Page video: ' + await page.video().path());

// Perform action that creates a page
const [editPage] = await Promise.all([
  context.waitForEvent('page'),
  editBtn.click() // Always click after waitForEvent, as in all of our docs, other wise you have a bug
]);

// Log path where video is saved
console.log('Edit page video: ' + await editPage.video().path());
// After context.close() you can find video files in the videos folder.
await context.close();
// Here you can read from those paths.

@louis57
Copy link
Author

louis57 commented Mar 4, 2021

@pavelfeldman Thanks for your answer. I am using helper from playwright-video, this is the complete saveVideo.d.ts

import { Page } from 'playwright-core';
import { CaptureOptions, PageVideoCapture } from './PageVideoCapture';
export declare const saveVideo: (page: Page, savePath: string, options?: CaptureOptions) => Promise<PageVideoCapture>;

So, I tried your suggestions. At the end, I get 3 videos (because my app has 3 windows in total, so one video for one page). But the tests can't be completed even though I used await context.close();

Test Suites: 1 passed, 1 total
Tests: 42 passed, 42 total
Time: 111.998 s, estimated 171 s
Ran all test suites.
Jest did not exit one second after the test run has completed.

This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with --detectOpenHandles to troubleshoot this issue.

I followed the suggested output, but nothing was opened at the end

In this case, it is not possible to record only one video for the whole test suite, isn't it.

@yury-s
Copy link
Member

yury-s commented Mar 11, 2021

playwright-video doesn't use Playwright's built-in video recording API, it does it in its own way so it's better to ask the question in their repo. If you used Playwright video API as Pavel suggested await context.close(); would wait until video recording is finished and output is written to disk.

In this case, it is not possible to record only one video for the whole test suite, isn't it.

With the playwright api you'll have one video file per page.

@louis57 louis57 closed this as completed Mar 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants