Skip to content

Commit

Permalink
use page.pdf function
Browse files Browse the repository at this point in the history
  • Loading branch information
jloleysens committed Apr 12, 2022
1 parent cc89f84 commit 31537c8
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 42 deletions.
10 changes: 10 additions & 0 deletions x-pack/plugins/screenshotting/server/browsers/chromium/driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,16 @@ export class HeadlessChromiumDriver {
return !this.page.isClosed();
}

async printA4Pdf(): Promise<Buffer> {
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
*/
Expand Down
52 changes: 30 additions & 22 deletions x-pack/plugins/screenshotting/server/formats/pdf/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,27 +98,35 @@ export async function toPdf(
{ metrics, results }: CaptureResult
): Promise<PdfScreenshotResult> {
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 ?? []),
};
}
25 changes: 25 additions & 0 deletions x-pack/plugins/screenshotting/server/screenshots/get_pdf.ts
Original file line number Diff line number Diff line change
@@ -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<Screenshot[]> {
logger.info('printing PDF');

return [
{
data: await browser.printA4Pdf(),
title: null,
description: null,
},
];
}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/screenshotting/server/screenshots/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
10 changes: 7 additions & 3 deletions x-pack/plugins/screenshotting/server/screenshots/observable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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';
Expand Down Expand Up @@ -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);
}
Expand Down
23 changes: 23 additions & 0 deletions x-pack/plugins/screenshotting/server/screenshots/types.ts
Original file line number Diff line number Diff line change
@@ -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;
}

0 comments on commit 31537c8

Please sign in to comment.