diff --git a/.changeset/dirty-bugs-care.md b/.changeset/dirty-bugs-care.md new file mode 100644 index 0000000000..4d90a9c939 --- /dev/null +++ b/.changeset/dirty-bugs-care.md @@ -0,0 +1,9 @@ +--- +'@backstage/test-utils': patch +'@backstage/test-utils-core': patch +--- + +Migrates all utility methods from `test-utils-core` into `test-utils` and delete exports from the old package. +This should have no impact since this package is considered internal and have no usages outside core packages. + +Notable changes are that the testing tool `msw.setupDefaultHandlers()` have been deprecated in favour of `setupRequestMockHandlers()`. diff --git a/.changeset/rude-starfishes-walk.md b/.changeset/rude-starfishes-walk.md new file mode 100644 index 0000000000..87ec76fd0a --- /dev/null +++ b/.changeset/rude-starfishes-walk.md @@ -0,0 +1,7 @@ +--- +'@backstage/config': patch +'@backstage/core-app-api': patch +'@backstage/core-plugin-api': patch +--- + +Replace usage of test-utils-core with test-utils diff --git a/packages/config/package.json b/packages/config/package.json index 88c20a76ea..719ab22772 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -34,7 +34,7 @@ "lodash": "^4.17.21" }, "devDependencies": { - "@backstage/test-utils-core": "^0.1.2", + "@backstage/test-utils": "^0.1.19", "@types/jest": "^26.0.7", "@types/node": "^14.14.32" }, diff --git a/packages/config/src/reader.test.ts b/packages/config/src/reader.test.ts index 0cea80dca1..3cbab17637 100644 --- a/packages/config/src/reader.test.ts +++ b/packages/config/src/reader.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { withLogCollector } from '@backstage/test-utils-core'; +import { withLogCollector } from '@backstage/test-utils'; import { ConfigReader } from './reader'; const DATA = { diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index 1eca9249fc..aee8eb9f02 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -48,7 +48,6 @@ "devDependencies": { "@backstage/cli": "^0.8.0", "@backstage/test-utils": "^0.1.19", - "@backstage/test-utils-core": "^0.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", "@testing-library/react-hooks": "^7.0.2", diff --git a/packages/core-app-api/src/apis/system/ApiProvider.test.tsx b/packages/core-app-api/src/apis/system/ApiProvider.test.tsx index d1793f890e..c08674adfe 100644 --- a/packages/core-app-api/src/apis/system/ApiProvider.test.tsx +++ b/packages/core-app-api/src/apis/system/ApiProvider.test.tsx @@ -25,7 +25,7 @@ import { import { ApiProvider } from './ApiProvider'; import { ApiRegistry } from './ApiRegistry'; import { render } from '@testing-library/react'; -import { withLogCollector } from '@backstage/test-utils-core'; +import { withLogCollector } from '@backstage/test-utils'; import { useVersionedContext } from '@backstage/version-bridge'; describe('ApiProvider', () => { diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json index 38e3f4aebe..c59668a432 100644 --- a/packages/core-plugin-api/package.json +++ b/packages/core-plugin-api/package.json @@ -45,8 +45,7 @@ "devDependencies": { "@backstage/cli": "^0.8.0", "@backstage/core-app-api": "^0.1.18", - "@backstage/test-utils": "^0.1.18", - "@backstage/test-utils-core": "^0.1.3", + "@backstage/test-utils": "^0.1.19", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", "@testing-library/react-hooks": "^7.0.2", diff --git a/packages/core-plugin-api/src/extensions/extensions.test.tsx b/packages/core-plugin-api/src/extensions/extensions.test.tsx index fabf90eebb..29c696c71f 100644 --- a/packages/core-plugin-api/src/extensions/extensions.test.tsx +++ b/packages/core-plugin-api/src/extensions/extensions.test.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { withLogCollector } from '@backstage/test-utils-core'; +import { withLogCollector } from '@backstage/test-utils'; import { render, screen } from '@testing-library/react'; import React from 'react'; import { useAnalyticsContext } from '../analytics/AnalyticsContext'; diff --git a/packages/test-utils-core/api-report.md b/packages/test-utils-core/api-report.md index 4dad7a3a8a..f21c749727 100644 --- a/packages/test-utils-core/api-report.md +++ b/packages/test-utils-core/api-report.md @@ -3,113 +3,5 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { ReactElement } from 'react'; -import { RenderResult } from '@testing-library/react'; - -// Warning: (ae-missing-release-tag) "AsyncLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type AsyncLogCollector = () => Promise; - -// Warning: (ae-missing-release-tag) "CollectedLogs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type CollectedLogs = { - [key in T]: string[]; -}; - -// Warning: (ae-missing-release-tag) "Keyboard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export class Keyboard { - constructor( - target: any, - { - debug, - }?: { - debug?: boolean | undefined; - }, - ); - // (undocumented) - click(): Promise; - // (undocumented) - debug: boolean; - // (undocumented) - document: any; - // (undocumented) - enter(value: any): Promise; - // (undocumented) - escape(): Promise; - // (undocumented) - get focused(): any; - // (undocumented) - static fromReadableInput(input: any): any; - // (undocumented) - _log(message: any, ...args: any[]): void; - // (undocumented) - _pretty(element: any): string; - // (undocumented) - send(chars: any): Promise; - // (undocumented) - _sendKey(key: any, charCode: any, action: any): Promise; - // (undocumented) - tab(): Promise; - // (undocumented) - static toReadableInput(chars: any): any; - // (undocumented) - toString(): string; - // (undocumented) - static type(target: any, input: any): Promise; - // (undocumented) - type(input: any): Promise; - // (undocumented) - static typeDebug(target: any, input: any): Promise; -} - -// Warning: (ae-missing-release-tag) "LogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type LogCollector = AsyncLogCollector | SyncLogCollector; - -// Warning: (ae-missing-release-tag) "LogFuncs" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type LogFuncs = 'log' | 'warn' | 'error'; - -// Warning: (ae-missing-release-tag) "renderWithEffects" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export function renderWithEffects(nodes: ReactElement): Promise; - -// Warning: (ae-missing-release-tag) "SyncLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type SyncLogCollector = () => void; - -// Warning: (ae-missing-release-tag) "withLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "withLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "withLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "withLogCollector" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export function withLogCollector( - callback: AsyncLogCollector, -): Promise>; - -// @public (undocumented) -export function withLogCollector( - callback: SyncLogCollector, -): CollectedLogs; - -// @public (undocumented) -export function withLogCollector( - logsToCollect: T[], - callback: AsyncLogCollector, -): Promise>; - -// @public (undocumented) -export function withLogCollector( - logsToCollect: T[], - callback: SyncLogCollector, -): CollectedLogs; +// (No @packageDocumentation comment for this package) ``` diff --git a/packages/test-utils-core/package.json b/packages/test-utils-core/package.json index 474d62a670..8256714560 100644 --- a/packages/test-utils-core/package.json +++ b/packages/test-utils-core/package.json @@ -23,18 +23,12 @@ "scripts": { "build": "backstage-cli build --outputs types,esm", "lint": "backstage-cli lint", - "test": "backstage-cli test", + "test": "backstage-cli test --passWithNoTests", "prepack": "backstage-cli prepack", "postpack": "backstage-cli postpack", "clean": "backstage-cli clean" }, - "dependencies": { - "@testing-library/jest-dom": "^5.10.1", - "@testing-library/react": "^11.2.5", - "@types/react": "*", - "react": "^16.12.0", - "react-dom": "^16.12.0" - }, + "dependencies": {}, "devDependencies": { "@types/jest": "^26.0.7", "@types/node": "^14.14.32" diff --git a/packages/test-utils-core/src/index.ts b/packages/test-utils-core/src/index.ts index 5658523c11..8f0a5b31e1 100644 --- a/packages/test-utils-core/src/index.ts +++ b/packages/test-utils-core/src/index.ts @@ -14,10 +14,7 @@ * limitations under the License. */ -/** - * Utilities to test Backstage core - * - * @packageDocumentation - */ - -export * from './testUtils'; +export {}; +throw new Error( + 'This module has been removed. Use @backstage/dev-utils instead', +); diff --git a/packages/test-utils-core/src/setupTests.ts b/packages/test-utils-core/src/setupTests.ts deleted file mode 100644 index 963c0f188b..0000000000 --- a/packages/test-utils-core/src/setupTests.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 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 '@testing-library/jest-dom'; diff --git a/packages/test-utils-core/src/testUtils/index.tsx b/packages/test-utils-core/src/testUtils/index.tsx deleted file mode 100644 index 6f6aa43ea9..0000000000 --- a/packages/test-utils-core/src/testUtils/index.tsx +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2020 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 * from './Keyboard'; -export * from './logCollector'; -export * from './testingLibrary'; diff --git a/packages/test-utils/api-report.md b/packages/test-utils/api-report.md index 9bd51c4795..c4936f6d96 100644 --- a/packages/test-utils/api-report.md +++ b/packages/test-utils/api-report.md @@ -17,9 +17,73 @@ import { RouteRef } from '@backstage/core-plugin-api'; import { StorageApi } from '@backstage/core-plugin-api'; import { StorageValueChange } from '@backstage/core-plugin-api'; -// Warning: (ae-missing-release-tag) "MockAnalyticsApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export type AsyncLogCollector = () => Promise; + +// @public +export type CollectedLogs = { + [key in T]: string[]; +}; + +// @public +export type ErrorWithContext = { + error: Error; + context?: ErrorContext; +}; + +// @public @deprecated (undocumented) +export class Keyboard { + constructor( + target: any, + { + debug, + }?: { + debug?: boolean | undefined; + }, + ); + // (undocumented) + click(): Promise; + // (undocumented) + debug: boolean; + // (undocumented) + document: any; + // (undocumented) + enter(value: any): Promise; + // (undocumented) + escape(): Promise; + // (undocumented) + get focused(): any; + // (undocumented) + static fromReadableInput(input: any): any; + // (undocumented) + _log(message: any, ...args: any[]): void; + // (undocumented) + _pretty(element: any): string; + // (undocumented) + send(chars: any): Promise; + // (undocumented) + _sendKey(key: any, charCode: any, action: any): Promise; + // (undocumented) + tab(): Promise; + // (undocumented) + static toReadableInput(chars: any): any; + // (undocumented) + toString(): string; + // (undocumented) + static type(target: any, input: any): Promise; + // (undocumented) + type(input: any): Promise; + // (undocumented) + static typeDebug(target: any, input: any): Promise; +} + +// @public +export type LogCollector = AsyncLogCollector | SyncLogCollector; + +// @public +export type LogFuncs = 'log' | 'warn' | 'error'; + +// @public export class MockAnalyticsApi implements AnalyticsApi { // (undocumented) captureEvent({ @@ -33,9 +97,6 @@ export class MockAnalyticsApi implements AnalyticsApi { getEvents(): AnalyticsEvent[]; } -// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// Warning: (ae-missing-release-tag) "mockBreakpoint" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function mockBreakpoint({ matches, @@ -43,19 +104,14 @@ export function mockBreakpoint({ matches?: boolean | undefined; }): void; -// Warning: (ae-missing-release-tag) "MockErrorApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export class MockErrorApi implements ErrorApi { - // Warning: (ae-forgotten-export) The symbol "Options" needs to be exported by the entry point index.d.ts - constructor(options?: Options); + constructor(options?: MockErrorApiOptions); // (undocumented) error$(): Observable<{ error: Error; context?: ErrorContext; }>; - // Warning: (ae-forgotten-export) The symbol "ErrorWithContext" needs to be exported by the entry point index.d.ts - // // (undocumented) getErrors(): ErrorWithContext[]; // (undocumented) @@ -64,9 +120,12 @@ export class MockErrorApi implements ErrorApi { waitForError(pattern: RegExp, timeoutMs?: number): Promise; } -// Warning: (ae-missing-release-tag) "MockStorageApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export type MockErrorApiOptions = { + collect?: boolean; +}; + +// @public export class MockStorageApi implements StorageApi { // (undocumented) static create(data?: MockStorageBucket): MockStorageApi; @@ -82,16 +141,12 @@ export class MockStorageApi implements StorageApi { set(key: string, data: T): Promise; } -// Warning: (ae-missing-release-tag) "MockStorageBucket" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type MockStorageBucket = { [key: string]: any; }; -// Warning: (ae-missing-release-tag) "msw" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public @deprecated (undocumented) export const msw: { setupDefaultHandlers: (worker: { listen: (t: any) => void; @@ -100,22 +155,58 @@ export const msw: { }) => void; }; -// Warning: (ae-forgotten-export) The symbol "TestAppOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "renderInTestApp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export function renderInTestApp( Component: ComponentType | ReactNode, options?: TestAppOptions, ): Promise; -// Warning: (ae-missing-release-tag) "wrapInTestApp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// +// @public +export function renderWithEffects(nodes: ReactElement): Promise; + +// @public +export function setupRequestMockHandlers(worker: { + listen: (t: any) => void; + close: () => void; + resetHandlers: () => void; +}): void; + +// @public +export type SyncLogCollector = () => void; + +// @public +export type TestAppOptions = { + routeEntries?: string[]; + mountedRoutes?: { + [path: string]: RouteRef | ExternalRouteRef; + }; +}; + +// @public +export function withLogCollector( + callback: AsyncLogCollector, +): Promise>; + +// @public +export function withLogCollector( + callback: SyncLogCollector, +): CollectedLogs; + +// @public +export function withLogCollector( + logsToCollect: T[], + callback: AsyncLogCollector, +): Promise>; + +// @public +export function withLogCollector( + logsToCollect: T[], + callback: SyncLogCollector, +): CollectedLogs; + // @public export function wrapInTestApp( Component: ComponentType | ReactNode, options?: TestAppOptions, ): ReactElement; - -export * from '@backstage/test-utils-core'; ``` diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index f6f4ac901a..624fdf28b3 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -31,7 +31,6 @@ "dependencies": { "@backstage/core-app-api": "^0.1.18", "@backstage/core-plugin-api": "^0.1.11", - "@backstage/test-utils-core": "^0.1.3", "@backstage/theme": "^0.2.11", "@backstage/types": "^0.1.1", "@material-ui/core": "^4.12.2", diff --git a/packages/test-utils/src/index.ts b/packages/test-utils/src/index.ts index 545a5b9961..83a955baa7 100644 --- a/packages/test-utils/src/index.ts +++ b/packages/test-utils/src/index.ts @@ -21,4 +21,3 @@ */ export * from './testUtils'; -export * from '@backstage/test-utils-core'; diff --git a/packages/test-utils-core/src/testUtils/Keyboard.js b/packages/test-utils/src/testUtils/Keyboard.js similarity index 98% rename from packages/test-utils-core/src/testUtils/Keyboard.js rename to packages/test-utils/src/testUtils/Keyboard.js index 3f45ca90f6..3f4724d562 100644 --- a/packages/test-utils-core/src/testUtils/Keyboard.js +++ b/packages/test-utils/src/testUtils/Keyboard.js @@ -23,6 +23,10 @@ const codes = { Esc: 27, }; +/** + * @public + * @deprecated because it has no usages. Perhaps resurfaced in the future when need be. + */ export class Keyboard { static async type(target, input) { await new Keyboard(target).type(input); diff --git a/packages/test-utils-core/src/testUtils/Keyboard.test.js b/packages/test-utils/src/testUtils/Keyboard.test.js similarity index 100% rename from packages/test-utils-core/src/testUtils/Keyboard.test.js rename to packages/test-utils/src/testUtils/Keyboard.test.js diff --git a/packages/test-utils/src/testUtils/apis/AnalyticsApi/MockAnalyticsApi.ts b/packages/test-utils/src/testUtils/apis/AnalyticsApi/MockAnalyticsApi.ts index 28585145ad..3e2fc2a01c 100644 --- a/packages/test-utils/src/testUtils/apis/AnalyticsApi/MockAnalyticsApi.ts +++ b/packages/test-utils/src/testUtils/apis/AnalyticsApi/MockAnalyticsApi.ts @@ -16,6 +16,11 @@ import { AnalyticsApi, AnalyticsEvent } from '@backstage/core-plugin-api'; +/** + * Mock implementation of {@link core-plugin-api#AnalyticsApi} with helpers to ensure that events are sent correctly. + * Use getEvents in tests to verify captured events. + * @public + */ export class MockAnalyticsApi implements AnalyticsApi { private events: AnalyticsEvent[] = []; diff --git a/packages/test-utils/src/testUtils/apis/ErrorApi/MockErrorApi.ts b/packages/test-utils/src/testUtils/apis/ErrorApi/MockErrorApi.ts index 01ee412182..87601e29e2 100644 --- a/packages/test-utils/src/testUtils/apis/ErrorApi/MockErrorApi.ts +++ b/packages/test-utils/src/testUtils/apis/ErrorApi/MockErrorApi.ts @@ -17,11 +17,20 @@ import { ErrorApi, ErrorContext } from '@backstage/core-plugin-api'; import { Observable } from '@backstage/types'; -type Options = { +/** + * Constructor arguments for {@link MockErrorApi} + * @public + */ +export type MockErrorApiOptions = { + // Need to be true if getErrors is used in testing. collect?: boolean; }; -type ErrorWithContext = { +/** + * ErrorWithContext contains error and ErrorContext + * @public + */ +export type ErrorWithContext = { error: Error; context?: ErrorContext; }; @@ -39,11 +48,16 @@ const nullObservable = { }, }; +/** + * Mock implementation of the {@link core-plugin-api#ErrorApi} to be used in tests. + * Incudes withForError and getErrors methods for error testing. + * @public + */ export class MockErrorApi implements ErrorApi { private readonly errors = new Array(); private readonly waiters = new Set(); - constructor(private readonly options: Options = {}) {} + constructor(private readonly options: MockErrorApiOptions = {}) {} post(error: Error, context?: ErrorContext) { if (this.options.collect) { diff --git a/packages/test-utils/src/testUtils/apis/ErrorApi/index.ts b/packages/test-utils/src/testUtils/apis/ErrorApi/index.ts index 8a6b5031e5..1273a91531 100644 --- a/packages/test-utils/src/testUtils/apis/ErrorApi/index.ts +++ b/packages/test-utils/src/testUtils/apis/ErrorApi/index.ts @@ -15,3 +15,4 @@ */ export { MockErrorApi } from './MockErrorApi'; +export type { MockErrorApiOptions, ErrorWithContext } from './MockErrorApi'; diff --git a/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.ts b/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.ts index d928c35435..6378a77474 100644 --- a/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.ts +++ b/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.ts @@ -18,8 +18,16 @@ import { StorageApi, StorageValueChange } from '@backstage/core-plugin-api'; import { Observable } from '@backstage/types'; import ObservableImpl from 'zen-observable'; +/** + * Type for map holding data in {@link MockStorageApi} + * @public + */ export type MockStorageBucket = { [key: string]: any }; +/** + * Mock implementation of the {@link core-plugin-api#StorageApi} to be used in tests + * @public + */ export class MockStorageApi implements StorageApi { private readonly namespace: string; private readonly data: MockStorageBucket; diff --git a/packages/test-utils/src/testUtils/appWrappers.test.tsx b/packages/test-utils/src/testUtils/appWrappers.test.tsx index a5a60130f2..25809912ec 100644 --- a/packages/test-utils/src/testUtils/appWrappers.test.tsx +++ b/packages/test-utils/src/testUtils/appWrappers.test.tsx @@ -23,7 +23,7 @@ import { useApi, useRouteRef, } from '@backstage/core-plugin-api'; -import { withLogCollector } from '@backstage/test-utils-core'; +import { withLogCollector } from './logCollector'; import { render } from '@testing-library/react'; import React, { useEffect } from 'react'; import { Route, Routes } from 'react-router'; diff --git a/packages/test-utils/src/testUtils/appWrappers.tsx b/packages/test-utils/src/testUtils/appWrappers.tsx index 09c9e5d0bf..6f55cc6190 100644 --- a/packages/test-utils/src/testUtils/appWrappers.tsx +++ b/packages/test-utils/src/testUtils/appWrappers.tsx @@ -27,7 +27,7 @@ import { createRouteRef, } from '@backstage/core-plugin-api'; import { RenderResult } from '@testing-library/react'; -import { renderWithEffects } from '@backstage/test-utils-core'; +import { renderWithEffects } from './testingLibrary'; import { mockApis } from './mockApis'; const ErrorBoundaryFallback = ({ error }: { error: Error }) => { @@ -43,8 +43,9 @@ const Progress = () =>
; /** * Options to customize the behavior of the test app wrapper. + * @public */ -type TestAppOptions = { +export type TestAppOptions = { /** * Initial route entries to pass along as `initialEntries` to the router. */ @@ -56,11 +57,11 @@ type TestAppOptions = { * used by `useRouteRef` in the rendered elements. * * @example - * wrapInTestApp(, { - * mountedRoutes: { + * wrapInTestApp(, \{ + * mountedRoutes: \{ * '/my-path': myRouteRef, - * } - * }) + * \} + * \}) * // ... * const link = useRouteRef(myRouteRef) */ @@ -80,6 +81,7 @@ function isExternalRouteRef( * * @param Component - A component or react node to render inside the test app. * @param options - Additional options for the rendering. + * @public */ export function wrapInTestApp( Component: ComponentType | ReactNode, @@ -171,6 +173,7 @@ export function wrapInTestApp( * * @param Component - A component or react node to render inside the test app. * @param options - Additional options for the rendering. + * @public */ export async function renderInTestApp( Component: ComponentType | ReactNode, diff --git a/packages/test-utils/src/testUtils/index.tsx b/packages/test-utils/src/testUtils/index.tsx index 859315313d..7d93d606cc 100644 --- a/packages/test-utils/src/testUtils/index.tsx +++ b/packages/test-utils/src/testUtils/index.tsx @@ -17,4 +17,8 @@ export * from './apis'; export { default as mockBreakpoint } from './mockBreakpoint'; export { wrapInTestApp, renderInTestApp } from './appWrappers'; +export type { TestAppOptions } from './appWrappers'; export * from './msw'; +export * from './Keyboard'; +export * from './logCollector'; +export * from './testingLibrary'; diff --git a/packages/test-utils-core/src/testUtils/logCollector.test.ts b/packages/test-utils/src/testUtils/logCollector.test.ts similarity index 100% rename from packages/test-utils-core/src/testUtils/logCollector.test.ts rename to packages/test-utils/src/testUtils/logCollector.test.ts diff --git a/packages/test-utils-core/src/testUtils/logCollector.ts b/packages/test-utils/src/testUtils/logCollector.ts similarity index 76% rename from packages/test-utils-core/src/testUtils/logCollector.ts rename to packages/test-utils/src/testUtils/logCollector.ts index 3180010529..25629f2c13 100644 --- a/packages/test-utils-core/src/testUtils/logCollector.ts +++ b/packages/test-utils/src/testUtils/logCollector.ts @@ -16,36 +16,65 @@ /* eslint-disable no-console */ +/** + * Severity levels of {@link CollectedLogs} + * @public */ export type LogFuncs = 'log' | 'warn' | 'error'; +/** + * AsyncLogCollector type used in {@link (withLogCollector:1)} callback function. + * @public */ export type AsyncLogCollector = () => Promise; +/** + * SyncLogCollector type used in {@link (withLogCollector:2)} callback function. + * @public */ export type SyncLogCollector = () => void; +/** + * Union type used in {@link (withLogCollector:3)} callback function. + * @public */ export type LogCollector = AsyncLogCollector | SyncLogCollector; +/** + * Map of severity level and corresponding log lines. + * @public */ export type CollectedLogs = { [key in T]: string[] }; const allCategories = ['log', 'warn', 'error']; -// Asynchronous log collector with that collects all categories +/** + * Asynchronous log collector with that collects all categories + * @public */ export function withLogCollector( callback: AsyncLogCollector, ): Promise>; -// Synchronous log collector with that collects all categories +/** + * Synchronous log collector with that collects all categories + * @public */ export function withLogCollector( callback: SyncLogCollector, ): CollectedLogs; -// Asynchronous log collector with that only collects selected categories +/** + * Asynchronous log collector with that only collects selected categories + * @public + */ export function withLogCollector( logsToCollect: T[], callback: AsyncLogCollector, ): Promise>; -// Synchronous log collector with that only collects selected categories +/** + * Synchronous log collector with that only collects selected categories + * @public */ export function withLogCollector( logsToCollect: T[], callback: SyncLogCollector, ): CollectedLogs; +/** + * Log collector that collect logs either from a sync or async collector. + * @public + * @deprecated import from test-utils instead + * */ export function withLogCollector( logsToCollect: LogFuncs[] | LogCollector, callback?: LogCollector, diff --git a/packages/test-utils/src/testUtils/mockBreakpoint.ts b/packages/test-utils/src/testUtils/mockBreakpoint.ts index 3335284f88..3bc285a81d 100644 --- a/packages/test-utils/src/testUtils/mockBreakpoint.ts +++ b/packages/test-utils/src/testUtils/mockBreakpoint.ts @@ -24,7 +24,7 @@ * If there are any updates from MUI React on testing `useMediaQuery` this mock should be replaced * https://material-ui.com/components/use-media-query/#testing * - * @param matchMediaOptions + * @public */ export default function mockBreakpoint({ matches = false }) { Object.defineProperty(window, 'matchMedia', { diff --git a/packages/test-utils/src/testUtils/msw/index.ts b/packages/test-utils/src/testUtils/msw/index.ts index 337c2999fc..40bc47e8f0 100644 --- a/packages/test-utils/src/testUtils/msw/index.ts +++ b/packages/test-utils/src/testUtils/msw/index.ts @@ -14,14 +14,31 @@ * limitations under the License. */ +/** + * @deprecated use {@link setupRequestMockHandlers} instead which can be called directly with the worker. + * @public + */ export const msw = { setupDefaultHandlers: (worker: { listen: (t: any) => void; close: () => void; resetHandlers: () => void; }) => { - beforeAll(() => worker.listen({ onUnhandledRequest: 'error' })); - afterAll(() => worker.close()); - afterEach(() => worker.resetHandlers()); + setupRequestMockHandlers(worker); }, }; + +/** + * Sets up handlers for request mocking + * @public + * @param worker - service worker + */ +export function setupRequestMockHandlers(worker: { + listen: (t: any) => void; + close: () => void; + resetHandlers: () => void; +}) { + beforeAll(() => worker.listen({ onUnhandledRequest: 'error' })); + afterAll(() => worker.close()); + afterEach(() => worker.resetHandlers()); +} diff --git a/packages/test-utils-core/src/testUtils/testingLibrary.ts b/packages/test-utils/src/testUtils/testingLibrary.ts similarity index 71% rename from packages/test-utils-core/src/testUtils/testingLibrary.ts rename to packages/test-utils/src/testUtils/testingLibrary.ts index 48e5132825..44ea20a4cc 100644 --- a/packages/test-utils-core/src/testUtils/testingLibrary.ts +++ b/packages/test-utils/src/testUtils/testingLibrary.ts @@ -18,11 +18,18 @@ import { ReactElement } from 'react'; import { act } from 'react-dom/test-utils'; import { render, RenderResult } from '@testing-library/react'; -// Components using useEffect to perform an asynchronous action (such as fetch) must be rendered within an async -// act call to properly get the final state, even with mocked responses. This utility method makes the signature a bit -// cleaner, since act doesn't return the result of the evaluated function. -// https://github.com/testing-library/react-testing-library/issues/281 -// https://github.com/facebook/react/pull/14853 +/** + * @public + * Simplifies rendering of async components in by taking care of the wrapping inside act + * + * @remarks + * + * Components using useEffect to perform an asynchronous action (such as fetch) must be rendered within an async + * act call to properly get the final state, even with mocked responses. This utility method makes the signature a bit + * cleaner, since act doesn't return the result of the evaluated function. + * https://github.com/testing-library/react-testing-library/issues/281 + * https://github.com/facebook/react/pull/14853 + */ export async function renderWithEffects( nodes: ReactElement, ): Promise {