-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* [Reporting/Test] Add Functional test for download CSV * add todo * add fs.existsSync check to find download * debug * handle timeout * validate toast * different way of getting repo_root Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
- Loading branch information
1 parent
2d08f42
commit 0a07c8e
Showing
5 changed files
with
203 additions
and
121 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
68 changes: 68 additions & 0 deletions
68
x-pack/test/functional/apps/dashboard/reporting/download_csv.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* 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. | ||
*/ | ||
|
||
import { REPO_ROOT } from '@kbn/dev-utils'; | ||
import expect from '@kbn/expect'; | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
import * as Rx from 'rxjs'; | ||
import { filter, first, map, timeout } from 'rxjs/operators'; | ||
import { FtrProviderContext } from '../../../ftr_provider_context'; | ||
|
||
const csvPath = path.resolve(REPO_ROOT, 'target/functional-tests/downloads/Ecommerce Data.csv'); | ||
|
||
export default function({ getService, getPageObjects }: FtrProviderContext) { | ||
const esArchiver = getService('esArchiver'); | ||
const browser = getService('browser'); | ||
const dashboardPanelActions = getService('dashboardPanelActions'); | ||
const log = getService('log'); | ||
const testSubjects = getService('testSubjects'); | ||
const PageObjects = getPageObjects(['reporting', 'common', 'dashboard']); | ||
|
||
describe('Reporting Download CSV', () => { | ||
before('initialize tests', async () => { | ||
log.debug('ReportingPage:initTests'); | ||
await esArchiver.loadIfNeeded('reporting/ecommerce'); | ||
await esArchiver.loadIfNeeded('reporting/ecommerce_kibana'); | ||
await browser.setWindowSize(1600, 850); | ||
}); | ||
|
||
after('clean up archives and previous file download', async () => { | ||
await esArchiver.unload('reporting/ecommerce'); | ||
await esArchiver.unload('reporting/ecommerce_kibana'); | ||
try { | ||
fs.unlinkSync(csvPath); | ||
} catch (e) { | ||
// nothing to worry | ||
} | ||
}); | ||
|
||
it('Downloads a CSV export of a saved search panel', async function() { | ||
await PageObjects.common.navigateToApp('dashboard'); | ||
await PageObjects.dashboard.loadSavedDashboard('Ecom Dashboard'); | ||
const savedSearchPanel = await testSubjects.find('embeddablePanelHeading-EcommerceData'); | ||
await dashboardPanelActions.toggleContextMenu(savedSearchPanel); | ||
|
||
await testSubjects.existOrFail('embeddablePanelAction-downloadCsvReport'); // wait for the full panel to display or else the test runner could click the wrong option! | ||
await testSubjects.click('embeddablePanelAction-downloadCsvReport'); | ||
await testSubjects.existOrFail('csvDownloadStarted'); // validate toast panel | ||
|
||
// check every 100ms for the file to exist in the download dir | ||
// just wait up to 5 seconds | ||
const success$ = Rx.interval(100).pipe( | ||
map(() => fs.existsSync(csvPath)), | ||
filter(value => value === true), | ||
first(), | ||
timeout(5000) | ||
); | ||
|
||
const fileExists = await success$.toPromise(); | ||
expect(fileExists).to.be(true); | ||
|
||
// no need to validate download contents, API Integration tests do that some different variations | ||
}); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 127 additions & 0 deletions
127
x-pack/test/functional/apps/dashboard/reporting/screenshots.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
/* | ||
* 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. | ||
*/ | ||
|
||
import expect from '@kbn/expect'; | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
import { promisify } from 'util'; | ||
import { FtrProviderContext } from '../../../ftr_provider_context'; | ||
import { checkIfPngsMatch } from './lib/compare_pngs'; | ||
|
||
const writeFileAsync = promisify(fs.writeFile); | ||
const mkdirAsync = promisify(fs.mkdir); | ||
|
||
const REPORTS_FOLDER = path.resolve(__dirname, 'reports'); | ||
|
||
export default function({ getService, getPageObjects }: FtrProviderContext) { | ||
const esArchiver = getService('esArchiver'); | ||
const browser = getService('browser'); | ||
const log = getService('log'); | ||
const config = getService('config'); | ||
const PageObjects = getPageObjects(['reporting', 'common', 'dashboard']); | ||
|
||
describe('Screenshots', () => { | ||
before('initialize tests', async () => { | ||
log.debug('ReportingPage:initTests'); | ||
await esArchiver.loadIfNeeded('reporting/ecommerce'); | ||
await esArchiver.loadIfNeeded('reporting/ecommerce_kibana'); | ||
await browser.setWindowSize(1600, 850); | ||
}); | ||
after('clean up archives', async () => { | ||
await esArchiver.unload('reporting/ecommerce'); | ||
await esArchiver.unload('reporting/ecommerce_kibana'); | ||
}); | ||
|
||
describe('Print PDF button', () => { | ||
it('is not available if new', async () => { | ||
await PageObjects.common.navigateToApp('dashboard'); | ||
await PageObjects.dashboard.clickNewDashboard(); | ||
await PageObjects.reporting.openPdfReportingPanel(); | ||
expect(await PageObjects.reporting.isGenerateReportButtonDisabled()).to.be('true'); | ||
}); | ||
|
||
it('becomes available when saved', async () => { | ||
await PageObjects.dashboard.saveDashboard('My PDF Dashboard'); | ||
await PageObjects.reporting.openPdfReportingPanel(); | ||
expect(await PageObjects.reporting.isGenerateReportButtonDisabled()).to.be(null); | ||
}); | ||
}); | ||
|
||
describe('Print Layout', () => { | ||
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); | ||
await PageObjects.common.navigateToApp('dashboard'); | ||
await PageObjects.dashboard.loadSavedDashboard('Ecom Dashboard'); | ||
await PageObjects.reporting.openPdfReportingPanel(); | ||
await PageObjects.reporting.checkUsePrintLayout(); | ||
await PageObjects.reporting.clickGenerateReportButton(); | ||
|
||
const url = await PageObjects.reporting.getReportURL(60000); | ||
const res = await PageObjects.reporting.getResponse(url); | ||
|
||
expect(res.statusCode).to.equal(200); | ||
expect(res.headers['content-type']).to.equal('application/pdf'); | ||
}); | ||
}); | ||
|
||
describe('Print PNG button', () => { | ||
it('is not available if new', async () => { | ||
await PageObjects.common.navigateToApp('dashboard'); | ||
await PageObjects.dashboard.clickNewDashboard(); | ||
await PageObjects.reporting.openPngReportingPanel(); | ||
expect(await PageObjects.reporting.isGenerateReportButtonDisabled()).to.be('true'); | ||
}); | ||
|
||
it('becomes available when saved', async () => { | ||
await PageObjects.dashboard.saveDashboard('My PNG Dash'); | ||
await PageObjects.reporting.openPngReportingPanel(); | ||
expect(await PageObjects.reporting.isGenerateReportButtonDisabled()).to.be(null); | ||
}); | ||
}); | ||
|
||
describe('Preserve Layout', () => { | ||
it('matches baseline report', async function() { | ||
const writeSessionReport = async (name: string, rawPdf: Buffer, reportExt: string) => { | ||
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: string, reportExt: string) => { | ||
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(); | ||
await PageObjects.reporting.forceSharedItemsContainerSize({ width: 1405 }); | ||
await PageObjects.reporting.clickGenerateReportButton(); | ||
await PageObjects.reporting.removeForceSharedItemsContainerSize(); | ||
|
||
const url = await PageObjects.reporting.getReportURL(60000); | ||
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); | ||
}); | ||
}); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters