diff --git a/x-pack/plugins/reporting/public/components/job_download_button.tsx b/x-pack/plugins/reporting/public/components/job_download_button.tsx index 70bcf3dac7666..911a19c0176c2 100644 --- a/x-pack/plugins/reporting/public/components/job_download_button.tsx +++ b/x-pack/plugins/reporting/public/components/job_download_button.tsx @@ -15,18 +15,12 @@ interface Props { } export const DownloadButton = ({ getUrl, job }: Props) => { - const downloadReport = () => { - window.open(getUrl(job.id)); - }; - return ( { - downloadReport(); - }} + href={getUrl(job.id)} + target="_blank" > { // load test data that contains a saved search and documents - await esArchiver.load('reporting/scripted'); + await esArchiver.load('reporting/scripted_small'); const { status: resStatus, @@ -121,7 +121,7 @@ export default function({ getService }: { getService: any }) { expect(resType).to.eql('text/csv'); expect(resText).to.eql(CSV_RESULT_SCRIPTED); - await esArchiver.unload('reporting/scripted'); + await esArchiver.unload('reporting/scripted_small'); }); it('Formatted date_nanos data', async () => { @@ -187,7 +187,7 @@ export default function({ getService }: { getService: any }) { it('Stops at Max Size Reached', async () => { // load test data that contains a saved search and documents - await esArchiver.load('reporting/scripted'); + await esArchiver.load('reporting/hugedata'); const { status: resStatus, @@ -209,14 +209,14 @@ export default function({ getService }: { getService: any }) { expect(resType).to.eql('text/csv'); expect(resText).to.eql(CSV_RESULT_HUGE); - await esArchiver.unload('reporting/scripted'); + await esArchiver.unload('reporting/hugedata'); }); }); describe('Merge user state into the query', () => { it('for query', async () => { // load test data that contains a saved search and documents - await esArchiver.load('reporting/scripted'); + await esArchiver.load('reporting/scripted_small'); const params = { searchId: 'search:f34bf440-5014-11e9-bce7-4dabcb8bef24', @@ -240,12 +240,12 @@ export default function({ getService }: { getService: any }) { expect(resType).to.eql('text/csv'); expect(resText).to.eql(CSV_RESULT_SCRIPTED_REQUERY); - await esArchiver.unload('reporting/scripted'); + await esArchiver.unload('reporting/scripted_small'); }); it('for sort', async () => { // load test data that contains a saved search and documents - await esArchiver.load('reporting/scripted'); + await esArchiver.load('reporting/hugedata'); const { status: resStatus, @@ -267,7 +267,7 @@ export default function({ getService }: { getService: any }) { expect(resType).to.eql('text/csv'); expect(resText).to.eql(CSV_RESULT_SCRIPTED_RESORTED); - await esArchiver.unload('reporting/scripted'); + await esArchiver.unload('reporting/hugedata'); }); it('for docvalue_fields', async () => { @@ -337,7 +337,7 @@ export default function({ getService }: { getService: any }) { describe.skip('Non-Immediate', () => { it('using queries in job params', async () => { // load test data that contains a saved search and documents - await esArchiver.load('reporting/scripted'); + await esArchiver.load('reporting/scripted_small'); const params = { searchId: 'search:f34bf440-5014-11e9-bce7-4dabcb8bef24', @@ -425,7 +425,7 @@ export default function({ getService }: { getService: any }) { }, 5000); // x-pack/test/functional/config settings are inherited, uses 3 seconds for polling interval. }); - await esArchiver.unload('reporting/scripted'); + await esArchiver.unload('reporting/scripted_small'); }); }); }); diff --git a/x-pack/test/reporting/api/generate/fixtures.ts b/x-pack/test/reporting/api/generate/fixtures.ts index 2dac3dde7d29e..c68e417498917 100644 --- a/x-pack/test/reporting/api/generate/fixtures.ts +++ b/x-pack/test/reporting/api/generate/fixtures.ts @@ -82,32 +82,12 @@ export const CSV_RESULT_TIMELESS = `name,power `; export const CSV_RESULT_SCRIPTED = `date,year,name,value,"years_ago" -"1981-01-01T00:00:00.000Z",1981,Fetty,1763,38 -"1981-01-01T00:00:00.000Z",1981,Fonnie,2330,38 -"1981-01-01T00:00:00.000Z",1981,Farbara,6456,38 "1981-01-01T00:00:00.000Z",1981,Felinda,1886,38 -"1981-01-01T00:00:00.000Z",1981,Frenda,7162,38 -"1981-01-01T00:00:00.000Z",1981,Feth,3685,38 -"1981-01-01T00:00:00.000Z",1981,Feverly,1987,38 -"1981-01-01T00:00:00.000Z",1981,Fecky,1930,38 -"1980-01-01T00:00:00.000Z",1980,Fonnie,2748,39 -"1980-01-01T00:00:00.000Z",1980,Frenda,8335,39 -"1980-01-01T00:00:00.000Z",1980,Fetty,1967,39 -"1980-01-01T00:00:00.000Z",1980,Farbara,8026,39 -"1980-01-01T00:00:00.000Z",1980,Feth,4246,39 -"1980-01-01T00:00:00.000Z",1980,Feverly,2249,39 "1980-01-01T00:00:00.000Z",1980,Fecky,2071,39 `; export const CSV_RESULT_SCRIPTED_REQUERY = `date,year,name,value,"years_ago" -"1981-01-01T00:00:00.000Z",1981,Fetty,1763,38 "1981-01-01T00:00:00.000Z",1981,Felinda,1886,38 -"1981-01-01T00:00:00.000Z",1981,Feth,3685,38 -"1981-01-01T00:00:00.000Z",1981,Feverly,1987,38 -"1981-01-01T00:00:00.000Z",1981,Fecky,1930,38 -"1980-01-01T00:00:00.000Z",1980,Fetty,1967,39 -"1980-01-01T00:00:00.000Z",1980,Feth,4246,39 -"1980-01-01T00:00:00.000Z",1980,Feverly,2249,39 "1980-01-01T00:00:00.000Z",1980,Fecky,2071,39 `; diff --git a/x-pack/test/reporting/configs/chromium_api.js b/x-pack/test/reporting/configs/chromium_api.js index 98235f433681e..95649dfb5d7a3 100644 --- a/x-pack/test/reporting/configs/chromium_api.js +++ b/x-pack/test/reporting/configs/chromium_api.js @@ -26,6 +26,7 @@ export default async function({ readConfigFile }) { ...functionalConfig.get('kbnTestServer.serverArgs'), '--logging.events.log', '["info","warning","error","fatal","optimize","reporting"]', + '--xpack.endpoint.enabled=true', '--xpack.reporting.csv.enablePanelActionDownload=true', '--xpack.reporting.capture.maxAttempts=1', '--xpack.security.session.idleTimeout=3600000', diff --git a/x-pack/test/reporting/configs/chromium_functional.js b/x-pack/test/reporting/configs/chromium_functional.js index dc5b6eb8038c7..753d2b2a20ab9 100644 --- a/x-pack/test/reporting/configs/chromium_functional.js +++ b/x-pack/test/reporting/configs/chromium_functional.js @@ -24,7 +24,10 @@ export default async function({ readConfigFile }) { ...functionalConfig.get('kbnTestServer.serverArgs'), '--logging.events.log', '["info","warning","error","fatal","optimize","reporting"]', + '--xpack.endpoint.enabled=true', '--xpack.reporting.csv.enablePanelActionDownload=true', + '--xpack.reporting.csv.checkForFormulas=false', + '--xpack.reporting.csv.maxSizeBytes=25000000', '--xpack.security.session.idleTimeout=3600000', '--xpack.spaces.enabled=false', ], diff --git a/x-pack/test/reporting/functional/reporting.js b/x-pack/test/reporting/functional/reporting.js index 86fe2fd0393ef..c1a2ae634662c 100644 --- a/x-pack/test/reporting/functional/reporting.js +++ b/x-pack/test/reporting/functional/reporting.js @@ -5,6 +5,15 @@ */ import expect from '@kbn/expect'; +import path from 'path'; +import fs from 'fs'; +import { promisify } from 'util'; +import { checkIfPngsMatch } from './lib'; + +const writeFileAsync = promisify(fs.writeFile); +const mkdirAsync = promisify(fs.mkdir); + +const REPORTS_FOLDER = path.resolve(__dirname, 'reports'); /* * TODO Remove this file and spread the tests to various apps @@ -14,6 +23,7 @@ export default function({ getService, getPageObjects }) { const esArchiver = getService('esArchiver'); const browser = getService('browser'); const log = getService('log'); + const config = getService('config'); const filterBar = getService('filterBar'); const PageObjects = getPageObjects([ 'reporting', @@ -54,7 +64,7 @@ export default function({ getService, getPageObjects }) { }); describe('Print Layout', () => { - it('Job completes and generates a download URL', async function() { + it('downloads a PDF file', async function() { // Generating and then comparing reports can take longer than the default 60s timeout because the comparePngs // function is taking about 15 seconds per comparison in jenkins. this.timeout(300000); @@ -65,7 +75,10 @@ export default function({ getService, getPageObjects }) { await PageObjects.reporting.clickGenerateReportButton(); const url = await PageObjects.reporting.getReportURL(60000); - expect(url).to.match(/download/); + const res = await PageObjects.reporting.getResponse(url); + + expect(res.statusCode).to.equal(200); + expect(res.headers['content-type']).to.equal('application/pdf'); }); }); @@ -85,8 +98,23 @@ export default function({ getService, getPageObjects }) { }); describe('Preserve Layout', () => { - it('Job completes and generates a download URL', async function() { + it('matches baseline report', async function() { + const writeSessionReport = async (name, rawPdf, reportExt) => { + const sessionDirectory = path.resolve(REPORTS_FOLDER, 'session'); + await mkdirAsync(sessionDirectory, { recursive: true }); + const sessionReportPath = path.resolve(sessionDirectory, `${name}.${reportExt}`); + await writeFileAsync(sessionReportPath, rawPdf); + return sessionReportPath; + }; + const getBaselineReportPath = (fileName, reportExt) => { + const baselineFolder = path.resolve(REPORTS_FOLDER, 'baseline'); + const fullPath = path.resolve(baselineFolder, `${fileName}.${reportExt}`); + log.debug(`getBaselineReportPath (${fullPath})`); + return fullPath; + }; + this.timeout(300000); + await PageObjects.common.navigateToApp('dashboard'); await PageObjects.dashboard.loadSavedDashboard('Ecom Dashboard'); await PageObjects.reporting.openPngReportingPanel(); @@ -95,7 +123,17 @@ export default function({ getService, getPageObjects }) { await PageObjects.reporting.removeForceSharedItemsContainerSize(); const url = await PageObjects.reporting.getReportURL(60000); - expect(url).to.match(/download/); + const reportData = await PageObjects.reporting.getRawPdfReportData(url); + const reportFileName = 'dashboard_preserve_layout'; + const sessionReportPath = await writeSessionReport(reportFileName, reportData, 'png'); + const percentSimilar = await checkIfPngsMatch( + sessionReportPath, + getBaselineReportPath(reportFileName, 'png'), + config.get('screenshots.directory'), + log + ); + + expect(percentSimilar).to.be.lessThan(0.1); }); }); }); @@ -191,7 +229,7 @@ export default function({ getService, getPageObjects }) { expect(await PageObjects.reporting.isGenerateReportButtonDisabled()).to.be(null); }); - it('Job completes and generates a download URL', async function() { + it('downloaded PDF has OK status', async function() { // Generating and then comparing reports can take longer than the default 60s timeout because the comparePngs // function is taking about 15 seconds per comparison in jenkins. this.timeout(180000); @@ -202,7 +240,10 @@ export default function({ getService, getPageObjects }) { await PageObjects.reporting.clickGenerateReportButton(); const url = await PageObjects.reporting.getReportURL(60000); - expect(url).to.match(/download/); + const res = await PageObjects.reporting.getResponse(url); + + expect(res.statusCode).to.equal(200); + expect(res.headers['content-type']).to.equal('application/pdf'); }); }); });