From 31537c83873cb298d47227bc93f081ce1d26091a Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Tue, 12 Apr 2022 10:47:24 +0200 Subject: [PATCH] use page.pdf function --- .../server/browsers/chromium/driver.ts | 10 ++++ .../server/formats/pdf/index.ts | 52 +++++++++++-------- .../server/screenshots/get_pdf.ts | 25 +++++++++ .../server/screenshots/get_screenshots.ts | 18 +------ .../server/screenshots/index.ts | 1 + .../server/screenshots/observable.ts | 10 ++-- .../server/screenshots/types.ts | 23 ++++++++ 7 files changed, 97 insertions(+), 42 deletions(-) create mode 100644 x-pack/plugins/screenshotting/server/screenshots/get_pdf.ts create mode 100644 x-pack/plugins/screenshotting/server/screenshots/types.ts diff --git a/x-pack/plugins/screenshotting/server/browsers/chromium/driver.ts b/x-pack/plugins/screenshotting/server/browsers/chromium/driver.ts index f9bf31ad35f6f..390917db227be 100644 --- a/x-pack/plugins/screenshotting/server/browsers/chromium/driver.ts +++ b/x-pack/plugins/screenshotting/server/browsers/chromium/driver.ts @@ -155,6 +155,16 @@ export class HeadlessChromiumDriver { return !this.page.isClosed(); } + async printA4Pdf(): Promise { + return this.page.pdf({ + format: 'a4', + preferCSSPageSize: true, + scale: 1, + landscape: false, + displayHeaderFooter: true, + }); + } + /* * Call Page.screenshot and return a base64-encoded string of the image */ diff --git a/x-pack/plugins/screenshotting/server/formats/pdf/index.ts b/x-pack/plugins/screenshotting/server/formats/pdf/index.ts index 7364ec210313a..0e79d96ef84d1 100644 --- a/x-pack/plugins/screenshotting/server/formats/pdf/index.ts +++ b/x-pack/plugins/screenshotting/server/formats/pdf/index.ts @@ -98,27 +98,35 @@ export async function toPdf( { metrics, results }: CaptureResult ): Promise { const timeRange = getTimeRange(results); - try { - const { buffer, pages } = await pngsToPdf({ - title: title ? `${title}${timeRange ? ` - ${timeRange}` : ''}` : undefined, - results, - layout, - logo, - logger, - }); - - return { - metrics: { - ...(metrics ?? {}), - pages, - }, - data: buffer, - errors: results.flatMap(({ error }) => (error ? [error] : [])), - renderErrors: results.flatMap(({ renderErrors }) => renderErrors ?? []), - }; - } catch (error) { - logger.error(`Could not generate the PDF buffer!`); - - throw error; + let buffer: Buffer; + let pages: number; + const shouldConvertPngsToPdf = layout.id !== LayoutTypes.PRINT; + if (shouldConvertPngsToPdf) { + try { + ({ buffer, pages } = await pngsToPdf({ + title: title ? `${title}${timeRange ? ` - ${timeRange}` : ''}` : undefined, + results, + layout, + logo, + logger, + })); + } catch (error) { + logger.error(`Could not generate the PDF buffer!`); + + throw error; + } + } else { + buffer = results[0].screenshots[0].data; + pages = -1; // TODO: Figure out how to get page numbers } + + return { + metrics: { + ...(metrics ?? {}), + pages, + }, + data: buffer, + errors: results.flatMap(({ error }) => (error ? [error] : [])), + renderErrors: results.flatMap(({ renderErrors }) => renderErrors ?? []), + }; } diff --git a/x-pack/plugins/screenshotting/server/screenshots/get_pdf.ts b/x-pack/plugins/screenshotting/server/screenshots/get_pdf.ts new file mode 100644 index 0000000000000..9b9629c3ab9af --- /dev/null +++ b/x-pack/plugins/screenshotting/server/screenshots/get_pdf.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger } from 'src/core/server'; +import type { HeadlessChromiumDriver } from '../browsers'; +import type { Screenshot } from './types'; + +export async function getPdf( + browser: HeadlessChromiumDriver, + logger: Logger +): Promise { + logger.info('printing PDF'); + + return [ + { + data: await browser.printA4Pdf(), + title: null, + description: null, + }, + ]; +} diff --git a/x-pack/plugins/screenshotting/server/screenshots/get_screenshots.ts b/x-pack/plugins/screenshotting/server/screenshots/get_screenshots.ts index 26ef272e7f18e..6899b9328736d 100644 --- a/x-pack/plugins/screenshotting/server/screenshots/get_screenshots.ts +++ b/x-pack/plugins/screenshotting/server/screenshots/get_screenshots.ts @@ -9,23 +9,7 @@ import apm from 'elastic-apm-node'; import type { Logger } from 'src/core/server'; import type { HeadlessChromiumDriver } from '../browsers'; import type { ElementsPositionAndAttribute } from './get_element_position_data'; - -export interface Screenshot { - /** - * Screenshot PNG image data. - */ - data: Buffer; - - /** - * Screenshot title. - */ - title: string | null; - - /** - * Screenshot description. - */ - description: string | null; -} +import type { Screenshot } from './types'; export const getScreenshots = async ( browser: HeadlessChromiumDriver, diff --git a/x-pack/plugins/screenshotting/server/screenshots/index.ts b/x-pack/plugins/screenshotting/server/screenshots/index.ts index 8672babe8b514..d800abc42a451 100644 --- a/x-pack/plugins/screenshotting/server/screenshots/index.ts +++ b/x-pack/plugins/screenshotting/server/screenshots/index.ts @@ -26,6 +26,7 @@ import type { HttpServiceSetup, KibanaRequest, Logger } from 'src/core/server'; import type { ExpressionAstExpression } from 'src/plugins/expressions/common'; import { LayoutParams, + LayoutTypes, SCREENSHOTTING_APP_ID, SCREENSHOTTING_EXPRESSION, SCREENSHOTTING_EXPRESSION_INPUT, diff --git a/x-pack/plugins/screenshotting/server/screenshots/observable.ts b/x-pack/plugins/screenshotting/server/screenshots/observable.ts index fbc147102e0af..ec08c61456c0d 100644 --- a/x-pack/plugins/screenshotting/server/screenshots/observable.ts +++ b/x-pack/plugins/screenshotting/server/screenshots/observable.ts @@ -9,7 +9,7 @@ import type { Transaction } from 'elastic-apm-node'; import { defer, forkJoin, throwError, Observable } from 'rxjs'; import { catchError, mergeMap, switchMapTo, timeoutWith } from 'rxjs/operators'; import type { Headers, Logger } from 'src/core/server'; -import { errors } from '../../common'; +import { errors, LayoutTypes } from '../../common'; import type { Context, HeadlessChromiumDriver } from '../browsers'; import { getChromiumDisconnectedError, DEFAULT_VIEWPORT } from '../browsers'; import type { Layout } from '../layouts'; @@ -18,7 +18,8 @@ import { getElementPositionAndAttributes } from './get_element_position_data'; import { getNumberOfItems } from './get_number_of_items'; import { getRenderErrors } from './get_render_errors'; import { getScreenshots } from './get_screenshots'; -import type { Screenshot } from './get_screenshots'; +import { getPdf } from './get_pdf'; +import type { Screenshot } from './types'; import { getTimeRange } from './get_time_range'; import { injectCustomCss } from './inject_css'; import { openUrl } from './open_url'; @@ -247,7 +248,10 @@ export class ScreenshotObservableHandler { getDefaultElementPosition(this.layout.getViewport(1)); let screenshots: Screenshot[] = []; try { - screenshots = await getScreenshots(this.driver, this.logger, elements); + screenshots = + this.layout.id === LayoutTypes.PRINT + ? await getPdf(this.driver, this.logger) + : await getScreenshots(this.driver, this.logger, elements); } catch (e) { throw new errors.FailedToCaptureScreenshot(e.message); } diff --git a/x-pack/plugins/screenshotting/server/screenshots/types.ts b/x-pack/plugins/screenshotting/server/screenshots/types.ts new file mode 100644 index 0000000000000..d4a408313fc43 --- /dev/null +++ b/x-pack/plugins/screenshotting/server/screenshots/types.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export interface Screenshot { + /** + * Screenshot PNG image data. + */ + data: Buffer; + + /** + * Screenshot title. + */ + title: string | null; + + /** + * Screenshot description. + */ + description: string | null; +}