diff --git a/kibana-reports/server/executor/createScheduledReport.ts b/kibana-reports/server/executor/createScheduledReport.ts
index 1cc04649..af60bfa5 100644
--- a/kibana-reports/server/executor/createScheduledReport.ts
+++ b/kibana-reports/server/executor/createScheduledReport.ts
@@ -23,7 +23,7 @@ import { ILegacyClusterClient, Logger } from '../../../../src/core/server';
import { createSavedSearchReport } from '../routes/utils/savedSearchReportHelper';
import { ReportSchemaType } from '../model';
import { CreateReportResultType } from '../routes/utils/types';
-import { createVisualReport } from '../routes/utils/visualReportHelper';
+import { createVisualReport } from '../routes/utils/visual_report/visualReportHelper';
import { deliverReport } from '../routes/lib/deliverReport';
import { updateReportState } from '../routes/lib/updateReportState';
diff --git a/kibana-reports/server/routes/lib/createReport.ts b/kibana-reports/server/routes/lib/createReport.ts
index bf051e24..c33c51b8 100644
--- a/kibana-reports/server/routes/lib/createReport.ts
+++ b/kibana-reports/server/routes/lib/createReport.ts
@@ -30,7 +30,7 @@ import {
import { createSavedSearchReport } from '../utils/savedSearchReportHelper';
import { ReportSchemaType } from '../../model';
import { CreateReportResultType } from '../utils/types';
-import { createVisualReport } from '../utils/visualReportHelper';
+import { createVisualReport } from '../utils/visual_report/visualReportHelper';
import { SetCookie } from 'puppeteer';
import { deliverReport } from './deliverReport';
import { updateReportState } from './updateReportState';
diff --git a/kibana-reports/server/routes/utils/__tests__/visualReportHelper.test.ts b/kibana-reports/server/routes/utils/__tests__/visualReportHelper.test.ts
index e5ea93cb..e015bb5a 100644
--- a/kibana-reports/server/routes/utils/__tests__/visualReportHelper.test.ts
+++ b/kibana-reports/server/routes/utils/__tests__/visualReportHelper.test.ts
@@ -14,7 +14,7 @@
*/
import 'regenerator-runtime/runtime';
-import { createVisualReport } from '../visualReportHelper';
+import { createVisualReport } from '../visual_report/visualReportHelper';
import { Logger } from '../../../../../../src/core/server';
import { ReportParamsSchemaType, reportSchema } from '../../../model';
diff --git a/kibana-reports/server/routes/utils/visual_report/report_template.html b/kibana-reports/server/routes/utils/visual_report/report_template.html
new file mode 100644
index 00000000..6f198bce
--- /dev/null
+++ b/kibana-reports/server/routes/utils/visual_report/report_template.html
@@ -0,0 +1,244 @@
+
+
+
+
+
+ Kibana Reports
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/kibana-reports/server/routes/utils/visualReportHelper.ts b/kibana-reports/server/routes/utils/visual_report/visualReportHelper.ts
similarity index 70%
rename from kibana-reports/server/routes/utils/visualReportHelper.ts
rename to kibana-reports/server/routes/utils/visual_report/visualReportHelper.ts
index f9d19b46..5078eca9 100644
--- a/kibana-reports/server/routes/utils/visualReportHelper.ts
+++ b/kibana-reports/server/routes/utils/visual_report/visualReportHelper.ts
@@ -16,16 +16,18 @@
import puppeteer, { ElementHandle, SetCookie } from 'puppeteer';
import createDOMPurify from 'dompurify';
import { JSDOM } from 'jsdom';
-import { Logger } from '../../../../../src/core/server';
+import { Logger } from '../../../../../../src/core/server';
import {
DEFAULT_REPORT_HEADER,
REPORT_TYPE,
FORMAT,
SELECTOR,
-} from './constants';
-import { getFileName } from './helpers';
-import { CreateReportResultType } from './types';
+} from '../constants';
+import { getFileName } from '../helpers';
+import { CreateReportResultType } from '../types';
import { ReportParamsSchemaType, VisualReportSchemaType } from 'server/model';
+import fs from 'fs';
+import cheerio from 'cheerio';
export const createVisualReport = async (
reportParams: ReportParamsSchemaType,
@@ -82,22 +84,33 @@ export const createVisualReport = async (
});
let buffer: Buffer;
- let element: ElementHandle;
// remove top nav bar
await page.evaluate(
/* istanbul ignore next */
(selector) => {
document.querySelector(selector)?.remove();
+ document
+ .querySelectorAll("[class^='euiButton']")
+ .forEach((e) => e.remove());
+ document.querySelector(
+ '.coreSystemRootDomElement.euiBody--headerIsFixed'
+ ).style.paddingTop = '0px';
},
SELECTOR.topNavBar
);
+ // force wait for any resize to load after the above DOM modification
+ await page.waitFor(1000);
// crop content
switch (reportSource) {
case REPORT_TYPE.dashboard:
- element = await page.waitForSelector(SELECTOR.dashboard);
+ await page.waitForSelector(SELECTOR.dashboard, {
+ visible: true,
+ });
break;
case REPORT_TYPE.visualization:
- element = await page.waitForSelector(SELECTOR.visualization);
+ await page.waitForSelector(SELECTOR.visualization, {
+ visible: true,
+ });
break;
default:
throw Error(
@@ -105,33 +118,14 @@ export const createVisualReport = async (
);
}
- const screenshot = await element.screenshot({ fullPage: false });
-
- /**
- * Sets the content of the page to have the header be above the trimmed screenshot
- * and the footer be below it
- */
- // TODO: make all html templates into files, such as reporting context menu button, and embedded html of email body
- await page.setContent(`
-
-
-
-
-
-
-
- ${reportHeader}
-
- ${reportFooter}
-
-
-
- `);
+ const screenshot = await page.screenshot({ fullPage: true });
+
+ const templateHtml = composeReportHtml(
+ reportHeader,
+ reportFooter,
+ screenshot.toString('base64')
+ );
+ await page.setContent(templateHtml);
// create pdf or png accordingly
if (reportFormat === FORMAT.pdf) {
@@ -160,3 +154,27 @@ export const createVisualReport = async (
return { timeCreated, dataUrl: buffer.toString('base64'), fileName };
};
+
+export const composeReportHtml = (
+ header: string,
+ footer: string,
+ screenshot: string
+) => {
+ const $ = cheerio.load(fs.readFileSync(`${__dirname}/report_template.html`), {
+ decodeEntities: false,
+ });
+
+ $('.reportWrapper img').attr('src', `data:image/png;base64,${screenshot}`);
+ $('#reportingHeader > div.mde-preview > div.mde-preview-content').html(
+ header
+ );
+ if (footer === '') {
+ $('#reportingFooter').attr('hidden', 'true');
+ } else {
+ $('#reportingFooter > div.mde-preview > div.mde-preview-content').html(
+ footer
+ );
+ }
+
+ return $.root().html() || '';
+};