packages/test-utils: do app wrapping with actual app + remove wrapInThemedTestApp

This commit is contained in:
Patrik Oldsberg
2020-05-28 19:04:55 +02:00
parent 63221f6fc5
commit e32f5a49ff
27 changed files with 185 additions and 199 deletions
@@ -16,7 +16,7 @@
import React from 'react';
import { render } from '@testing-library/react';
import { wrapInThemedTestApp } from '@backstage/test-utils';
import { wrapInTestApp } from '@backstage/test-utils';
import CodeSnippet from './CodeSnippet';
@@ -33,16 +33,14 @@ const minProps = {
describe('<CodeSnippet />', () => {
it('renders text without exploding', () => {
const { getByText } = render(
wrapInThemedTestApp(<CodeSnippet {...minProps} />),
);
const { getByText } = render(wrapInTestApp(<CodeSnippet {...minProps} />));
expect(getByText(/"Hello"/)).toBeInTheDocument();
expect(getByText(/"World"/)).toBeInTheDocument();
});
it('renders without line numbers', () => {
const { queryByText } = render(
wrapInThemedTestApp(<CodeSnippet {...minProps} />),
wrapInTestApp(<CodeSnippet {...minProps} />),
);
expect(queryByText('1')).not.toBeInTheDocument();
expect(queryByText('2')).not.toBeInTheDocument();
@@ -51,7 +49,7 @@ describe('<CodeSnippet />', () => {
it('renders with line numbers', () => {
const { queryByText } = render(
wrapInThemedTestApp(<CodeSnippet {...minProps} showLineNumbers />),
wrapInTestApp(<CodeSnippet {...minProps} showLineNumbers />),
);
expect(queryByText(/1/)).toBeInTheDocument();
expect(queryByText(/2/)).toBeInTheDocument();
@@ -16,7 +16,7 @@
import React from 'react';
import { render } from '@testing-library/react';
import { wrapInThemedTestApp } from '@backstage/test-utils';
import { wrapInTestApp } from '@backstage/test-utils';
import CopyTextButton from './CopyTextButton';
import {
ApiRegistry,
@@ -57,7 +57,7 @@ const apiRegistry = ApiRegistry.from([
describe('<CopyTextButton />', () => {
it('renders without exploding', () => {
const { getByDisplayValue } = render(
wrapInThemedTestApp(
wrapInTestApp(
<ApiProvider apis={apiRegistry}>
<CopyTextButton {...props} />
</ApiProvider>,
@@ -69,7 +69,7 @@ describe('<CopyTextButton />', () => {
it('displays tooltip on click', async () => {
document.execCommand = jest.fn();
const rendered = render(
wrapInThemedTestApp(
wrapInTestApp(
<ApiProvider apis={apiRegistry}>
<CopyTextButton {...props} />
</ApiProvider>,
@@ -16,7 +16,7 @@
import React from 'react';
// import { fireEvent, waitForElementToBeRemoved } from '@testing-library/react';
import { renderWithEffects, wrapInThemedTestApp } from '@backstage/test-utils';
import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils';
// import { createSetting } from 'shared/apis/settings';
import DismissableBanner from './DismissableBanner';
@@ -30,7 +30,7 @@ describe('<DismissableBanner />', () => {
*/
const rendered = await renderWithEffects(
wrapInThemedTestApp(
wrapInTestApp(
<DismissableBanner
variant="info"
// setting={mockSetting}
@@ -16,7 +16,7 @@
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import { renderWithEffects, wrapInThemedTestApp } from '@backstage/test-utils';
import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils';
import HorizontalScrollGrid from './HorizontalScrollGrid';
import { Grid } from '@material-ui/core';
@@ -34,7 +34,7 @@ describe('<HorizontalScrollGrid />', () => {
it('renders without exploding', () => {
const rendered = render(
wrapInThemedTestApp(
wrapInTestApp(
<HorizontalScrollGrid>
<Grid item>item1</Grid>
<Grid item>item2</Grid>
@@ -69,7 +69,7 @@ describe('<HorizontalScrollGrid />', () => {
};
const rendered = await renderWithEffects(
wrapInThemedTestApp(
wrapInTestApp(
<HorizontalScrollGrid style={{ maxWidth: 300 }}>
<Grid item style={{ minWidth: 200 }}>
item1
@@ -16,29 +16,27 @@
import React from 'react';
import { render } from '@testing-library/react';
import { wrapInThemedTestApp } from '@backstage/test-utils';
import { wrapInTestApp } from '@backstage/test-utils';
import { Lifecycle } from './Lifecycle';
describe('<Lifecycle />', () => {
it('renders Alpha with shorthand', async () => {
const { getByText } = render(
wrapInThemedTestApp(<Lifecycle alpha shorthand />),
);
const { getByText } = render(wrapInTestApp(<Lifecycle alpha shorthand />));
expect(getByText('α')).toBeInTheDocument();
});
it('renders Alpha without shorthand', async () => {
const { getByText } = render(wrapInThemedTestApp(<Lifecycle alpha />));
const { getByText } = render(wrapInTestApp(<Lifecycle alpha />));
expect(getByText('Alpha')).toBeInTheDocument();
});
it('renders Beta with shorthand', async () => {
const { getByText } = render(wrapInThemedTestApp(<Lifecycle shorthand />));
const { getByText } = render(wrapInTestApp(<Lifecycle shorthand />));
expect(getByText('β')).toBeInTheDocument();
});
it('renders Beta without shorthand', async () => {
const { getByText } = render(wrapInThemedTestApp(<Lifecycle />));
const { getByText } = render(wrapInTestApp(<Lifecycle />));
expect(getByText('Beta')).toBeInTheDocument();
});
});
@@ -16,37 +16,33 @@
import React from 'react';
import { render } from '@testing-library/react';
import { wrapInThemedTestApp } from '@backstage/test-utils';
import { wrapInTestApp } from '@backstage/test-utils';
import CircleProgress, { getProgressColor } from './CircleProgress';
describe('<CircleProgress />', () => {
it('renders without exploding', () => {
const { getByText } = render(
wrapInThemedTestApp(<CircleProgress value={10} fractional={false} />),
wrapInTestApp(<CircleProgress value={10} fractional={false} />),
);
getByText('10%');
});
it('handles fractional prop', () => {
const { getByText } = render(
wrapInThemedTestApp(<CircleProgress value={0.1} fractional />),
wrapInTestApp(<CircleProgress value={0.1} fractional />),
);
getByText('10%');
});
it('handles max prop', () => {
const { getByText } = render(
wrapInThemedTestApp(
<CircleProgress value={1} max={10} fractional={false} />,
),
wrapInTestApp(<CircleProgress value={1} max={10} fractional={false} />),
);
getByText('1%');
});
it('handles unit prop', () => {
const { getByText } = render(
wrapInThemedTestApp(
<CircleProgress value={10} fractional={false} unit="m" />,
),
wrapInTestApp(<CircleProgress value={10} fractional={false} unit="m" />),
);
getByText('10m');
});
@@ -16,7 +16,7 @@
import React from 'react';
import { render } from '@testing-library/react';
import { wrapInThemedTestApp } from '@backstage/test-utils';
import { wrapInTestApp } from '@backstage/test-utils';
import ProgressCard from './ProgressCard';
@@ -24,32 +24,26 @@ const minProps = { title: 'Tingle upgrade', progress: 0.12 };
describe('<ProgressCard />', () => {
it('renders without exploding', () => {
const { getByText } = render(
wrapInThemedTestApp(<ProgressCard {...minProps} />),
);
const { getByText } = render(wrapInTestApp(<ProgressCard {...minProps} />));
expect(getByText(/Tingle.*/)).toBeInTheDocument();
});
it('renders progress and title', () => {
const { getByText } = render(
wrapInThemedTestApp(<ProgressCard {...minProps} />),
);
const { getByText } = render(wrapInTestApp(<ProgressCard {...minProps} />));
expect(getByText(/Tingle.*/)).toBeInTheDocument();
expect(getByText(/12%.*/)).toBeInTheDocument();
});
it('does not render deepLink', () => {
const { queryByText } = render(
wrapInThemedTestApp(<ProgressCard {...minProps} />),
wrapInTestApp(<ProgressCard {...minProps} />),
);
expect(queryByText('View more')).not.toBeInTheDocument();
});
it('handles invalid numbers', () => {
const badProps = { title: 'Tingle upgrade', progress: 'hejjo' };
const { getByText } = render(
wrapInThemedTestApp(<ProgressCard {...badProps} />),
);
const { getByText } = render(wrapInTestApp(<ProgressCard {...badProps} />));
expect(getByText(/N\/A.*/)).toBeInTheDocument();
});
});
@@ -17,7 +17,7 @@
/* eslint-disable jest/no-disabled-tests */
import React from 'react';
import { render } from '@testing-library/react';
import { wrapInThemedTestApp } from '@backstage/test-utils';
import { wrapInTestApp } from '@backstage/test-utils';
import TrendLine from '.';
@@ -25,7 +25,7 @@ describe('TrendLine', () => {
describe('when no data is present', () => {
it('renders null without throwing', () => {
const rendered = render(
wrapInThemedTestApp(<TrendLine data={[]} title="sparkline" />),
wrapInTestApp(<TrendLine data={[]} title="sparkline" />),
);
expect(rendered.queryByTitle('sparkline')).not.toBeInTheDocument();
});
@@ -34,7 +34,7 @@ describe('TrendLine', () => {
describe('when one datapoint is present', () => {
it('renders as a straight line', () => {
const rendered = render(
wrapInThemedTestApp(<TrendLine data={[0.5]} title="sparkline" />),
wrapInTestApp(<TrendLine data={[0.5]} title="sparkline" />),
);
expect(rendered.getByTitle('sparkline')).toBeInTheDocument();
});
@@ -43,7 +43,7 @@ describe('TrendLine', () => {
describe.skip('when the data finishes above the success threshold', () => {
it('renders with the correct color', () => {
const rendered = render(
wrapInThemedTestApp(<TrendLine data={[0.5, 0.95]} title="sparkline" />),
wrapInTestApp(<TrendLine data={[0.5, 0.95]} title="sparkline" />),
);
expect(rendered.getByTitle('sparkline')).toBeInTheDocument();
});
@@ -52,7 +52,7 @@ describe('TrendLine', () => {
describe.skip('when the data finishes within the the warning threshold', () => {
it('renders with the correct color', () => {
const rendered = render(
wrapInThemedTestApp(<TrendLine data={[0.5, 0.65]} title="sparkline" />),
wrapInTestApp(<TrendLine data={[0.5, 0.65]} title="sparkline" />),
);
expect(rendered.getByTitle('sparkline')).toBeInTheDocument();
});
@@ -61,7 +61,7 @@ describe('TrendLine', () => {
describe.skip('when the data finishes within the the error threshold', () => {
it('renders with the correct color', () => {
const rendered = render(
wrapInThemedTestApp(<TrendLine data={[0.5, 0.4]} title="sparkline" />),
wrapInTestApp(<TrendLine data={[0.5, 0.4]} title="sparkline" />),
);
expect(rendered.getByTitle('sparkline')).toBeInTheDocument();
});
@@ -16,7 +16,7 @@
import React from 'react';
import { render } from '@testing-library/react';
import { wrapInThemedTestApp } from '@backstage/test-utils';
import { wrapInTestApp } from '@backstage/test-utils';
import WarningPanel from './WarningPanel';
@@ -24,15 +24,13 @@ const minProps = { title: 'Mock title', message: 'Some more info' };
describe('<WarningPanel />', () => {
it('renders without exploding', () => {
const { getByText } = render(
wrapInThemedTestApp(<WarningPanel {...minProps} />),
);
const { getByText } = render(wrapInTestApp(<WarningPanel {...minProps} />));
expect(getByText('Mock title')).toBeInTheDocument();
});
it('renders message and children', () => {
const { getByText } = render(
wrapInThemedTestApp(<WarningPanel {...minProps}>children</WarningPanel>),
wrapInTestApp(<WarningPanel {...minProps}>children</WarningPanel>),
);
expect(getByText('Some more info')).toBeInTheDocument();
expect(getByText('children')).toBeInTheDocument();
@@ -17,7 +17,7 @@
import React from 'react';
import { render } from '@testing-library/react';
import { ContentHeader } from './ContentHeader';
import { wrapInThemedTestApp } from '@backstage/test-utils';
import { wrapInTestApp } from '@backstage/test-utils';
jest.mock('react-helmet', () => {
return {
@@ -27,9 +27,7 @@ jest.mock('react-helmet', () => {
describe('<ContentHeader/>', () => {
it('should render with title', () => {
const rendered = render(
wrapInThemedTestApp(<ContentHeader title="Title" />),
);
const rendered = render(wrapInTestApp(<ContentHeader title="Title" />));
rendered.getByText('Title');
});
@@ -37,14 +35,14 @@ describe('<ContentHeader/>', () => {
const title = 'Custom title';
const titleComponent = () => <h1>{title}</h1>;
const rendered = render(
wrapInThemedTestApp(<ContentHeader titleComponent={titleComponent} />),
wrapInTestApp(<ContentHeader titleComponent={titleComponent} />),
);
rendered.getByText(title);
});
it('should render with description', () => {
const rendered = render(
wrapInThemedTestApp(<ContentHeader description="description" />),
wrapInTestApp(<ContentHeader description="description" />),
);
rendered.getByText('description');
});
@@ -17,14 +17,12 @@
import React from 'react';
import { render } from '@testing-library/react';
import { ErrorPage } from './ErrorPage';
import { wrapInThemedTestApp } from '@backstage/test-utils';
import { wrapInTestApp } from '@backstage/test-utils';
describe('<ErrorPage/>', () => {
it('should render with status code, status message and go back link', () => {
const rendered = render(
wrapInThemedTestApp(
<ErrorPage status="404" statusMessage="PAGE NOT FOUND" />,
),
wrapInTestApp(<ErrorPage status="404" statusMessage="PAGE NOT FOUND" />),
);
rendered.getByText(/page not found/i);
rendered.getByText(/404/i);
@@ -16,7 +16,7 @@
import React from 'react';
import { render } from '@testing-library/react';
import { wrapInThemedTestApp } from '@backstage/test-utils';
import { wrapInTestApp } from '@backstage/test-utils';
import { Header } from './Header';
jest.mock('react-helmet', () => {
@@ -27,19 +27,19 @@ jest.mock('react-helmet', () => {
describe('<Header/>', () => {
it('should render with title', () => {
const rendered = render(wrapInThemedTestApp(<Header title="Title" />));
const rendered = render(wrapInTestApp(<Header title="Title" />));
rendered.getByText('Title');
});
it('should set document title', () => {
const rendered = render(wrapInThemedTestApp(<Header title="Title1" />));
const rendered = render(wrapInTestApp(<Header title="Title1" />));
rendered.getByText('Title1');
rendered.getByText('defaultTitle: Title1 | Backstage');
});
it('should override document title', () => {
const rendered = render(
wrapInThemedTestApp(<Header title="Title1" pageTitleOverride="Title2" />),
wrapInTestApp(<Header title="Title1" pageTitleOverride="Title2" />),
);
rendered.getByText('Title1');
rendered.getByText('defaultTitle: Title2 | Backstage');
@@ -47,14 +47,14 @@ describe('<Header/>', () => {
it('should have subtitle', () => {
const rendered = render(
wrapInThemedTestApp(<Header title="Title" subtitle="Subtitle" />),
wrapInTestApp(<Header title="Title" subtitle="Subtitle" />),
);
rendered.getByText('Subtitle');
});
it('should have type rendered', () => {
const rendered = render(
wrapInThemedTestApp(<Header title="Title" type="tool" />),
wrapInTestApp(<Header title="Title" type="tool" />),
);
rendered.getByText('tool');
});
@@ -16,18 +16,18 @@
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import { wrapInThemedTestApp, Keyboard } from '@backstage/test-utils';
import { wrapInTestApp, Keyboard } from '@backstage/test-utils';
import { HeaderActionMenu } from './HeaderActionMenu';
describe('<ComponentContextMenu />', () => {
it('renders without any items and without exploding', () => {
render(wrapInThemedTestApp(<HeaderActionMenu actionItems={[]} />));
render(wrapInTestApp(<HeaderActionMenu actionItems={[]} />));
});
it('can open the menu and click menu items', () => {
const onClickFunction = jest.fn();
const rendered = render(
wrapInThemedTestApp(
wrapInTestApp(
<HeaderActionMenu
actionItems={[{ label: 'Some label', onClick: onClickFunction }]}
/>,
@@ -49,7 +49,7 @@ describe('<ComponentContextMenu />', () => {
it('Disabled', async () => {
const rendered = render(
wrapInThemedTestApp(
wrapInTestApp(
<HeaderActionMenu
actionItems={[{ label: 'Some label', disabled: true }]}
/>,
@@ -66,7 +66,7 @@ describe('<ComponentContextMenu />', () => {
it('Test wrapper, and secondary label', () => {
const onClickFunction = jest.fn();
const rendered = render(
wrapInThemedTestApp(
wrapInTestApp(
<HeaderActionMenu
actionItems={[
{
@@ -92,7 +92,7 @@ describe('<ComponentContextMenu />', () => {
it('should close when hitting escape', async () => {
const rendered = render(
wrapInThemedTestApp(
wrapInTestApp(
<HeaderActionMenu actionItems={[{ label: 'Some label' }]} />,
),
);
@@ -16,39 +16,37 @@
import React from 'react';
import { render } from '@testing-library/react';
import { wrapInThemedTestApp } from '@backstage/test-utils';
import { wrapInTestApp } from '@backstage/test-utils';
import { HeaderLabel } from './HeaderLabel';
describe('<HeaderLabel />', () => {
it('should have a label', () => {
const rendered = render(wrapInThemedTestApp(<HeaderLabel label="Label" />));
const rendered = render(wrapInTestApp(<HeaderLabel label="Label" />));
expect(rendered.getByText('Label')).toBeInTheDocument();
});
it('should say unknown', () => {
const rendered = render(wrapInThemedTestApp(<HeaderLabel label="Label" />));
const rendered = render(wrapInTestApp(<HeaderLabel label="Label" />));
expect(rendered.getByText('<Unknown>')).toBeInTheDocument();
});
it('should say unknown when passing null as value prop', () => {
const rendered = render(
wrapInThemedTestApp(<HeaderLabel label="Label" value={null} />),
wrapInTestApp(<HeaderLabel label="Label" value={null} />),
);
expect(rendered.getByText('<Unknown>')).toBeInTheDocument();
});
it('should have value', () => {
const rendered = render(
wrapInThemedTestApp(<HeaderLabel label="Label" value="Value" />),
wrapInTestApp(<HeaderLabel label="Label" value="Value" />),
);
expect(rendered.getByText('Value')).toBeInTheDocument();
});
it('should have a link', () => {
const rendered = render(
wrapInThemedTestApp(
<HeaderLabel label="Label" value="Value" url="/test" />,
),
wrapInTestApp(<HeaderLabel label="Label" value="Value" url="/test" />),
);
const anchor = rendered.container.querySelector('a') as HTMLAnchorElement;
expect(rendered.getByText('Value')).toBeInTheDocument();
+1
View File
@@ -29,6 +29,7 @@
},
"dependencies": {
"@backstage/cli": "^0.1.1-alpha.6",
"@backstage/core-api": "^0.1.1-alpha.6",
"@backstage/test-utils-core": "^0.1.1-alpha.6",
"@backstage/theme": "^0.1.1-alpha.6",
"@material-ui/core": "^4.9.1",
@@ -27,7 +27,7 @@ describe('wrapInTestApp', () => {
<Route path="/route1">Route 1</Route>
<Route path="/route2">Route 2</Route>
</>,
['/route2'],
{ routeEntries: ['/route2'] },
),
);
expect(rendered.getByText('Route 2')).toBeInTheDocument();
@@ -15,15 +15,52 @@
*/
import React, { ComponentType, ReactNode, FunctionComponent } from 'react';
import { ThemeProvider } from '@material-ui/core';
import { MemoryRouter } from 'react-router';
import { Route } from 'react-router-dom';
import { lightTheme } from '@backstage/theme';
import privateExports, {
defaultSystemIcons,
ApiTestRegistry,
} from '@backstage/core-api';
const { PrivateAppImpl } = privateExports;
const NotFoundErrorPage = () => {
throw new Error('Reached NotFound Page');
};
/**
* Options to customize the behavior of the test app wrapper.
*/
type TestAppOptions = {
/**
* Initial route entries to pass along as `initialEntries` to the router.
*/
routeEntries?: string[];
};
export function wrapInTestApp(
Component: ComponentType | ReactNode,
initialRouterEntries: string[] = ['/'],
options: TestAppOptions = {},
) {
const { routeEntries = ['/'] } = options;
const app = new PrivateAppImpl({
apis: new ApiTestRegistry(),
components: {
NotFoundErrorPage,
},
icons: defaultSystemIcons,
plugins: [],
themes: [
{
id: 'light',
theme: lightTheme,
title: 'Test App Theme',
variant: 'light',
},
],
});
let Wrapper: ComponentType;
if (Component instanceof Function) {
Wrapper = Component;
@@ -31,21 +68,13 @@ export function wrapInTestApp(
Wrapper = (() => Component) as FunctionComponent;
}
const AppProvider = app.getProvider();
return (
<MemoryRouter initialEntries={initialRouterEntries}>
<Route component={Wrapper} />
</MemoryRouter>
<AppProvider>
<MemoryRouter initialEntries={routeEntries}>
<Route component={Wrapper} />
</MemoryRouter>
</AppProvider>
);
}
export function wrapInThemedTestApp(
component: ReactNode,
initialRouterEntries: string[] = ['/'],
) {
const themed = <ThemeProvider theme={lightTheme}>{component}</ThemeProvider>;
return wrapInTestApp(themed, initialRouterEntries);
}
export const wrapInTheme = (component: ReactNode, theme = lightTheme) => (
<ThemeProvider theme={theme}>{component}</ThemeProvider>
);