From ca42cf92699d3af2d2d22def93cc9c6927d00e18 Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Mon, 28 Jun 2021 12:34:43 -0500 Subject: [PATCH] Add @storybook/testing-react (#103004) --- .eslintrc.js | 12 +++ package.json | 1 + .../DetailView/ExceptionStacktrace.test.tsx | 42 ---------- ...s.tsx => exception_stacktrace.stories.tsx} | 78 ++++++++++--------- .../DetailView/exception_stacktrace.test.tsx | 31 ++++++++ ...tacktrace.tsx => exception_stacktrace.tsx} | 0 .../ErrorGroupDetails/DetailView/index.tsx | 2 +- .../link_preview.test.tsx | 45 +++++------ yarn.lock | 5 ++ 9 files changed, 109 insertions(+), 107 deletions(-) delete mode 100644 x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/ExceptionStacktrace.test.tsx rename x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/{ExceptionStacktrace.stories.tsx => exception_stacktrace.stories.tsx} (98%) create mode 100644 x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/exception_stacktrace.test.tsx rename x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/{ExceptionStacktrace.tsx => exception_stacktrace.tsx} (100%) diff --git a/.eslintrc.js b/.eslintrc.js index c64f03a8398e5..2eea41984b30e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -857,6 +857,18 @@ module.exports = { 'react-hooks/exhaustive-deps': ['error', { additionalHooks: '^useFetcher$' }], }, }, + { + files: ['x-pack/plugins/apm/**/*.stories.*', 'x-pack/plugins/observability/**/*.stories.*'], + rules: { + 'react/function-component-definition': [ + 'off', + { + namedComponents: 'function-declaration', + unnamedComponents: 'arrow-function', + }, + ], + }, + }, /** * Fleet overrides diff --git a/package.json b/package.json index b071b587a3620..2e22a4e0ccf77 100644 --- a/package.json +++ b/package.json @@ -493,6 +493,7 @@ "@storybook/core-events": "^6.1.20", "@storybook/node-logger": "^6.1.20", "@storybook/react": "^6.1.20", + "@storybook/testing-react": "^0.0.17", "@storybook/theming": "^6.1.20", "@testing-library/dom": "^7.30.3", "@testing-library/jest-dom": "^5.11.10", diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/ExceptionStacktrace.test.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/ExceptionStacktrace.test.tsx deleted file mode 100644 index f3f46f50f6020..0000000000000 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/ExceptionStacktrace.test.tsx +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { shallow } from 'enzyme'; -import { ExceptionStacktrace } from './ExceptionStacktrace'; - -describe('ExceptionStacktrace', () => { - describe('render', () => { - it('renders', () => { - const props = { exceptions: [] }; - - expect(() => - shallow() - ).not.toThrowError(); - }); - - describe('with a stack trace', () => { - it('renders the stack trace', () => { - const props = { exceptions: [{}] }; - - expect( - shallow().find('Stacktrace') - ).toHaveLength(1); - }); - }); - - describe('with more than one stack trace', () => { - it('renders a cause stack trace', () => { - const props = { exceptions: [{}, {}] }; - - expect( - shallow().find('CauseStacktrace') - ).toHaveLength(1); - }); - }); - }); -}); diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/ExceptionStacktrace.stories.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/exception_stacktrace.stories.tsx similarity index 98% rename from x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/ExceptionStacktrace.stories.tsx rename to x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/exception_stacktrace.stories.tsx index 8616bf29cb97f..f21c189584d31 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/ExceptionStacktrace.stories.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/exception_stacktrace.stories.tsx @@ -5,27 +5,31 @@ * 2.0. */ -import React, { ComponentType } from 'react'; +import { Story } from '@storybook/react'; +import React, { ComponentProps, ComponentType } from 'react'; import { EuiThemeProvider } from '../../../../../../../../src/plugins/kibana_react/common'; -import { Exception } from '../../../../../typings/es_schemas/raw/error_raw'; -import { ExceptionStacktrace } from './ExceptionStacktrace'; +import { ExceptionStacktrace } from './exception_stacktrace'; + +type Args = ComponentProps; export default { title: 'app/ErrorGroupDetails/DetailView/ExceptionStacktrace', component: ExceptionStacktrace, decorators: [ - (Story: ComponentType) => { - return ( - - - - ); - }, + (StoryComponent: ComponentType) => ( + + + + ), ], }; -export function JavaWithLongLines() { - const exceptions: Exception[] = [ +export const JavaWithLongLines: Story = (args) => ( + +); +JavaWithLongLines.args = { + codeLanguage: 'java', + exceptions: [ { stacktrace: [ { @@ -1734,22 +1738,23 @@ export function JavaWithLongLines() { 'Null return value from advice does not match primitive return type for: public abstract double co.elastic.apm.opbeans.repositories.Numbers.getRevenue()', type: 'org.springframework.aop.AopInvocationException', }, - ]; - - return ; -} + ], +}; JavaWithLongLines.decorators = [ - (Story: ComponentType) => { - return ( -
- -
- ); - }, + (StoryComponent: ComponentType) => ( +
+ +
+ ), ]; -export function JavaScriptWithSomeContext() { - const exceptions: Exception[] = [ +export const JavaScriptWithSomeContext: Story = (args) => ( + +); +JavaScriptWithSomeContext.storyName = 'JavaScript With Some Context'; +JavaScriptWithSomeContext.args = { + codeLanguage: 'javascript', + exceptions: [ { code: '503', stacktrace: [ @@ -1870,16 +1875,15 @@ export function JavaScriptWithSomeContext() { type: 'Error', message: 'Unexpected APM Server response when polling config', }, - ]; - - return ( - - ); -} -JavaScriptWithSomeContext.storyName = 'JavaScript With Some Context'; + ], +}; -export function RubyWithContextAndLibraryFrames() { - const exceptions: Exception[] = [ +export const RubyWithContextAndLibraryFrames: Story = (args) => ( + +); +RubyWithContextAndLibraryFrames.args = { + codeLanguage: 'ruby', + exceptions: [ { stacktrace: [ { @@ -2536,7 +2540,5 @@ export function RubyWithContextAndLibraryFrames() { message: "Couldn't find Order with 'id'=956", type: 'ActiveRecord::RecordNotFound', }, - ]; - - return ; -} + ], +}; diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/exception_stacktrace.test.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/exception_stacktrace.test.tsx new file mode 100644 index 0000000000000..9417c0c584f1b --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/exception_stacktrace.test.tsx @@ -0,0 +1,31 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { composeStories } from '@storybook/testing-react'; +import React from 'react'; +import { mount } from 'enzyme'; +import * as stories from './exception_stacktrace.stories'; + +const { JavaWithLongLines } = composeStories(stories); + +describe('ExceptionStacktrace', () => { + describe('render', () => { + describe('with stacktraces', () => { + it('renders the stacktraces', () => { + expect(mount().find('Stacktrace')).toHaveLength(3); + }); + }); + + describe('with more than one stack trace', () => { + it('renders cause stacktraces', () => { + expect( + mount().find('CauseStacktrace') + ).toHaveLength(2); + }); + }); + }); +}); diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/ExceptionStacktrace.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/exception_stacktrace.tsx similarity index 100% rename from x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/ExceptionStacktrace.tsx rename to x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/exception_stacktrace.tsx diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx index 11926dd965f95..ae67ec868d766 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx @@ -39,7 +39,7 @@ import { getTabs, logStacktraceTab, } from './ErrorTabs'; -import { ExceptionStacktrace } from './ExceptionStacktrace'; +import { ExceptionStacktrace } from './exception_stacktrace'; const HeaderContainer = euiStyled.div` display: flex; diff --git a/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/CreateEditCustomLinkFlyout/link_preview.test.tsx b/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/CreateEditCustomLinkFlyout/link_preview.test.tsx index 407f460f25ad3..d88cef0702a87 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/CreateEditCustomLinkFlyout/link_preview.test.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/CreateEditCustomLinkFlyout/link_preview.test.tsx @@ -5,8 +5,7 @@ * 2.0. */ -import React from 'react'; -import { LinkPreview } from '../CreateEditCustomLinkFlyout/link_preview'; +import { composeStories } from '@storybook/testing-react'; import { render, getNodeText, @@ -14,24 +13,15 @@ import { act, waitFor, } from '@testing-library/react'; -import { - getCallApmApiSpy, - CallApmApiSpy, -} from '../../../../../../services/rest/callApmApiSpy'; +import React from 'react'; +import * as stories from './link_preview.stories'; + +const { Example } = composeStories(stories); export const removeExternalLinkText = (str: string) => str.replace(/\(opens in a new tab or window\)/g, ''); describe('LinkPreview', () => { - let callApmApiSpy: CallApmApiSpy; - beforeAll(() => { - callApmApiSpy = getCallApmApiSpy().mockResolvedValue({ - transaction: { id: 'foo' }, - }); - }); - afterAll(() => { - jest.clearAllMocks(); - }); const getElementValue = (container: HTMLElement, id: string) => getNodeText( ((getByTestId(container, id) as HTMLDivElement) @@ -41,7 +31,7 @@ describe('LinkPreview', () => { it('shows label and url default values', () => { act(() => { const { container } = render( - + ); expect(getElementValue(container, 'preview-label')).toEqual('Elastic.co'); expect(getElementValue(container, 'preview-url')).toEqual( @@ -53,7 +43,7 @@ describe('LinkPreview', () => { it('shows label and url values', () => { act(() => { const { container } = render( - { it("shows warning when couldn't replace context variables", () => { act(() => { const { container } = render( - { expect(getByTestId(container, 'preview-warning')).toBeInTheDocument(); }); }); + it('replaces url with transaction id', async () => { const { container } = render( - ); - await waitFor(() => expect(callApmApiSpy).toHaveBeenCalled()); - expect(getElementValue(container, 'preview-label')).toEqual('foo'); - expect( - removeExternalLinkText( - (getByTestId(container, 'preview-link') as HTMLAnchorElement).text - ) - ).toEqual('https://baz.co?transaction=foo'); + + await waitFor(() => { + expect(getElementValue(container, 'preview-label')).toEqual('foo'); + expect( + removeExternalLinkText( + (getByTestId(container, 'preview-link') as HTMLAnchorElement).text + ) + ).toEqual('https://baz.co?transaction=0'); + }); }); }); diff --git a/yarn.lock b/yarn.lock index e07b3edff1445..ea968cf3631f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4307,6 +4307,11 @@ regenerator-runtime "^0.13.7" source-map "^0.7.3" +"@storybook/testing-react@^0.0.17": + version "0.0.17" + resolved "https://registry.yarnpkg.com/@storybook/testing-react/-/testing-react-0.0.17.tgz#632dd22f8815743f78c182b126f444cf51d92d71" + integrity sha512-93nbA/JSWDEys1msd438+wzETRFDEgT2aFqJL2y46++zsyv8g2mCYKZkf9E36KQHMQbO1uJBHT8CmrLQa8VmZw== + "@storybook/theming@6.1.20", "@storybook/theming@^6.1.20": version "6.1.20" resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.1.20.tgz#ed0b330a5c08bbe998e9df95e615f0e84a8d663f"