[test/functional/services] tsfy FailureDebugging, SavedQueryManagementComponent & Snapshots (#45682) (#45866)

* [test/functional/services] tsfy failure_debugging, snapshots, saved_query_management_component

* update renovate config

* fix path in snapshot service
This commit is contained in:
Dmitry Lemeshko 2019-09-17 18:06:15 +02:00 committed by GitHub
parent 7d35d8aef1
commit 5e1072e452
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 81 additions and 51 deletions

View file

@ -316,6 +316,7 @@
"@types/markdown-it": "^0.0.7",
"@types/minimatch": "^2.0.29",
"@types/mocha": "^5.2.6",
"@types/mkdirp": "^0.5.2",
"@types/moment-timezone": "^0.5.8",
"@types/mustache": "^0.8.31",
"@types/node": "^10.12.27",

View file

@ -17,16 +17,24 @@
* under the License.
*/
import mkdirp from 'mkdirp';
import { resolve } from 'path';
import { writeFile } from 'fs';
import mkdirp from 'mkdirp';
import del from 'del';
import { promisify } from 'bluebird';
import Bluebird, { promisify } from 'bluebird';
import { FtrProviderContext } from '../ftr_provider_context';
const writeFileAsync = promisify(writeFile);
const mkdirAsync = promisify(mkdirp);
interface Test {
fullTitle(): string;
}
export async function FailureDebuggingProvider({ getService }) {
type WriteFileAsync = (path: string | number | Buffer | URL, data: any) => Bluebird<void>;
type MkDirAsync = (dirName: string) => Bluebird<mkdirp.Made>;
const writeFileAsync = promisify(writeFile) as WriteFileAsync;
const mkdirAsync = promisify(mkdirp) as MkDirAsync;
export async function FailureDebuggingProvider({ getService }: FtrProviderContext) {
const screenshots = getService('screenshots');
const config = getService('config');
const lifecycle = getService('lifecycle');
@ -40,26 +48,23 @@ export async function FailureDebuggingProvider({ getService }) {
log.info(`Current URL is: ${currentUrl}`);
}
async function savePageHtml(name) {
async function savePageHtml(name: string) {
await mkdirAsync(config.get('failureDebugging.htmlDirectory'));
const htmlOutputFileName = resolve(config.get('failureDebugging.htmlDirectory'), `${name}.html`);
const htmlOutputFileName = resolve(
config.get('failureDebugging.htmlDirectory'),
`${name}.html`
);
const pageSource = await browser.getPageSource();
log.info(`Saving page source to: ${htmlOutputFileName}`);
await writeFileAsync(htmlOutputFileName, pageSource);
}
async function onFailure(_, test) {
async function onFailure(_: any, test: Test) {
// Replace characters in test names which can't be used in filenames, like *
const name = test.fullTitle().replace(/([^ a-zA-Z0-9-]+)/g, '_');
await Promise.all([
screenshots.takeForFailure(name),
logCurrentUrl(),
savePageHtml(name),
]);
await Promise.all([screenshots.takeForFailure(name), logCurrentUrl(), savePageHtml(name)]);
}
lifecycle
.on('testFailure', onFailure)
.on('testHookFailure', onFailure);
lifecycle.on('testFailure', onFailure).on('testHookFailure', onFailure);
}

View file

@ -31,7 +31,6 @@ import {
} from './dashboard';
import { DocTableProvider } from './doc_table';
import { EmbeddingProvider } from './embedding';
// @ts-ignore not TS yet
import { FailureDebuggingProvider } from './failure_debugging';
import { FilterBarProvider } from './filter_bar';
import { FindProvider } from './find';
@ -42,7 +41,6 @@ import { QueryBarProvider } from './query_bar';
import { RemoteProvider } from './remote';
import { RenderableProvider } from './renderable';
import { ScreenshotsProvider } from './screenshots';
// @ts-ignore not TS yet
import { SnapshotsProvider } from './snapshots';
import { TableProvider } from './table';
import { TestSubjectsProvider } from './test_subjects';
@ -50,7 +48,6 @@ import { ToastsProvider } from './toasts';
// @ts-ignore not TS yet
import { PieChartProvider } from './visualizations';
import { VisualizeListingTableProvider } from './visualize_listing_table';
// @ts-ignore not TS yet
import { SavedQueryManagementComponentProvider } from './saved_query_management_component';
export const services = {

View file

@ -18,20 +18,25 @@
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../ftr_provider_context';
export function SavedQueryManagementComponentProvider({ getService }) {
export function SavedQueryManagementComponentProvider({ getService }: FtrProviderContext) {
const testSubjects = getService('testSubjects');
const queryBar = getService('queryBar');
const retry = getService('retry');
class SavedQueryManagementComponent {
async saveNewQuery(name, description, includeFilters, includeTimeFilter) {
public async saveNewQuery(
name: string,
description: string,
includeFilters: boolean,
includeTimeFilter: boolean
) {
await this.openSaveCurrentQueryModal();
await this.submitSaveQueryForm(name, description, includeFilters, includeTimeFilter);
}
async saveNewQueryWithNameError(name) {
public async saveNewQueryWithNameError(name?: string) {
await this.openSaveCurrentQueryModal();
if (name) {
await testSubjects.setValue('saveQueryFormTitle', name);
@ -42,40 +47,52 @@ export function SavedQueryManagementComponentProvider({ getService }) {
// an error.
await testSubjects.click('savedQueryFormSaveButton');
const saveQueryFormSaveButtonStatus = await testSubjects.isEnabled('savedQueryFormSaveButton');
const saveQueryFormSaveButtonStatus = await testSubjects.isEnabled(
'savedQueryFormSaveButton'
);
try {
expect(saveQueryFormSaveButtonStatus).to.not.eql(true);
}
finally {
} finally {
await testSubjects.click('savedQueryFormCancelButton');
}
}
async saveCurrentlyLoadedAsNewQuery(name, description, includeFilters, includeTimeFilter) {
public async saveCurrentlyLoadedAsNewQuery(
name: string,
description: string,
includeFilters: boolean,
includeTimeFilter: boolean
) {
await this.openSavedQueryManagementComponent();
await testSubjects.click('saved-query-management-save-as-new-button');
await this.submitSaveQueryForm(name, description, includeFilters, includeTimeFilter);
}
async updateCurrentlyLoadedQuery(description, includeFilters, includeTimeFilter) {
public async updateCurrentlyLoadedQuery(
description: string,
includeFilters: boolean,
includeTimeFilter: boolean
) {
await this.openSavedQueryManagementComponent();
await testSubjects.click('saved-query-management-save-changes-button');
await this.submitSaveQueryForm(null, description, includeFilters, includeTimeFilter);
}
async loadSavedQuery(title) {
public async loadSavedQuery(title: string) {
await this.openSavedQueryManagementComponent();
await testSubjects.click(`~load-saved-query-${title}-button`);
await retry.try(async () => {
await this.openSavedQueryManagementComponent();
const selectedSavedQueryText = await testSubjects.getVisibleText('~saved-query-list-item-selected');
const selectedSavedQueryText = await testSubjects.getVisibleText(
'~saved-query-list-item-selected'
);
expect(selectedSavedQueryText).to.eql(title);
});
await this.closeSavedQueryManagementComponent();
}
async deleteSavedQuery(title) {
public async deleteSavedQuery(title: string) {
await this.openSavedQueryManagementComponent();
await testSubjects.click(`~delete-saved-query-${title}-button`);
await testSubjects.click('confirmModalConfirmButton');
@ -89,18 +106,27 @@ export function SavedQueryManagementComponentProvider({ getService }) {
expect(queryString).to.be.empty();
}
async submitSaveQueryForm(title, description, includeFilters, includeTimeFilter) {
async submitSaveQueryForm(
title: string | null,
description: string,
includeFilters: boolean,
includeTimeFilter: boolean
) {
if (title) {
await testSubjects.setValue('saveQueryFormTitle', title);
}
await testSubjects.setValue('saveQueryFormDescription', description);
const currentIncludeFiltersValue = (await testSubjects.getAttribute('saveQueryFormIncludeFiltersOption', 'checked')) === 'true';
const currentIncludeFiltersValue =
(await testSubjects.getAttribute('saveQueryFormIncludeFiltersOption', 'checked')) ===
'true';
if (currentIncludeFiltersValue !== includeFilters) {
await testSubjects.click('saveQueryFormIncludeFiltersOption');
}
const currentIncludeTimeFilterValue = (await testSubjects.getAttribute('saveQueryFormIncludeTimeFilterOption', 'checked')) === 'true';
const currentIncludeTimeFilterValue =
(await testSubjects.getAttribute('saveQueryFormIncludeTimeFilterOption', 'checked')) ===
'true';
if (currentIncludeTimeFilterValue !== includeTimeFilter) {
await testSubjects.click('saveQueryFormIncludeTimeFilterOption');
}
@ -108,12 +134,12 @@ export function SavedQueryManagementComponentProvider({ getService }) {
await testSubjects.click('savedQueryFormSaveButton');
}
async savedQueryExistOrFail(title) {
async savedQueryExistOrFail(title: string) {
await this.openSavedQueryManagementComponent();
await testSubjects.existOrFail(`~load-saved-query-${title}-button`);
}
async savedQueryMissingOrFail(title) {
async savedQueryMissingOrFail(title: string) {
await retry.try(async () => {
await this.openSavedQueryManagementComponent();
await testSubjects.missingOrFail(`~load-saved-query-${title}-button`);
@ -154,7 +180,7 @@ export function SavedQueryManagementComponentProvider({ getService }) {
await testSubjects.missingOrFail('saved-query-management-save-changes-button');
}
async deleteSavedQueryMissingOrFail(title) {
async deleteSavedQueryMissingOrFail(title: string) {
await this.openSavedQueryManagementComponent();
await testSubjects.missingOrFail(`delete-saved-query-${title}-button`);
}

View file

@ -20,7 +20,6 @@
import { resolve, dirname } from 'path';
import { writeFile, readFileSync } from 'fs';
import Bluebird, { fromNode as fcb, promisify } from 'bluebird';
// @ts-ignore
import mkdirp from 'mkdirp';
import del from 'del';
import { comparePngs } from './lib/compare_pngs';
@ -28,7 +27,7 @@ import { FtrProviderContext } from '../ftr_provider_context';
import { WebElementWrapper } from './lib/web_element_wrapper';
type WriteFileAsync = (path: string | number | Buffer | URL, data: any) => Bluebird<void>;
type MkDirAsync = (dirName: string) => Bluebird<void>;
type MkDirAsync = (dirName: string) => Bluebird<mkdirp.Made>;
const mkdirAsync = promisify(mkdirp) as MkDirAsync;
const writeFileAsync = promisify(writeFile) as WriteFileAsync;
@ -68,15 +67,15 @@ export async function ScreenshotsProvider({ getService }: FtrProviderContext) {
}
}
async take(name: string, el: WebElementWrapper) {
async take(name: string, el?: WebElementWrapper) {
return await this._take(resolve(SESSION_DIRECTORY, `${name}.png`), el);
}
async takeForFailure(name: string, el: WebElementWrapper) {
async takeForFailure(name: string, el?: WebElementWrapper) {
await this._take(resolve(FAILURE_DIRECTORY, `${name}.png`), el);
}
async _take(path: string, el: WebElementWrapper) {
async _take(path: string, el?: WebElementWrapper) {
try {
log.info(`Taking screenshot "${path}"`);
const screenshot = await (el ? el.takeScreenshot() : browser.takeScreenshot());

View file

@ -20,13 +20,16 @@
import expect from '@kbn/expect';
import { dirname, resolve } from 'path';
import { writeFile, readFileSync } from 'fs';
import { fromNode as fcb, promisify } from 'bluebird';
import Bluebird, { fromNode as fcb, promisify } from 'bluebird';
import mkdirp from 'mkdirp';
import del from 'del';
import { FtrProviderContext } from '../ftr_provider_context';
const writeFileAsync = promisify(writeFile);
type WriteFileAsync = (path: string | number | Buffer | URL, data: any) => Bluebird<void>;
export async function SnapshotsProvider({ getService }) {
const writeFileAsync = promisify(writeFile) as WriteFileAsync;
export async function SnapshotsProvider({ getService }: FtrProviderContext) {
const log = getService('log');
const config = getService('config');
@ -35,7 +38,6 @@ export async function SnapshotsProvider({ getService }) {
await del([SESSION_DIRECTORY]);
class Snapshots {
/**
*
* @param name {string} name of the file to use for comparison
@ -43,7 +45,7 @@ export async function SnapshotsProvider({ getService }) {
* @param updateBaselines {boolean} optional, pass true to update the baseline snapshot.
* @return {Promise.<number>} returns 0 if successful.
*/
async compareAgainstBaseline(name, value, updateBaselines) {
public async compareAgainstBaseline(name: string, value: object, updateBaselines?: boolean) {
log.debug('compareAgainstBaseline');
const sessionPath = resolve(SESSION_DIRECTORY, `${name}.json`);
await this._take(sessionPath, value);
@ -55,22 +57,22 @@ export async function SnapshotsProvider({ getService }) {
return 0;
} else {
log.debug('comparing');
return this._compare(sessionPath, baselinePath);
return this.compare(sessionPath, baselinePath);
}
}
_compare(sessionPath, baselinePath) {
private compare(sessionPath: string, baselinePath: string) {
const currentObject = readFileSync(sessionPath, { encoding: 'utf8' });
const baselineObject = readFileSync(baselinePath, { encoding: 'utf8' });
expect(currentObject).to.eql(baselineObject);
return 0;
}
async take(name) {
public async take(name: string) {
return await this._take(resolve(SESSION_DIRECTORY, `${name}.json`));
}
async _take(path, snapshot) {
private async _take(path: string, snapshot?: object) {
try {
await fcb(cb => mkdirp(dirname(path), cb));
await fcb(cb => writeFile(path, JSON.stringify(snapshot), 'utf8', cb));