@backstage/test-utils 1.6.0-next.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # @backstage/test-utils
2
2
 
3
+ ## 1.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - d47be30: Added the icons option to the renderInTestApp function's TestAppOptions to be forwarded to the icons option of `createApp`.
8
+
9
+ ### Patch Changes
10
+
11
+ - b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons).
12
+ - 836127c: Updated dependency `@testing-library/react` to `^16.0.0`.
13
+ - Updated dependencies
14
+ - @backstage/core-app-api@1.15.0
15
+ - @backstage/core-plugin-api@1.9.4
16
+ - @backstage/theme@0.5.7
17
+ - @backstage/plugin-permission-react@0.4.26
18
+ - @backstage/config@1.2.0
19
+ - @backstage/types@1.1.1
20
+ - @backstage/plugin-permission-common@0.8.1
21
+
22
+ ## 1.6.0-next.1
23
+
24
+ ### Patch Changes
25
+
26
+ - b537bd7: Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons).
27
+ - 836127c: Updated dependency `@testing-library/react` to `^16.0.0`.
28
+ - Updated dependencies
29
+ - @backstage/core-app-api@1.14.3-next.0
30
+ - @backstage/core-plugin-api@1.9.4-next.0
31
+ - @backstage/theme@0.5.7-next.0
32
+ - @backstage/plugin-permission-react@0.4.26-next.0
33
+ - @backstage/config@1.2.0
34
+ - @backstage/types@1.1.1
35
+ - @backstage/plugin-permission-common@0.8.1
36
+
3
37
  ## 1.6.0-next.0
4
38
 
5
39
  ### Minor Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/test-utils__alpha",
3
- "version": "1.6.0-next.0",
3
+ "version": "1.6.0",
4
4
  "main": "../dist/alpha.esm.js",
5
5
  "module": "../dist/alpha.esm.js",
6
6
  "types": "../dist/alpha.d.ts"
@@ -31,7 +31,9 @@ const mockIcons = {
31
31
  group: MockIcon,
32
32
  help: MockIcon,
33
33
  user: MockIcon,
34
- warning: MockIcon
34
+ warning: MockIcon,
35
+ star: MockIcon,
36
+ unstarred: MockIcon
35
37
  };
36
38
  const ErrorBoundaryFallback = ({ error }) => {
37
39
  throw new Error(`Reached ErrorBoundaryFallback Page with error, ${error}`);
@@ -1 +1 @@
1
- {"version":3,"file":"appWrappers.esm.js","sources":["../../src/testUtils/appWrappers.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, {\n ComponentType,\n PropsWithChildren,\n ReactElement,\n ReactNode,\n} from 'react';\nimport { MemoryRouter, Route } from 'react-router-dom';\nimport { themes, UnifiedThemeProvider } from '@backstage/theme';\nimport MockIcon from '@material-ui/icons/AcUnit';\nimport { AppIcons, createSpecializedApp } from '@backstage/core-app-api';\nimport {\n AppComponents,\n attachComponentData,\n BootErrorPageProps,\n createRouteRef,\n ExternalRouteRef,\n IconComponent,\n RouteRef,\n} from '@backstage/core-plugin-api';\nimport { MatcherFunction, RenderResult } from '@testing-library/react';\nimport { LegacyRootOption, renderWithEffects } from './testingLibrary';\nimport { defaultApis } from './defaultApis';\nimport { mockApis } from './mockApis';\n\nconst mockIcons = {\n 'kind:api': MockIcon,\n 'kind:component': MockIcon,\n 'kind:domain': MockIcon,\n 'kind:group': MockIcon,\n 'kind:location': MockIcon,\n 'kind:system': MockIcon,\n 'kind:user': MockIcon,\n 'kind:resource': MockIcon,\n 'kind:template': MockIcon,\n\n brokenImage: MockIcon,\n catalog: MockIcon,\n scaffolder: MockIcon,\n techdocs: MockIcon,\n search: MockIcon,\n chat: MockIcon,\n dashboard: MockIcon,\n docs: MockIcon,\n email: MockIcon,\n github: MockIcon,\n group: MockIcon,\n help: MockIcon,\n user: MockIcon,\n warning: MockIcon,\n};\n\nconst ErrorBoundaryFallback = ({ error }: { error: Error }) => {\n throw new Error(`Reached ErrorBoundaryFallback Page with error, ${error}`);\n};\nconst NotFoundErrorPage = () => {\n throw new Error('Reached NotFound Page');\n};\nconst BootErrorPage = ({ step, error }: BootErrorPageProps) => {\n throw new Error(`Reached BootError Page at step ${step} with error ${error}`);\n};\nconst Progress = () => <div data-testid=\"progress\" />;\n\nconst NoRender = (_props: { children: ReactNode }) => null;\n\n/**\n * Options to customize the behavior of the test app wrapper.\n * @public\n */\nexport type TestAppOptions = {\n /**\n * Initial route entries to pass along as `initialEntries` to the router.\n */\n routeEntries?: string[];\n\n /**\n * An object of paths to mount route ref on, with the key being the path and the value\n * being the RouteRef that the path will be bound to. This allows the route refs to be\n * used by `useRouteRef` in the rendered elements.\n *\n * @example\n * wrapInTestApp(<MyComponent />, \\{\n * mountedRoutes: \\{\n * '/my-path': myRouteRef,\n * \\}\n * \\})\n * // ...\n * const link = useRouteRef(myRouteRef)\n */\n mountedRoutes?: { [path: string]: RouteRef | ExternalRouteRef };\n\n /**\n * Components to be forwarded to the `components` option of `createApp`.\n */\n components?: Partial<AppComponents>;\n\n /**\n * Icons to be forwarded to the `icons` option of `createApp`.\n */\n icons?: Partial<AppIcons> & {\n [key in string]: IconComponent;\n };\n};\n\nfunction isExternalRouteRef(\n routeRef: RouteRef | ExternalRouteRef,\n): routeRef is ExternalRouteRef {\n // TODO(Rugvip): Least ugly workaround for now, but replace :D\n return String(routeRef).includes('{type=external,');\n}\n\n/**\n * Creates a Wrapper component that wraps a component inside a Backstage test app,\n * providing a mocked theme and app context, along with mocked APIs.\n *\n * @param options - Additional options for the rendering.\n * @public\n */\nexport function createTestAppWrapper(\n options: TestAppOptions = {},\n): (props: { children: ReactNode }) => JSX.Element {\n const { routeEntries = ['/'] } = options;\n const boundRoutes = new Map<ExternalRouteRef, RouteRef>();\n\n const app = createSpecializedApp({\n apis: mockApis,\n defaultApis,\n // Bit of a hack to make sure that the default config loader isn't used\n // as that would force every single test to wait for config loading.\n configLoader: false as unknown as undefined,\n components: {\n Progress,\n BootErrorPage,\n NotFoundErrorPage,\n ErrorBoundaryFallback,\n Router: ({ children }) => (\n <MemoryRouter initialEntries={routeEntries} children={children} />\n ),\n ...options.components,\n },\n icons: {\n ...mockIcons,\n ...options.icons,\n },\n plugins: [],\n themes: [\n {\n id: 'light',\n title: 'Test App Theme',\n variant: 'light',\n Provider: ({ children }) => (\n <UnifiedThemeProvider theme={themes.light}>\n {children}\n </UnifiedThemeProvider>\n ),\n },\n ],\n bindRoutes: ({ bind }) => {\n for (const [externalRef, absoluteRef] of boundRoutes) {\n bind(\n { ref: externalRef },\n {\n ref: absoluteRef,\n },\n );\n }\n },\n });\n\n const routeElements = Object.entries(options.mountedRoutes ?? {}).map(\n ([path, routeRef]) => {\n const Page = () => <div>Mounted at {path}</div>;\n\n // Allow external route refs to be bound to paths as well, for convenience.\n // We work around it by creating and binding an absolute ref to the external one.\n if (isExternalRouteRef(routeRef)) {\n const absoluteRef = createRouteRef({ id: 'id' });\n boundRoutes.set(routeRef, absoluteRef);\n attachComponentData(Page, 'core.mountPoint', absoluteRef);\n } else {\n attachComponentData(Page, 'core.mountPoint', routeRef);\n }\n return <Route key={path} path={path} element={<Page />} />;\n },\n );\n\n const AppProvider = app.getProvider();\n const AppRouter = app.getRouter();\n\n const TestAppWrapper = ({ children }: { children: ReactNode }) => (\n <AppProvider>\n <AppRouter>\n <NoRender>{routeElements}</NoRender>\n {children}\n </AppRouter>\n </AppProvider>\n );\n\n return TestAppWrapper;\n}\n\n/**\n * Wraps a component inside a Backstage test app, providing a mocked theme\n * and app context, along with mocked APIs.\n *\n * @param Component - A component or react node to render inside the test app.\n * @param options - Additional options for the rendering.\n * @public\n */\nexport function wrapInTestApp(\n Component: ComponentType | ReactNode,\n options: TestAppOptions = {},\n): ReactElement {\n const TestAppWrapper = createTestAppWrapper(options);\n\n let wrappedElement: React.ReactElement;\n if (Component instanceof Function) {\n wrappedElement = React.createElement(Component as ComponentType);\n } else {\n wrappedElement = Component as React.ReactElement;\n }\n\n return <TestAppWrapper>{wrappedElement}</TestAppWrapper>;\n}\n\n/**\n * Renders a component inside a Backstage test app, providing a mocked theme\n * and app context, along with mocked APIs.\n *\n * The render executes async effects similar to `renderWithEffects`. To avoid this\n * behavior, use a regular `render()` + `wrapInTestApp()` instead.\n *\n * @param Component - A component or react node to render inside the test app.\n * @param options - Additional options for the rendering.\n * @public\n */\nexport async function renderInTestApp(\n Component: ComponentType<PropsWithChildren<{}>> | ReactNode,\n options: TestAppOptions & LegacyRootOption = {},\n): Promise<RenderResult> {\n let wrappedElement: React.ReactElement;\n if (Component instanceof Function) {\n wrappedElement = React.createElement(Component as ComponentType);\n } else {\n wrappedElement = Component as React.ReactElement;\n }\n const { legacyRoot } = options;\n\n return renderWithEffects(wrappedElement, {\n wrapper: createTestAppWrapper(options),\n legacyRoot,\n });\n}\n\n/**\n * Returns a `@testing-library/react` valid MatcherFunction for supplied text\n *\n * @param string - text Text to match by element's textContent\n *\n * @public\n */\nexport const textContentMatcher =\n (text: string): MatcherFunction =>\n (_, node) => {\n if (!node) {\n return false;\n }\n\n const hasText = (textNode: Element) =>\n textNode?.textContent?.includes(text) ?? false;\n const childrenDontHaveText = (containerNode: Element) =>\n Array.from(containerNode?.children).every(child => !hasText(child));\n\n return hasText(node) && childrenDontHaveText(node);\n };\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"appWrappers.esm.js","sources":["../../src/testUtils/appWrappers.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, {\n ComponentType,\n PropsWithChildren,\n ReactElement,\n ReactNode,\n} from 'react';\nimport { MemoryRouter, Route } from 'react-router-dom';\nimport { themes, UnifiedThemeProvider } from '@backstage/theme';\nimport MockIcon from '@material-ui/icons/AcUnit';\nimport { AppIcons, createSpecializedApp } from '@backstage/core-app-api';\nimport {\n AppComponents,\n attachComponentData,\n BootErrorPageProps,\n createRouteRef,\n ExternalRouteRef,\n IconComponent,\n RouteRef,\n} from '@backstage/core-plugin-api';\nimport { MatcherFunction, RenderResult } from '@testing-library/react';\nimport { LegacyRootOption, renderWithEffects } from './testingLibrary';\nimport { defaultApis } from './defaultApis';\nimport { mockApis } from './mockApis';\n\nconst mockIcons = {\n 'kind:api': MockIcon,\n 'kind:component': MockIcon,\n 'kind:domain': MockIcon,\n 'kind:group': MockIcon,\n 'kind:location': MockIcon,\n 'kind:system': MockIcon,\n 'kind:user': MockIcon,\n 'kind:resource': MockIcon,\n 'kind:template': MockIcon,\n\n brokenImage: MockIcon,\n catalog: MockIcon,\n scaffolder: MockIcon,\n techdocs: MockIcon,\n search: MockIcon,\n chat: MockIcon,\n dashboard: MockIcon,\n docs: MockIcon,\n email: MockIcon,\n github: MockIcon,\n group: MockIcon,\n help: MockIcon,\n user: MockIcon,\n warning: MockIcon,\n star: MockIcon,\n unstarred: MockIcon,\n};\n\nconst ErrorBoundaryFallback = ({ error }: { error: Error }) => {\n throw new Error(`Reached ErrorBoundaryFallback Page with error, ${error}`);\n};\nconst NotFoundErrorPage = () => {\n throw new Error('Reached NotFound Page');\n};\nconst BootErrorPage = ({ step, error }: BootErrorPageProps) => {\n throw new Error(`Reached BootError Page at step ${step} with error ${error}`);\n};\nconst Progress = () => <div data-testid=\"progress\" />;\n\nconst NoRender = (_props: { children: ReactNode }) => null;\n\n/**\n * Options to customize the behavior of the test app wrapper.\n * @public\n */\nexport type TestAppOptions = {\n /**\n * Initial route entries to pass along as `initialEntries` to the router.\n */\n routeEntries?: string[];\n\n /**\n * An object of paths to mount route ref on, with the key being the path and the value\n * being the RouteRef that the path will be bound to. This allows the route refs to be\n * used by `useRouteRef` in the rendered elements.\n *\n * @example\n * wrapInTestApp(<MyComponent />, \\{\n * mountedRoutes: \\{\n * '/my-path': myRouteRef,\n * \\}\n * \\})\n * // ...\n * const link = useRouteRef(myRouteRef)\n */\n mountedRoutes?: { [path: string]: RouteRef | ExternalRouteRef };\n\n /**\n * Components to be forwarded to the `components` option of `createApp`.\n */\n components?: Partial<AppComponents>;\n\n /**\n * Icons to be forwarded to the `icons` option of `createApp`.\n */\n icons?: Partial<AppIcons> & {\n [key in string]: IconComponent;\n };\n};\n\nfunction isExternalRouteRef(\n routeRef: RouteRef | ExternalRouteRef,\n): routeRef is ExternalRouteRef {\n // TODO(Rugvip): Least ugly workaround for now, but replace :D\n return String(routeRef).includes('{type=external,');\n}\n\n/**\n * Creates a Wrapper component that wraps a component inside a Backstage test app,\n * providing a mocked theme and app context, along with mocked APIs.\n *\n * @param options - Additional options for the rendering.\n * @public\n */\nexport function createTestAppWrapper(\n options: TestAppOptions = {},\n): (props: { children: ReactNode }) => JSX.Element {\n const { routeEntries = ['/'] } = options;\n const boundRoutes = new Map<ExternalRouteRef, RouteRef>();\n\n const app = createSpecializedApp({\n apis: mockApis,\n defaultApis,\n // Bit of a hack to make sure that the default config loader isn't used\n // as that would force every single test to wait for config loading.\n configLoader: false as unknown as undefined,\n components: {\n Progress,\n BootErrorPage,\n NotFoundErrorPage,\n ErrorBoundaryFallback,\n Router: ({ children }) => (\n <MemoryRouter initialEntries={routeEntries} children={children} />\n ),\n ...options.components,\n },\n icons: {\n ...mockIcons,\n ...options.icons,\n },\n plugins: [],\n themes: [\n {\n id: 'light',\n title: 'Test App Theme',\n variant: 'light',\n Provider: ({ children }) => (\n <UnifiedThemeProvider theme={themes.light}>\n {children}\n </UnifiedThemeProvider>\n ),\n },\n ],\n bindRoutes: ({ bind }) => {\n for (const [externalRef, absoluteRef] of boundRoutes) {\n bind(\n { ref: externalRef },\n {\n ref: absoluteRef,\n },\n );\n }\n },\n });\n\n const routeElements = Object.entries(options.mountedRoutes ?? {}).map(\n ([path, routeRef]) => {\n const Page = () => <div>Mounted at {path}</div>;\n\n // Allow external route refs to be bound to paths as well, for convenience.\n // We work around it by creating and binding an absolute ref to the external one.\n if (isExternalRouteRef(routeRef)) {\n const absoluteRef = createRouteRef({ id: 'id' });\n boundRoutes.set(routeRef, absoluteRef);\n attachComponentData(Page, 'core.mountPoint', absoluteRef);\n } else {\n attachComponentData(Page, 'core.mountPoint', routeRef);\n }\n return <Route key={path} path={path} element={<Page />} />;\n },\n );\n\n const AppProvider = app.getProvider();\n const AppRouter = app.getRouter();\n\n const TestAppWrapper = ({ children }: { children: ReactNode }) => (\n <AppProvider>\n <AppRouter>\n <NoRender>{routeElements}</NoRender>\n {children}\n </AppRouter>\n </AppProvider>\n );\n\n return TestAppWrapper;\n}\n\n/**\n * Wraps a component inside a Backstage test app, providing a mocked theme\n * and app context, along with mocked APIs.\n *\n * @param Component - A component or react node to render inside the test app.\n * @param options - Additional options for the rendering.\n * @public\n */\nexport function wrapInTestApp(\n Component: ComponentType | ReactNode,\n options: TestAppOptions = {},\n): ReactElement {\n const TestAppWrapper = createTestAppWrapper(options);\n\n let wrappedElement: React.ReactElement;\n if (Component instanceof Function) {\n wrappedElement = React.createElement(Component as ComponentType);\n } else {\n wrappedElement = Component as React.ReactElement;\n }\n\n return <TestAppWrapper>{wrappedElement}</TestAppWrapper>;\n}\n\n/**\n * Renders a component inside a Backstage test app, providing a mocked theme\n * and app context, along with mocked APIs.\n *\n * The render executes async effects similar to `renderWithEffects`. To avoid this\n * behavior, use a regular `render()` + `wrapInTestApp()` instead.\n *\n * @param Component - A component or react node to render inside the test app.\n * @param options - Additional options for the rendering.\n * @public\n */\nexport async function renderInTestApp(\n Component: ComponentType<PropsWithChildren<{}>> | ReactNode,\n options: TestAppOptions & LegacyRootOption = {},\n): Promise<RenderResult> {\n let wrappedElement: React.ReactElement;\n if (Component instanceof Function) {\n wrappedElement = React.createElement(Component as ComponentType);\n } else {\n wrappedElement = Component as React.ReactElement;\n }\n const { legacyRoot } = options;\n\n return renderWithEffects(wrappedElement, {\n wrapper: createTestAppWrapper(options),\n legacyRoot,\n });\n}\n\n/**\n * Returns a `@testing-library/react` valid MatcherFunction for supplied text\n *\n * @param string - text Text to match by element's textContent\n *\n * @public\n */\nexport const textContentMatcher =\n (text: string): MatcherFunction =>\n (_, node) => {\n if (!node) {\n return false;\n }\n\n const hasText = (textNode: Element) =>\n textNode?.textContent?.includes(text) ?? false;\n const childrenDontHaveText = (containerNode: Element) =>\n Array.from(containerNode?.children).every(child => !hasText(child));\n\n return hasText(node) && childrenDontHaveText(node);\n };\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/test-utils",
3
- "version": "1.6.0-next.0",
3
+ "version": "1.6.0",
4
4
  "description": "Utilities to test Backstage plugins and apps.",
5
5
  "backstage": {
6
6
  "role": "web-library"
@@ -49,11 +49,11 @@
49
49
  },
50
50
  "dependencies": {
51
51
  "@backstage/config": "^1.2.0",
52
- "@backstage/core-app-api": "^1.14.2",
53
- "@backstage/core-plugin-api": "^1.9.3",
52
+ "@backstage/core-app-api": "^1.15.0",
53
+ "@backstage/core-plugin-api": "^1.9.4",
54
54
  "@backstage/plugin-permission-common": "^0.8.1",
55
- "@backstage/plugin-permission-react": "^0.4.25",
56
- "@backstage/theme": "^0.5.6",
55
+ "@backstage/plugin-permission-react": "^0.4.26",
56
+ "@backstage/theme": "^0.5.7",
57
57
  "@backstage/types": "^1.1.1",
58
58
  "@material-ui/core": "^4.12.2",
59
59
  "@material-ui/icons": "^4.9.1",
@@ -63,12 +63,12 @@
63
63
  "zen-observable": "^0.10.0"
64
64
  },
65
65
  "devDependencies": {
66
- "@backstage/cli": "^0.27.1-next.0",
66
+ "@backstage/cli": "^0.27.1",
67
67
  "@testing-library/jest-dom": "^6.0.0",
68
68
  "msw": "^1.0.0"
69
69
  },
70
70
  "peerDependencies": {
71
- "@testing-library/react": "^15.0.0",
71
+ "@testing-library/react": "^16.0.0",
72
72
  "react": "^16.13.1 || ^17.0.0 || ^18.0.0",
73
73
  "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0",
74
74
  "react-router-dom": "6.0.0-beta.0 || ^6.3.0"