forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Functional tests for KibanaErrorBoundary (elastic#170569)
Part of elastic/kibana-team#646 This PR adds an example plugin in `examples/error_boundary` that shows usage of KibanaErrorBoundary. The example plugin is used in a functional test to ensure errors are caught in the appropriate way, and error messages include a working Refresh button. --------- Co-authored-by: kibanamachine <[email protected]>
- Loading branch information
1 parent
c902f90
commit 09f4708
Showing
13 changed files
with
262 additions
and
11 deletions.
There are no files selected for viewing
Validating CODEOWNERS rules …
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
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,3 @@ | ||
## Error Boundary Example | ||
|
||
A very simple example plugin for testing Kibana Error Boundary. |
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,14 @@ | ||
{ | ||
"type": "plugin", | ||
"id": "@kbn/error-boundary-example-plugin", | ||
"owner": "@elastic/appex-sharedux", | ||
"description": "A plugin which exemplifes the KibanaErrorBoundary", | ||
"plugin": { | ||
"id": "error_boundary_example", | ||
"server": false, | ||
"browser": true, | ||
"requiredPlugins": [ | ||
"developerExamples" | ||
] | ||
} | ||
} |
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,12 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
import { ErrorBoundaryExamplePlugin } from './plugin'; | ||
|
||
export function plugin() { | ||
return new ErrorBoundaryExamplePlugin(); | ||
} |
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,111 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
import { EuiButton } from '@elastic/eui'; | ||
|
||
import React, { useState } from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
|
||
import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; | ||
import { DeveloperExamplesSetup } from '@kbn/developer-examples-plugin/public'; | ||
import { KibanaErrorBoundary, KibanaErrorBoundaryProvider } from '@kbn/shared-ux-error-boundary'; | ||
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; | ||
|
||
interface SetupDeps { | ||
developerExamples: DeveloperExamplesSetup; | ||
} | ||
|
||
const useErrors = () => { | ||
return useState(false); | ||
}; | ||
|
||
export const FatalComponent = () => { | ||
const [hasError, setHasError] = useErrors(); | ||
|
||
if (hasError) { | ||
const fatalError = new Error('Example of unknown error type'); | ||
throw fatalError; | ||
} | ||
|
||
return ( | ||
<EuiButton | ||
onClick={() => { | ||
setHasError(true); | ||
}} | ||
data-test-subj="fatalErrorBtn" | ||
> | ||
Click for fatal error | ||
</EuiButton> | ||
); | ||
}; | ||
|
||
export const RecoverableComponent = () => { | ||
const [hasError, setHasError] = useErrors(); | ||
|
||
if (hasError) { | ||
// FIXME: use network interception to disable responses | ||
// for chunk requests and attempt to lazy-load a component | ||
// https://github.com/elastic/kibana/issues/170777 | ||
const upgradeError = new Error('ChunkLoadError'); | ||
upgradeError.name = 'ChunkLoadError'; | ||
throw upgradeError; | ||
} | ||
|
||
return ( | ||
<EuiButton | ||
onClick={() => { | ||
setHasError(true); | ||
}} | ||
data-test-subj="recoverableErrorBtn" | ||
> | ||
Click for recoverable error | ||
</EuiButton> | ||
); | ||
}; | ||
|
||
export class ErrorBoundaryExamplePlugin implements Plugin<void, void, SetupDeps> { | ||
public setup(core: CoreSetup, deps: SetupDeps) { | ||
// Register an application into the side navigation menu | ||
core.application.register({ | ||
id: 'errorBoundaryExample', | ||
title: 'Error Boundary Example', | ||
async mount({ element }: AppMountParameters) { | ||
ReactDOM.render( | ||
<KibanaErrorBoundaryProvider analytics={core.analytics}> | ||
<KibanaErrorBoundary> | ||
<KibanaPageTemplate> | ||
<KibanaPageTemplate.Header | ||
pageTitle="KibanaErrorBoundary example" | ||
data-test-subj="errorBoundaryExampleHeader" | ||
/> | ||
<KibanaPageTemplate.Section grow={false}> | ||
<FatalComponent /> | ||
</KibanaPageTemplate.Section> | ||
<KibanaPageTemplate.Section> | ||
<RecoverableComponent /> | ||
</KibanaPageTemplate.Section> | ||
</KibanaPageTemplate> | ||
</KibanaErrorBoundary> | ||
</KibanaErrorBoundaryProvider>, | ||
element | ||
); | ||
return () => ReactDOM.unmountComponentAtNode(element); | ||
}, | ||
}); | ||
|
||
// This section is only needed to get this example plugin to show up in our Developer Examples. | ||
deps.developerExamples.register({ | ||
appId: 'errorBoundaryExample', | ||
title: 'Error Boundary Example Application', | ||
description: `Build a plugin that registers an application that simply says "Error Boundary Example"`, | ||
}); | ||
} | ||
public start(_core: CoreStart) { | ||
return {}; | ||
} | ||
public stop() {} | ||
} |
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,22 @@ | ||
{ | ||
"extends": "../../tsconfig.base.json", | ||
"compilerOptions": { | ||
"outDir": "target/types" | ||
}, | ||
"include": [ | ||
"index.ts", | ||
"common/**/*.ts", | ||
"public/**/*.ts", | ||
"public/**/*.tsx", | ||
"../../typings/**/*" | ||
], | ||
"exclude": [ | ||
"target/**/*" | ||
], | ||
"kbn_references": [ | ||
"@kbn/core", | ||
"@kbn/developer-examples-plugin", | ||
"@kbn/shared-ux-error-boundary", | ||
"@kbn/shared-ux-page-kibana-template" | ||
] | ||
} |
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
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
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
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
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 | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import expect from '@kbn/expect'; | ||
import { FtrProviderContext } from '../../functional/ftr_provider_context'; | ||
|
||
// eslint-disable-next-line import/no-default-export | ||
export default function ({ getService, getPageObjects }: FtrProviderContext) { | ||
const retry = getService('retry'); | ||
const testSubjects = getService('testSubjects'); | ||
const PageObjects = getPageObjects(['common']); | ||
const log = getService('log'); | ||
|
||
describe('Error Boundary Examples', () => { | ||
before(async () => { | ||
await PageObjects.common.navigateToApp('errorBoundaryExample'); | ||
await testSubjects.existOrFail('errorBoundaryExampleHeader'); | ||
}); | ||
|
||
it('fatal error', async () => { | ||
log.debug('clicking button for fatal error'); | ||
await testSubjects.click('fatalErrorBtn'); | ||
const errorHeader = await testSubjects.getVisibleText('errorBoundaryFatalHeader'); | ||
expect(errorHeader).to.not.be(undefined); | ||
|
||
log.debug('checking that the error has taken over the page'); | ||
await testSubjects.missingOrFail('errorBoundaryExampleHeader'); | ||
|
||
await testSubjects.click('errorBoundaryFatalShowDetailsBtn'); | ||
const errorString = await testSubjects.getVisibleText('errorBoundaryFatalDetailsErrorString'); | ||
expect(errorString).to.match(/Error: Example of unknown error type/); | ||
|
||
log.debug('closing error flyout'); | ||
await testSubjects.click('euiFlyoutCloseButton'); | ||
|
||
log.debug('clicking page refresh'); | ||
await testSubjects.click('errorBoundaryFatalPromptReloadBtn'); | ||
|
||
await retry.try(async () => { | ||
log.debug('checking for page refresh'); | ||
await testSubjects.existOrFail('errorBoundaryExampleHeader'); | ||
}); | ||
}); | ||
|
||
it('recoverable error', async () => { | ||
log.debug('clicking button for recoverable error'); | ||
await testSubjects.click('recoverableErrorBtn'); | ||
const errorHeader = await testSubjects.getVisibleText('errorBoundaryRecoverableHeader'); | ||
expect(errorHeader).to.not.be(undefined); | ||
|
||
log.debug('checking that the error has taken over the page'); | ||
await testSubjects.missingOrFail('errorBoundaryExampleHeader'); | ||
|
||
log.debug('clicking page refresh'); | ||
await testSubjects.click('errorBoundaryRecoverablePromptReloadBtn'); | ||
|
||
await retry.try(async () => { | ||
log.debug('checking for page refresh'); | ||
await testSubjects.existOrFail('errorBoundaryExampleHeader'); | ||
}); | ||
}); | ||
}); | ||
} |
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
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