Merge pull request #31353 from backstage/fix/not-found
NFS: fixed Not found page when a page extension is mounted on /
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-app': patch
|
||||
---
|
||||
|
||||
Fixed an issue that caused the `NotFound` page to not render correctly when a Page was mounted at `/`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/frontend-test-utils': minor
|
||||
---
|
||||
|
||||
**BREAKING**: Removed the `extensions` option from `renderInTestApp`. If you need to pass extensions to the test app, use the new `renderTestApp` utility instead.
|
||||
@@ -39,7 +39,7 @@ import {
|
||||
useApp,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { screen } from '@testing-library/react';
|
||||
import { renderInTestApp } from '@backstage/frontend-test-utils';
|
||||
import { renderTestApp } from '@backstage/frontend-test-utils';
|
||||
|
||||
const exampleApiRef = createApiRef<string>({
|
||||
id: 'plugin.example.service',
|
||||
@@ -304,7 +304,7 @@ describe('collectLegacyRoutes', () => {
|
||||
</FlatRoutes>,
|
||||
);
|
||||
|
||||
renderInTestApp(<div />, { features });
|
||||
renderTestApp({ features });
|
||||
|
||||
await expect(
|
||||
screen.findByText('plugins: app, test'),
|
||||
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
createRouteRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { EntityLayout, EntitySwitch, isKind } from '@backstage/plugin-catalog';
|
||||
import { renderInTestApp } from '@backstage/frontend-test-utils';
|
||||
import { renderTestApp } from '@backstage/frontend-test-utils';
|
||||
import { default as catalogPlugin } from '@backstage/plugin-catalog/alpha';
|
||||
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
||||
import { catalogApiMock } from '@backstage/plugin-catalog-react/testUtils';
|
||||
@@ -263,7 +263,7 @@ describe('convertLegacyApp', () => {
|
||||
});
|
||||
|
||||
// Overview
|
||||
const renderOverviewTest = await renderInTestApp(<div />, {
|
||||
const renderOverviewTest = await renderTestApp({
|
||||
features: [catalogOverride, ...converted],
|
||||
initialRouteEntries: ['/catalog/default/test/x'],
|
||||
});
|
||||
@@ -272,7 +272,7 @@ describe('convertLegacyApp', () => {
|
||||
).resolves.toBeInTheDocument();
|
||||
renderOverviewTest.unmount();
|
||||
|
||||
const renderOverviewOther = await renderInTestApp(<div />, {
|
||||
const renderOverviewOther = await renderTestApp({
|
||||
features: [catalogOverride, ...converted],
|
||||
initialRouteEntries: ['/catalog/default/other/x'],
|
||||
});
|
||||
@@ -282,7 +282,7 @@ describe('convertLegacyApp', () => {
|
||||
renderOverviewOther.unmount();
|
||||
|
||||
// Foo tab
|
||||
const renderFooTest = await renderInTestApp(<div />, {
|
||||
const renderFooTest = await renderTestApp({
|
||||
features: [catalogOverride, ...converted],
|
||||
initialRouteEntries: ['/catalog/default/test/x/foo'],
|
||||
});
|
||||
@@ -291,7 +291,7 @@ describe('convertLegacyApp', () => {
|
||||
).resolves.toBeInTheDocument();
|
||||
renderFooTest.unmount();
|
||||
|
||||
const renderFooOther = await renderInTestApp(<div />, {
|
||||
const renderFooOther = await renderTestApp({
|
||||
features: [catalogOverride, ...converted],
|
||||
initialRouteEntries: ['/catalog/default/other/x/foo'],
|
||||
});
|
||||
@@ -301,7 +301,7 @@ describe('convertLegacyApp', () => {
|
||||
renderFooOther.unmount();
|
||||
|
||||
// Bar tab
|
||||
const renderBarTest = await renderInTestApp(<div />, {
|
||||
const renderBarTest = await renderTestApp({
|
||||
features: [catalogOverride, ...converted],
|
||||
initialRouteEntries: ['/catalog/default/test/x/bar'],
|
||||
});
|
||||
@@ -310,7 +310,7 @@ describe('convertLegacyApp', () => {
|
||||
).resolves.toBeInTheDocument();
|
||||
renderBarTest.unmount();
|
||||
|
||||
const renderBarOther = await renderInTestApp(<div />, {
|
||||
const renderBarOther = await renderTestApp({
|
||||
features: [catalogOverride, ...converted],
|
||||
initialRouteEntries: ['/catalog/default/other/x/bar'],
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Fragment } from 'react';
|
||||
import { AppRootWrapperBlueprint } from './AppRootWrapperBlueprint';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import {
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
createExtension,
|
||||
createExtensionInput,
|
||||
} from '../wiring';
|
||||
import { renderInTestApp } from '@backstage/frontend-test-utils';
|
||||
import { renderTestApp } from '@backstage/frontend-test-utils';
|
||||
|
||||
describe('AppRootWrapperBlueprint', () => {
|
||||
it('should return an extension with sensible defaults', () => {
|
||||
@@ -63,7 +63,7 @@ describe('AppRootWrapperBlueprint', () => {
|
||||
},
|
||||
});
|
||||
|
||||
renderInTestApp(<div />, { extensions: [extension] });
|
||||
renderTestApp({ extensions: [extension] });
|
||||
|
||||
await waitFor(() => expect(screen.getByText('Hello')).toBeInTheDocument());
|
||||
});
|
||||
@@ -83,16 +83,18 @@ describe('AppRootWrapperBlueprint', () => {
|
||||
component: ({ children }) => (
|
||||
<div data-testid={`${config.name}-${inputs.children.length}`}>
|
||||
{children}
|
||||
{inputs.children.flatMap(c =>
|
||||
c.get(coreExtensionData.reactElement),
|
||||
)}
|
||||
{inputs.children.flatMap((c, index) => (
|
||||
<Fragment key={index}>
|
||||
{c.get(coreExtensionData.reactElement)}
|
||||
</Fragment>
|
||||
))}
|
||||
</div>
|
||||
),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
renderInTestApp(<div />, {
|
||||
renderTestApp({
|
||||
extensions: [
|
||||
extension,
|
||||
createExtension({
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { renderInTestApp } from '@backstage/frontend-test-utils';
|
||||
import { renderTestApp } from '@backstage/frontend-test-utils';
|
||||
import { createSwappableComponent } from '../components';
|
||||
import { SwappableComponentBlueprint } from './SwappableComponentBlueprint';
|
||||
import { PageBlueprint } from './PageBlueprint';
|
||||
import { waitFor, screen } from '@testing-library/react';
|
||||
import { screen } from '@testing-library/react';
|
||||
|
||||
describe('SwappableComponentBlueprint', () => {
|
||||
it('should allow defining a component override for a component ref', () => {
|
||||
@@ -48,21 +48,19 @@ describe('SwappableComponentBlueprint', () => {
|
||||
loader: () => (props: { hello: string }) => <div>{props.hello}</div>,
|
||||
});
|
||||
|
||||
renderInTestApp(<div />, {
|
||||
renderTestApp({
|
||||
extensions: [
|
||||
PageBlueprint.make({
|
||||
params: define =>
|
||||
define({
|
||||
// todo(blam): there's a bug that this path cannot be `/`?
|
||||
path: '/test',
|
||||
path: '/',
|
||||
loader: async () => <TestComponent hello="test!" />,
|
||||
}),
|
||||
}),
|
||||
],
|
||||
initialRouteEntries: ['/test'],
|
||||
});
|
||||
|
||||
await waitFor(() => expect(screen.getByText('test!')).toBeInTheDocument());
|
||||
await expect(screen.findByText('test!')).resolves.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render a component ref without a default implementation', async () => {
|
||||
@@ -70,22 +68,21 @@ describe('SwappableComponentBlueprint', () => {
|
||||
id: 'test.component',
|
||||
});
|
||||
|
||||
renderInTestApp(<div />, {
|
||||
renderTestApp({
|
||||
extensions: [
|
||||
PageBlueprint.make({
|
||||
params: define =>
|
||||
define({
|
||||
path: '/test',
|
||||
path: '/',
|
||||
loader: async () => <TestComponent />,
|
||||
}),
|
||||
}),
|
||||
],
|
||||
initialRouteEntries: ['/test'],
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
expect(screen.getByTestId('test.component')).toBeInTheDocument(),
|
||||
);
|
||||
await expect(
|
||||
screen.findByTestId('test.component'),
|
||||
).resolves.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render a component ref with an async loader implementation', async () => {
|
||||
@@ -95,21 +92,20 @@ describe('SwappableComponentBlueprint', () => {
|
||||
<div>{props.hello}</div>,
|
||||
});
|
||||
|
||||
renderInTestApp(<div />, {
|
||||
renderTestApp({
|
||||
extensions: [
|
||||
PageBlueprint.make({
|
||||
params: define =>
|
||||
define({
|
||||
// todo(blam): there's a bug that this path cannot be `/`?
|
||||
path: '/test',
|
||||
path: '/',
|
||||
loader: async () => <TestComponent hello="test!" />,
|
||||
}),
|
||||
}),
|
||||
],
|
||||
initialRouteEntries: ['/test'],
|
||||
});
|
||||
|
||||
await waitFor(() => expect(screen.getByText('test!')).toBeInTheDocument());
|
||||
await expect(screen.findByText('test!')).resolves.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render a component ref with an async loader implementation and prop transform', async () => {
|
||||
@@ -120,22 +116,18 @@ describe('SwappableComponentBlueprint', () => {
|
||||
transformProps: ({ hello }) => ({ hello: `tr ${hello}` }),
|
||||
});
|
||||
|
||||
renderInTestApp(<div />, {
|
||||
renderTestApp({
|
||||
extensions: [
|
||||
PageBlueprint.make({
|
||||
params: define =>
|
||||
define({
|
||||
// todo(blam): there's a bug that this path cannot be `/`?
|
||||
path: '/test',
|
||||
path: '/',
|
||||
loader: async () => <TestComponent hello="test!" />,
|
||||
}),
|
||||
}),
|
||||
],
|
||||
initialRouteEntries: ['/test'],
|
||||
});
|
||||
|
||||
await waitFor(() =>
|
||||
expect(screen.getByText('tr test!')).toBeInTheDocument(),
|
||||
);
|
||||
await expect(screen.findByText('tr test!')).resolves.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,6 +29,7 @@ import { RouteRef } from '@backstage/frontend-plugin-api';
|
||||
import { TestApiProvider } from '@backstage/test-utils';
|
||||
import { TestApiProviderProps } from '@backstage/test-utils';
|
||||
import { TestApiRegistry } from '@backstage/test-utils';
|
||||
import { testingLibraryDomTypesQueries } from '@testing-library/dom/types/queries';
|
||||
import { withLogCollector } from '@backstage/test-utils';
|
||||
|
||||
export { ApiMock };
|
||||
@@ -119,6 +120,19 @@ export function renderInTestApp(
|
||||
options?: TestAppOptions,
|
||||
): RenderResult;
|
||||
|
||||
// @public
|
||||
export function renderTestApp(
|
||||
options: RenderTestAppOptions,
|
||||
): RenderResult<testingLibraryDomTypesQueries, HTMLElement, HTMLElement>;
|
||||
|
||||
// @public
|
||||
export type RenderTestAppOptions = {
|
||||
config?: JsonObject;
|
||||
extensions?: ExtensionDefinition<any>[];
|
||||
features?: FrontendFeature[];
|
||||
initialRouteEntries?: string[];
|
||||
};
|
||||
|
||||
export { TestApiProvider };
|
||||
|
||||
export { TestApiProviderProps };
|
||||
@@ -131,7 +145,6 @@ export type TestAppOptions = {
|
||||
[path: string]: RouteRef;
|
||||
};
|
||||
config?: JsonObject;
|
||||
extensions?: ExtensionDefinition<any>[];
|
||||
features?: FrontendFeature[];
|
||||
initialRouteEntries?: string[];
|
||||
};
|
||||
|
||||
@@ -21,3 +21,4 @@ export {
|
||||
} from './createExtensionTester';
|
||||
|
||||
export { renderInTestApp, type TestAppOptions } from './renderInTestApp';
|
||||
export { renderTestApp, type RenderTestAppOptions } from './renderTestApp';
|
||||
|
||||
@@ -67,11 +67,6 @@ export type TestAppOptions = {
|
||||
*/
|
||||
config?: JsonObject;
|
||||
|
||||
/**
|
||||
* Additional extensions to add to the test app.
|
||||
*/
|
||||
extensions?: ExtensionDefinition<any>[];
|
||||
|
||||
/**
|
||||
* Additional features to add to the test app.
|
||||
*/
|
||||
@@ -107,6 +102,12 @@ const appPluginOverride = appPlugin.withOverrides({
|
||||
appPlugin.getExtension('sign-in-page:app').override({
|
||||
disabled: true,
|
||||
}),
|
||||
appPlugin.getExtension('app/layout').override({
|
||||
disabled: true,
|
||||
}),
|
||||
appPlugin.getExtension('app/routes').override({
|
||||
disabled: true,
|
||||
}),
|
||||
appPlugin.getExtension('app/nav').override({
|
||||
output: [coreExtensionData.reactElement],
|
||||
factory(_originalFactory, { inputs }) {
|
||||
@@ -147,13 +148,10 @@ export function renderInTestApp(
|
||||
): RenderResult {
|
||||
const extensions: Array<ExtensionDefinition> = [
|
||||
createExtension({
|
||||
attachTo: { id: 'app/routes', input: 'routes' },
|
||||
output: [coreExtensionData.reactElement, coreExtensionData.routePath],
|
||||
attachTo: { id: 'app/root', input: 'children' },
|
||||
output: [coreExtensionData.reactElement],
|
||||
factory: () => {
|
||||
return [
|
||||
coreExtensionData.reactElement(element),
|
||||
coreExtensionData.routePath('/'),
|
||||
];
|
||||
return [coreExtensionData.reactElement(element)];
|
||||
},
|
||||
}),
|
||||
RouterBlueprint.make({
|
||||
@@ -190,10 +188,6 @@ export function renderInTestApp(
|
||||
}
|
||||
}
|
||||
|
||||
if (options?.extensions) {
|
||||
extensions.push(...options.extensions);
|
||||
}
|
||||
|
||||
const features: FrontendFeature[] = [
|
||||
createFrontendPlugin({
|
||||
pluginId: 'test',
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright 2025 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createSpecializedApp } from '@backstage/frontend-app-api';
|
||||
import {
|
||||
coreExtensionData,
|
||||
createFrontendPlugin,
|
||||
ExtensionDefinition,
|
||||
FrontendFeature,
|
||||
RouterBlueprint,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { render } from '@testing-library/react';
|
||||
import appPlugin from '@backstage/plugin-app';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
|
||||
const DEFAULT_MOCK_CONFIG = {
|
||||
app: { baseUrl: 'http://localhost:3000' },
|
||||
backend: { baseUrl: 'http://localhost:7007' },
|
||||
};
|
||||
|
||||
/**
|
||||
* Options for `renderTestApp`.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type RenderTestAppOptions = {
|
||||
/**
|
||||
* Additional configuration passed to the app when rendering elements inside it.
|
||||
*/
|
||||
config?: JsonObject;
|
||||
/**
|
||||
* Additional extensions to add to the test app.
|
||||
*/
|
||||
extensions?: ExtensionDefinition<any>[];
|
||||
|
||||
/**
|
||||
* Additional features to add to the test app.
|
||||
*/
|
||||
features?: FrontendFeature[];
|
||||
|
||||
/**
|
||||
* Initial route entries to use for the router.
|
||||
*/
|
||||
initialRouteEntries?: string[];
|
||||
};
|
||||
|
||||
const appPluginOverride = appPlugin.withOverrides({
|
||||
extensions: [
|
||||
appPlugin.getExtension('sign-in-page:app').override({
|
||||
disabled: true,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
/**
|
||||
* Renders the provided extensions inside a Backstage app, returning the same
|
||||
* utilities as `@testing-library/react` `render` function.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function renderTestApp(options: RenderTestAppOptions) {
|
||||
const extensions = [
|
||||
RouterBlueprint.make({
|
||||
params: {
|
||||
component: ({ children }) => (
|
||||
<MemoryRouter initialEntries={options.initialRouteEntries}>
|
||||
{children}
|
||||
</MemoryRouter>
|
||||
),
|
||||
},
|
||||
}),
|
||||
...(options.extensions ?? []),
|
||||
];
|
||||
|
||||
const features: FrontendFeature[] = [
|
||||
createFrontendPlugin({
|
||||
pluginId: 'test',
|
||||
extensions,
|
||||
}),
|
||||
appPluginOverride,
|
||||
];
|
||||
|
||||
if (options.features) {
|
||||
features.push(...options.features);
|
||||
}
|
||||
|
||||
const app = createSpecializedApp({
|
||||
features,
|
||||
config: ConfigReader.fromConfigs([
|
||||
{
|
||||
context: 'render-config',
|
||||
data: options?.config ?? DEFAULT_MOCK_CONFIG,
|
||||
},
|
||||
]),
|
||||
});
|
||||
|
||||
return render(
|
||||
app.tree.root.instance!.getData(coreExtensionData.reactElement),
|
||||
);
|
||||
}
|
||||
+68
-13
@@ -16,6 +16,7 @@
|
||||
|
||||
import {
|
||||
ApiBlueprint,
|
||||
AppRootElementBlueprint,
|
||||
createExtensionInput,
|
||||
createFrontendModule,
|
||||
createSwappableComponent,
|
||||
@@ -24,7 +25,7 @@ import {
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { DefaultSwappableComponentsApi } from './DefaultSwappableComponentsApi';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { renderInTestApp } from '@backstage/frontend-test-utils';
|
||||
import { renderInTestApp, renderTestApp } from '@backstage/frontend-test-utils';
|
||||
|
||||
const { ref: testRefA } = createSwappableComponent({ id: 'test.a' });
|
||||
const { ref: testRefB1 } = createSwappableComponent({ id: 'test.b' });
|
||||
@@ -149,8 +150,17 @@ describe('DefaultSwappableComponentsApi', () => {
|
||||
id: 'test.mock',
|
||||
});
|
||||
|
||||
renderInTestApp(<MockComponent />, {
|
||||
extensions: [api],
|
||||
renderTestApp({
|
||||
extensions: [
|
||||
AppRootElementBlueprint.make({
|
||||
name: 'derp',
|
||||
params: define =>
|
||||
define({
|
||||
element: <MockComponent />,
|
||||
}),
|
||||
}),
|
||||
api,
|
||||
],
|
||||
});
|
||||
|
||||
await expect(
|
||||
@@ -164,8 +174,17 @@ describe('DefaultSwappableComponentsApi', () => {
|
||||
loader: () => () => <div>test.mock</div>,
|
||||
});
|
||||
|
||||
renderInTestApp(<MockComponent />, {
|
||||
extensions: [api],
|
||||
renderTestApp({
|
||||
extensions: [
|
||||
AppRootElementBlueprint.make({
|
||||
name: 'derp',
|
||||
params: define =>
|
||||
define({
|
||||
element: <MockComponent />,
|
||||
}),
|
||||
}),
|
||||
api,
|
||||
],
|
||||
});
|
||||
|
||||
await expect(
|
||||
@@ -179,8 +198,17 @@ describe('DefaultSwappableComponentsApi', () => {
|
||||
loader: async () => () => <div>test.mock</div>,
|
||||
});
|
||||
|
||||
renderInTestApp(<MockComponent />, {
|
||||
extensions: [api],
|
||||
renderTestApp({
|
||||
extensions: [
|
||||
AppRootElementBlueprint.make({
|
||||
name: 'derp',
|
||||
params: define =>
|
||||
define({
|
||||
element: <MockComponent />,
|
||||
}),
|
||||
}),
|
||||
api,
|
||||
],
|
||||
});
|
||||
|
||||
await expect(
|
||||
@@ -202,8 +230,17 @@ describe('DefaultSwappableComponentsApi', () => {
|
||||
}),
|
||||
});
|
||||
|
||||
renderInTestApp(<MockComponent />, {
|
||||
extensions: [api],
|
||||
renderTestApp({
|
||||
extensions: [
|
||||
AppRootElementBlueprint.make({
|
||||
name: 'derp',
|
||||
params: define =>
|
||||
define({
|
||||
element: <MockComponent />,
|
||||
}),
|
||||
}),
|
||||
api,
|
||||
],
|
||||
features: [
|
||||
createFrontendModule({
|
||||
pluginId: 'app',
|
||||
@@ -231,8 +268,17 @@ describe('DefaultSwappableComponentsApi', () => {
|
||||
}),
|
||||
});
|
||||
|
||||
renderInTestApp(<MockComponent />, {
|
||||
extensions: [api],
|
||||
renderTestApp({
|
||||
extensions: [
|
||||
AppRootElementBlueprint.make({
|
||||
name: 'derp',
|
||||
params: define =>
|
||||
define({
|
||||
element: <MockComponent />,
|
||||
}),
|
||||
}),
|
||||
api,
|
||||
],
|
||||
features: [
|
||||
createFrontendModule({
|
||||
pluginId: 'app',
|
||||
@@ -264,8 +310,17 @@ describe('DefaultSwappableComponentsApi', () => {
|
||||
}),
|
||||
});
|
||||
|
||||
renderInTestApp(<MockComponent external="test" />, {
|
||||
extensions: [api],
|
||||
renderTestApp({
|
||||
extensions: [
|
||||
AppRootElementBlueprint.make({
|
||||
name: 'derp',
|
||||
params: define =>
|
||||
define({
|
||||
element: <MockComponent external="test" />,
|
||||
}),
|
||||
}),
|
||||
api,
|
||||
],
|
||||
features: [
|
||||
createFrontendModule({
|
||||
pluginId: 'app',
|
||||
|
||||
@@ -36,12 +36,18 @@ export const AppRoutes = createExtension({
|
||||
factory({ inputs }) {
|
||||
const Routes = () => {
|
||||
const element = useRoutes([
|
||||
...inputs.routes.map(route => ({
|
||||
path: `${route
|
||||
.get(coreExtensionData.routePath)
|
||||
.replace(/\/$/, '')}/*`,
|
||||
element: route.get(coreExtensionData.reactElement),
|
||||
})),
|
||||
...inputs.routes.map(route => {
|
||||
const routePath = route.get(coreExtensionData.routePath);
|
||||
|
||||
return {
|
||||
path:
|
||||
routePath === '/'
|
||||
? routePath
|
||||
: `${routePath.replace(/\/$/, '')}/*`,
|
||||
|
||||
element: route.get(coreExtensionData.reactElement),
|
||||
};
|
||||
}),
|
||||
{
|
||||
path: '*',
|
||||
element: <NotFoundErrorPage />,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { renderInTestApp } from '@backstage/frontend-test-utils';
|
||||
import { renderTestApp } from '@backstage/frontend-test-utils';
|
||||
import { act, useEffect } from 'react';
|
||||
import {
|
||||
AppRootElementBlueprint,
|
||||
@@ -29,7 +29,7 @@ async function withDialogApi<T>(
|
||||
callback: (dialogApi: DialogApi) => Promise<T>,
|
||||
) {
|
||||
const deferred = createDeferred<DialogApi>();
|
||||
await renderInTestApp(<div />, {
|
||||
await renderTestApp({
|
||||
extensions: [
|
||||
AppRootElementBlueprint.makeWithOverrides({
|
||||
name: 'derp',
|
||||
|
||||
Reference in New Issue
Block a user