frontend-test-utils: add createExtensionTester

Co-authored-by: Vincenzo Scamporlino <vincenzos@spotify.com>
Co-authored-by: Camila Belo <camilaibs@gmail.com>
Co-authored-by: Fredrik Adelöw <freben@gmail.com>
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2023-11-15 12:24:01 +01:00
parent 67972f83f9
commit 59fabd5106
7 changed files with 158 additions and 2 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/frontend-test-utils': patch
---
Added `createExtensionTester` for rendering extensions in tests.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/frontend-test-utils': minor
---
New testing utility library for `@backstage/frontend-app-api` and `@backstagr/frontend-plugin-api`.
+8 -1
View File
@@ -28,5 +28,12 @@
},
"files": [
"dist"
]
],
"dependencies": {
"@backstage/frontend-app-api": "workspace:^",
"@backstage/frontend-plugin-api": "workspace:^",
"@backstage/test-utils": "workspace:^",
"@backstage/types": "workspace:^",
"@testing-library/react": "^14.0.0"
}
}
@@ -0,0 +1,117 @@
/*
* Copyright 2023 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 { createApp } from '@backstage/frontend-app-api';
import { Extension, createPlugin } from '@backstage/frontend-plugin-api';
import { MockConfigApi } from '@backstage/test-utils';
import { JsonArray, JsonObject, JsonValue } from '@backstage/types';
import { RenderResult, render, waitFor } from '@testing-library/react';
class ExtensionTester {
/** @internal */
static forSubject<TConfig>(
subject: Extension<TConfig>,
options?: { config?: TConfig },
): ExtensionTester {
const tester = new ExtensionTester();
tester.add(subject, options);
return tester;
}
readonly #extensions = new Array<{
extension: Extension<any>;
config?: JsonValue;
}>();
add<TConfig>(
extension: Extension<TConfig>,
options?: { config?: TConfig },
): ExtensionTester {
this.#extensions.push({
extension,
config: options?.config as JsonValue,
});
return this;
}
async render(options?: { config?: JsonObject }): Promise<RenderResult> {
const { config = {} } = options ?? {};
const [subject, ...rest] = this.#extensions;
if (!subject) {
throw new Error(
'No subject found. At least one extension should be added to the tester.',
);
}
const extensionsConfig: JsonArray = [
...rest.map(entry => ({
[entry.extension.id]: {
config: entry.config,
},
})),
{
[subject.extension.id]: {
attachTo: { id: 'core', input: 'root' },
config: subject.config,
disabled: false,
},
},
{
'core.layout': false,
},
{
'core.nav': false,
},
{
'core.routes': false,
},
];
const finalConfig = {
...config,
app: {
...(typeof config.app === 'object' ? config.app : undefined),
extensions: extensionsConfig,
},
};
const app = createApp({
features: [
createPlugin({
id: 'test',
extensions: this.#extensions.map(entry => entry.extension),
}),
],
configLoader: async () => new MockConfigApi(finalConfig),
});
const result = render(app.createRoot());
await waitFor(() =>
// eslint-disable-next-line jest/no-standalone-expect
expect(result.queryByText('Loading...')).not.toBeInTheDocument(),
);
return result;
}
}
export function createExtensionTester<TConfig>(
subject: Extension<TConfig>,
options?: { config?: TConfig },
): ExtensionTester {
return ExtensionTester.forSubject(subject, options);
}
@@ -0,0 +1,17 @@
/*
* Copyright 2023 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.
*/
export { createExtensionTester } from './createExtensionTester';
+1 -1
View File
@@ -14,4 +14,4 @@
* limitations under the License.
*/
export {};
export * from './app';
+5
View File
@@ -4350,7 +4350,12 @@ __metadata:
resolution: "@backstage/frontend-test-utils@workspace:packages/frontend-test-utils"
dependencies:
"@backstage/cli": "workspace:^"
"@backstage/frontend-app-api": "workspace:^"
"@backstage/frontend-plugin-api": "workspace:^"
"@backstage/test-utils": "workspace:^"
"@backstage/types": "workspace:^"
"@testing-library/jest-dom": ^6.0.0
"@testing-library/react": ^14.0.0
languageName: unknown
linkType: soft