xk6-browser icon indicating copy to clipboard operation
xk6-browser copied to clipboard

Implement `Page.pdf([options])`

Open robingustafsson opened this issue 4 years ago • 4 comments

Add support for Page.pdf([options]), to saving a page down to a PDF file.

Relevant links:

  • Playwright docs: https://playwright.dev/docs/next/api/class-page#page-pdf
  • xk6-browser code for Page.pdf([options]): https://github.com/grafana/xk6-browser/blob/main/common/page.go#L504
  • Playwright code: https://github.com/microsoft/playwright/blob/master/packages/playwright-core/src/server/chromium/crPdf.ts
  • Playwright tests: https://github.com/microsoft/playwright/blob/master/tests/pdf.spec.ts

robingustafsson avatar Nov 12 '21 09:11 robingustafsson

Unlike browser downloads (#98), which happen entirely on the browser side AFAIU, this would return the PDF data to the JS script, right? From there the user could upload the file somewhere or inspect it directly, but k6 can't write it to the filesystem, unless we use something like xk6-file, which would run into issues with more than one VU. I guess we could template the filename per VU, or something like that.

How do you envision this working @robingustafsson?

imiric avatar Nov 12 '21 10:11 imiric

Yes, it would be returned to the JS script (see Page.printToPDF()).

The user should be able to specify a path option to save the file to the filesystem, same as with Page.screenshot() and ElementHandle.screenshot(). This raises issues with disk writes while running the test, yes. We'll need to find a solution that would both work for the single VU functional test use case where writing to disk makes sense (but perhaps async off-thread) as well as when running in a load test with many VUs where writing directly to disk for every VU doesn't make as much sense.

Same situation for video capture in https://github.com/grafana/xk6-browser/issues/103.

Let's start with the use cases as I seem them:

  • 1 VU: Take a screenshot to verify that page/app is rendered as is expected (this can both be a manual verification by a human or automated using visual diffing as would be possible with expect(screenshot).toMatchSnapshot(filename).
  • 1 VU: Render HTML document to a PDF as part of using xk6-browser to implement a feature in some other software (I know that our collegues on the Grafana team uses Puppeteer for this today when preparing exports/reports based on dashboards)
  • 1 VU: Capture a video of a test scenario to get a visual representation of how fast pages/apps load
  • >1 VU: Capture screenshots when an error happpens (user would probably need to define what constitues an error)
  • >1 VU: Capture video from 1 VU per <scenario, load zone> tuple to again get a visual representation of what a the end-user experience is like on a page or in an app

I don't have a ready solution how to implement this in terms of APIs/options right now :sweat_smile: but I'm confident we can come up with something that will work.

robingustafsson avatar Nov 12 '21 11:11 robingustafsson

Perhaps @nicolevanderhoeven and @tom-miseur can fill in with more use cases for screenshots, videos, PDFs and downloads.

robingustafsson avatar Nov 12 '21 12:11 robingustafsson

+1 to everything Robin said. Some other use cases I can think of:

  • Video streaming: Take a screenshot now, click the play button, and then take a screenshot every 10 seconds to verify that the video is playing. When the screenshot stops changing, click on another video. A video instead of a screenshot would be awesome here too.
  • (Eventually) Cross-browser testing: Compare screenshots from different browsers to verify that the app is rendered correctly everywhere.
  • Generating test data: Download bank statements (as PDF or CSV) and upload them to a mortgage application form.
  • Virtualization, SAP: Take a screenshot to verify elements not accessible to the DOM, like potentially SAP legacy apps on Netweaver.

nicolevanderhoeven avatar Nov 12 '21 13:11 nicolevanderhoeven