Skip to content

Commit

Permalink
Typescript-ify screenshot stitcher code in reporting (#20061) (#20149)
Browse files Browse the repository at this point in the history
* typescript screenshot stitcher

* Throw an error if the data captured is not of the expected width and height.

* Import babel-core types

* Add babel-core types to x-pack package.json

* Dimensions => Rectangle
  • Loading branch information
stacey-gammon authored Jun 22, 2018
1 parent 17f483a commit 17ebccb
Show file tree
Hide file tree
Showing 15 changed files with 486 additions and 262 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@
"@kbn/plugin-generator": "link:packages/kbn-plugin-generator",
"@kbn/test": "link:packages/kbn-test",
"@types/angular": "^1.6.45",
"@types/babel-core": "^6.25.5",
"@types/bluebird": "^3.1.1",
"@types/classnames": "^2.2.3",
"@types/eslint": "^4.16.2",
"@types/execa": "^0.9.0",
Expand Down
3 changes: 2 additions & 1 deletion x-pack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@kbn/plugin-helpers": "link:../packages/kbn-plugin-helpers",
"@kbn/test": "link:../packages/kbn-test",
"@types/jest": "^22.2.3",
"@types/pngjs": "^3.3.1",
"abab": "^1.0.4",
"ansicolors": "0.3.2",
"aws-sdk": "2.2.33",
Expand Down Expand Up @@ -82,6 +83,7 @@
"@elastic/numeral": "2.3.2",
"@kbn/datemath": "link:../packages/kbn-datemath",
"@kbn/ui-framework": "link:../packages/kbn-ui-framework",
"@samverschueren/stream-to-observable": "^0.3.0",
"@slack/client": "^4.2.2",
"angular-paging": "2.2.1",
"angular-resource": "1.4.9",
Expand Down Expand Up @@ -154,7 +156,6 @@
"rison-node": "0.3.1",
"rxjs": "^6.1.0",
"semver": "5.1.0",
"@samverschueren/stream-to-observable": "^0.3.0",
"styled-components": "2.3.2",
"tar-fs": "1.13.0",
"tinycolor2": "1.3.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export class HeadlessChromiumDriver {
scale: 1
}
});
this._logger.debug(`captured screenshot clip ${JSON.stringify(screenshotClip)}`);
this._logger.debug(`Captured screenshot clip ${JSON.stringify(screenshotClip)}`);
return data;
}, this._logger);
}
Expand All @@ -112,6 +112,7 @@ export class HeadlessChromiumDriver {
}

async setViewport({ width, height, zoom }) {
this._logger.debug(`Setting viewport to width: ${width}, height: ${height}, zoom: ${zoom}`);
const { Emulation } = this._client;

await Emulation.setDeviceMetricsOverride({
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

// No types found for this package. May want to investigate an alternative with types.
// @ts-ignore: implicit any for JS file
import $streamToObservable from '@samverschueren/stream-to-observable';
import { PNG } from 'pngjs';
import * as Rx from 'rxjs';
import { ObservableInput } from 'rxjs';
import { map, mergeMap, reduce, switchMap, tap, toArray } from 'rxjs/operators';
import { Logger, Screenshot, Size } from './types';

// if we're only given one screenshot, and it matches the given size
// we're going to skip the combination and just use it
const canUseFirstScreenshot = (
screenshots: Screenshot[],
size: { width: number; height: number }
) => {
if (screenshots.length !== 1) {
return false;
}

const firstScreenshot = screenshots[0];
return (
firstScreenshot.rectangle.width === size.width &&
firstScreenshot.rectangle.height === size.height
);
};

/**
* Combines the screenshot clips into a single screenshot of size `outputSize`.
* @param screenshots - Array of screenshots to combine
* @param outputSize - Final output size that the screenshots should match up with
* @param logger - logger for extra debug output
*/
export function $combine(
screenshots: Screenshot[],
outputSize: Size,
logger: Logger
): Rx.Observable<string> {
logger.debug(
`Combining screenshot clips into final, scaled output dimension of ${JSON.stringify(
outputSize
)}`
);

if (screenshots.length === 0) {
return Rx.throwError('Unable to combine 0 screenshots');
}

if (canUseFirstScreenshot(screenshots, outputSize)) {
return Rx.of(screenshots[0].data);
}

// Turn the screenshot data into actual PNGs
const pngs$ = Rx.from(screenshots).pipe(
mergeMap(
(screenshot: Screenshot): ObservableInput<PNG> => {
const png = new PNG();
const buffer = Buffer.from(screenshot.data, 'base64');
const parseAsObservable = Rx.bindNodeCallback(png.parse.bind(png));
return parseAsObservable(buffer);
},
(screenshot: Screenshot, png: PNG) => {
if (
png.width !== screenshot.rectangle.width ||
png.height !== screenshot.rectangle.height
) {
const errorMessage = `Screenshot captured with width:${
png.width
} and height: ${png.height}) is not of expected width: ${
screenshot.rectangle.width
} and height: ${screenshot.rectangle.height}`;

logger.error(errorMessage);
throw new Error(errorMessage);
}
return { screenshot, png };
}
)
);

const output$ = pngs$.pipe(
reduce((output: PNG, input: { screenshot: Screenshot; png: PNG }) => {
const { png, screenshot } = input;
// Spitting out a lot of output to help debug https://github.com/elastic/kibana/issues/19563. Once that is
// fixed, this should probably get pared down.
logger.debug(`Output dimensions is ${JSON.stringify(outputSize)}`);
logger.debug(`Input png w: ${png.width} and h: ${png.height}`);
logger.debug(
`Creating output png with ${JSON.stringify(screenshot.rectangle)}`
);
const { rectangle } = screenshot;
png.bitblt(
output,
0,
0,
rectangle.width,
rectangle.height,
rectangle.x,
rectangle.y
);
return output;
}, new PNG({ width: outputSize.width, height: outputSize.height }))
);

return output$.pipe(
tap(png => png.pack()),
switchMap<PNG, Buffer>($streamToObservable),
toArray(),
map((chunks: Buffer[]) => Buffer.concat(chunks).toString('base64'))
);
}

This file was deleted.

This file was deleted.

Loading

0 comments on commit 17ebccb

Please sign in to comment.