mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[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:
parent
7d35d8aef1
commit
5e1072e452
6 changed files with 81 additions and 51 deletions
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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 = {
|
||||
|
|
|
@ -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`);
|
||||
}
|
|
@ -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());
|
||||
|
|
|
@ -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));
|
Loading…
Add table
Add a link
Reference in a new issue