mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Dashboard] Add better debugging to error embeddable checks (#153457)
Closes https://github.com/elastic/kibana/issues/97701 ## Summary This PR replaces all instances of `await testSubjects.missingOrFail('embeddableError');` with a call to the new `noErrorEmbeddablesPresent()` method from the `dashboardExpect` service. This `noErrorEmbeddablesPresent()` method adds some extra debugging logic to the error embeddable check where, if at least one error embeddable is present, then both the panel title(s) and the relevant error message(s) will be printed as part of the error that is thrown. With these changes, if the attached flaky test fails again, we should at least have some more information on **why** it failed. ### Flaky Test Runner This was specifically only running the flaky `save_search_session_relative_time.ts` test suite: <a href="https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2024"><img src="https://user-images.githubusercontent.com/8698078/227240095-a336b03b-6499-4d80-8b60-5e325d54a4ae.png"/></a> ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
This commit is contained in:
parent
464169f0b4
commit
adb0bb58d3
6 changed files with 44 additions and 10 deletions
|
@ -32,11 +32,42 @@ export class DashboardExpectService extends FtrService {
|
|||
}
|
||||
|
||||
async visualizationsArePresent(vizList: string[]) {
|
||||
this.log.debug('Checking all visualisations are present on dashsboard');
|
||||
this.log.debug('Checking all visualisations are present on the dashboard');
|
||||
const notLoaded = await this.dashboard.getNotLoadedVisualizations(vizList);
|
||||
expect(notLoaded).to.be.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that there is no error embeddables on the dashboard
|
||||
* @throws An error if an error embeddable is present
|
||||
*/
|
||||
async noErrorEmbeddablesPresent() {
|
||||
this.log.debug('Ensure that there are no error embeddables on the dashboard');
|
||||
|
||||
const errorEmbeddables = await this.testSubjects.findAll('embeddableError');
|
||||
if (errorEmbeddables.length > 0) {
|
||||
const errorMessages = await Promise.all(
|
||||
errorEmbeddables.map(async (embeddable) => {
|
||||
const panel = await embeddable.findByXpath('./..'); // get the parent of 'embeddableError'
|
||||
let panelTitle = 'Empty title';
|
||||
if (await this.testSubjects.descendantExists('dashboardPanelTitle', panel)) {
|
||||
panelTitle = await (
|
||||
await this.testSubjects.findDescendant('dashboardPanelTitle', panel)
|
||||
).getVisibleText();
|
||||
}
|
||||
const panelError = await embeddable.getVisibleText();
|
||||
return `${panelTitle}: "${panelError}"`;
|
||||
})
|
||||
);
|
||||
|
||||
throw new Error(
|
||||
`Found error embeddable(s): ${errorMessages.reduce((errorString, error) => {
|
||||
return errorString + '\n' + `\t- ${error}`;
|
||||
}, '')}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async selectedLegendColorCount(color: string, expectedCount: number) {
|
||||
this.log.debug(`DashboardExpect.selectedLegendColorCount(${color}, ${expectedCount})`);
|
||||
await this.retry.try(async () => {
|
||||
|
|
|
@ -16,6 +16,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
const dashboardPanelActions = getService('dashboardPanelActions');
|
||||
const queryBar = getService('queryBar');
|
||||
const elasticChart = getService('elasticChart');
|
||||
const dashboardExpect = getService('dashboardExpect');
|
||||
|
||||
const xyChartSelector = 'xyVisChart';
|
||||
|
||||
const enableNewChartLibraryDebug = async () => {
|
||||
|
@ -36,7 +38,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.loadSavedDashboard('Not Delayed');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await testSubjects.missingOrFail('embeddableError');
|
||||
await dashboardExpect.noErrorEmbeddablesPresent();
|
||||
await enableNewChartLibraryDebug();
|
||||
const data = await PageObjects.visChart.getBarChartData(xyChartSelector, 'Sum of bytes');
|
||||
expect(data.length).to.be(5);
|
||||
|
@ -46,7 +48,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.loadSavedDashboard('Delayed 5s');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await testSubjects.missingOrFail('embeddableError');
|
||||
await dashboardExpect.noErrorEmbeddablesPresent();
|
||||
await enableNewChartLibraryDebug();
|
||||
const data = await PageObjects.visChart.getBarChartData(xyChartSelector, 'Sum of bytes');
|
||||
expect(data.length).to.be(5);
|
||||
|
|
|
@ -25,6 +25,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
const queryBar = getService('queryBar');
|
||||
const elasticChart = getService('elasticChart');
|
||||
const toasts = getService('toasts');
|
||||
const dashboardExpect = getService('dashboardExpect');
|
||||
|
||||
const enableNewChartLibraryDebug = async () => {
|
||||
await elasticChart.setNewChartUiDebugFlag();
|
||||
|
@ -63,7 +64,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await queryBar.clickQuerySubmitButton();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await searchSessions.expectState('completed');
|
||||
await testSubjects.missingOrFail('embeddableError');
|
||||
await dashboardExpect.noErrorEmbeddablesPresent();
|
||||
const session2 = await dashboardPanelActions.getSearchSessionIdByTitle(
|
||||
'Sum of Bytes by Extension'
|
||||
);
|
||||
|
@ -104,7 +105,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
// Check that session is restored
|
||||
await searchSessions.expectState('restored');
|
||||
await testSubjects.missingOrFail('embeddableError');
|
||||
await dashboardExpect.noErrorEmbeddablesPresent();
|
||||
|
||||
// switching dashboard to edit mode (or any other non-fetch required) state change
|
||||
// should leave session state untouched
|
||||
|
|
|
@ -9,7 +9,6 @@ import expect from '@kbn/expect';
|
|||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const testSubjects = getService('testSubjects');
|
||||
const log = getService('log');
|
||||
const retry = getService('retry');
|
||||
const PageObjects = getPageObjects([
|
||||
|
@ -85,7 +84,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
async function checkSampleDashboardLoaded(visualizationContainer?: string) {
|
||||
log.debug('Checking no error labels');
|
||||
await testSubjects.missingOrFail('embeddableError');
|
||||
await dashboardExpect.noErrorEmbeddablesPresent();
|
||||
log.debug('Checking charts rendered');
|
||||
await elasticChart.waitForRenderComplete(visualizationContainer ?? 'lnsVisualizationContainer');
|
||||
log.debug('Checking saved searches rendered');
|
||||
|
|
|
@ -27,6 +27,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
const listingTable = getService('listingTable');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const elasticChart = getService('elasticChart');
|
||||
const dashboardExpect = getService('dashboardExpect');
|
||||
|
||||
describe('Session and searches integration', () => {
|
||||
before(async function () {
|
||||
|
@ -195,7 +196,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await searchSessionItem.view();
|
||||
expect(await toasts.getToastCount()).to.be(0); // there should be no warnings
|
||||
await searchSessions.expectState('restored', 20000);
|
||||
await testSubjects.missingOrFail('embeddableError');
|
||||
await dashboardExpect.noErrorEmbeddablesPresent();
|
||||
|
||||
const data = await elasticChart.getChartDebugData();
|
||||
expect(data!.bars![0].bars.length).to.eql(4);
|
||||
|
|
|
@ -9,7 +9,6 @@ import expect from '@kbn/expect';
|
|||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const testSubjects = getService('testSubjects');
|
||||
const spacesService = getService('spaces');
|
||||
const security = getService('security');
|
||||
const PageObjects = getPageObjects([
|
||||
|
@ -26,6 +25,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
const searchSessions = getService('searchSessions');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
const toasts = getService('toasts');
|
||||
const dashboardExpect = getService('dashboardExpect');
|
||||
|
||||
describe('dashboard in space', () => {
|
||||
afterEach(async () => await clean());
|
||||
|
@ -67,7 +67,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
// Check that session is restored
|
||||
await searchSessions.expectState('restored');
|
||||
await testSubjects.missingOrFail('embeddableError');
|
||||
await dashboardExpect.noErrorEmbeddablesPresent();
|
||||
expect(await toasts.getToastCount()).to.be(0); // no session restoration related warnings
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue