diff --git a/.changeset/angry-dingos-lick.md b/.changeset/angry-dingos-lick.md new file mode 100644 index 0000000000..933f19a839 --- /dev/null +++ b/.changeset/angry-dingos-lick.md @@ -0,0 +1,9 @@ +--- +'@backstage/plugin-catalog-graph': patch +'@backstage/plugin-pagerduty': patch +'@backstage/plugin-scaffolder-backend': patch +'@backstage/plugin-splunk-on-call': patch +'@backstage/plugin-techdocs-react': patch +--- + +Internal refactor to improve tests diff --git a/.eslintrc.js b/.eslintrc.js index 47a47daee6..6d07fab291 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -18,7 +18,7 @@ var path = require('path'); module.exports = { root: true, - plugins: ['notice'], + plugins: ['notice', 'testing-library'], rules: { 'notice/notice': [ 'error', @@ -45,5 +45,10 @@ module.exports = { "CallExpression[arguments.length=0] > MemberExpression[property.name='toUpperCase']", }, ], + 'testing-library/await-async-query': 'error', + 'testing-library/await-async-utils': 'error', + 'testing-library/no-await-sync-query': 'error', + 'testing-library/prefer-wait-for': 'error', + 'testing-library/no-dom-import': 'error', }, }; diff --git a/package.json b/package.json index 9439364045..2f20eeeee3 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "e2e-test": "workspace:*", "eslint": "^8.6.0", "eslint-plugin-notice": "^0.9.10", + "eslint-plugin-testing-library": "^5.9.1", "fs-extra": "10.1.0", "husky": "^8.0.0", "lint-staged": "^13.0.0", diff --git a/packages/app/cypress/integration/app.js b/packages/app/cypress/integration/app.js index 7b874907be..6371bcc4f8 100644 --- a/packages/app/cypress/integration/app.js +++ b/packages/app/cypress/integration/app.js @@ -25,14 +25,17 @@ describe('App', () => { it('should display support info when clicking the button', () => { cy.visit('/'); + // eslint-disable-next-line testing-library/await-async-query cy.findByTestId('support-button').click({ force: true }); cy.contains('#backstage'); }); it('should display error message when triggering it', () => { cy.visit('/'); + // eslint-disable-next-line testing-library/await-async-query cy.findByTestId('error-button').click({ force: true }); cy.contains('Error: Oh no!'); + // eslint-disable-next-line testing-library/await-async-query cy.findByTestId('error-button-close').click({ force: true }); }); @@ -55,6 +58,7 @@ describe('App', () => { cy.contains('Token') .get('input[name=github-auth-tf]') .type('password', { force: true }); + // eslint-disable-next-line testing-library/await-async-query cy.findByTestId('github-auth-button').click({ force: true }); cy.contains(`Welcome, ${name}!`); cy.contains('Logout').click({ force: true }); diff --git a/packages/core-app-api/src/routing/FeatureFlagged.test.tsx b/packages/core-app-api/src/routing/FeatureFlagged.test.tsx index d1b45c39d1..410540f77e 100644 --- a/packages/core-app-api/src/routing/FeatureFlagged.test.tsx +++ b/packages/core-app-api/src/routing/FeatureFlagged.test.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import React from 'react'; import { FeatureFlagged } from './FeatureFlagged'; import { render } from '@testing-library/react'; @@ -44,7 +45,7 @@ describe('FeatureFlagged', () => { , ); - expect(await queryByText('BACKSTAGE!')).toBeInTheDocument(); + expect(queryByText('BACKSTAGE!')).toBeInTheDocument(); }); it('should not render contents when the feature flag is disabled', async () => { jest @@ -61,7 +62,7 @@ describe('FeatureFlagged', () => { , ); - expect(await queryByText('BACKSTAGE!')).not.toBeInTheDocument(); + expect(queryByText('BACKSTAGE!')).not.toBeInTheDocument(); }); }); describe('without', () => { @@ -80,7 +81,7 @@ describe('FeatureFlagged', () => { , ); - expect(await queryByText('BACKSTAGE!')).not.toBeInTheDocument(); + expect(queryByText('BACKSTAGE!')).not.toBeInTheDocument(); }); it('should render contents when the feature flag is disabled', async () => { jest @@ -97,7 +98,7 @@ describe('FeatureFlagged', () => { , ); - expect(await queryByText('BACKSTAGE!')).toBeInTheDocument(); + expect(queryByText('BACKSTAGE!')).toBeInTheDocument(); }); }); }); diff --git a/packages/core-components/src/components/FeatureDiscovery/FeatureCalloutCircular.test.tsx b/packages/core-components/src/components/FeatureDiscovery/FeatureCalloutCircular.test.tsx index 35ea30ffa6..f72e33ac4b 100644 --- a/packages/core-components/src/components/FeatureDiscovery/FeatureCalloutCircular.test.tsx +++ b/packages/core-components/src/components/FeatureDiscovery/FeatureCalloutCircular.test.tsx @@ -70,8 +70,8 @@ describe('', () => { description="description" />, ); - const dot = await getByTestId('dot'); - const text = await getByTestId('text'); + const dot = getByTestId('dot'); + const text = getByTestId('text'); expect(dot).toBeInTheDocument(); expect(text).toBeInTheDocument(); @@ -96,8 +96,8 @@ describe('', () => { description="description" />, ); - const dot = await getByTestId('dot'); - const text = await getByTestId('text'); + const dot = getByTestId('dot'); + const text = getByTestId('text'); act(() => { Element.prototype.getBoundingClientRect = jest.fn( @@ -128,8 +128,8 @@ describe('', () => { description="description" />, ); - const dot = await getByTestId('dot'); - const text = await getByTestId('text'); + const dot = getByTestId('dot'); + const text = getByTestId('text'); act(() => { Element.prototype.getBoundingClientRect = jest.fn( diff --git a/packages/core-components/src/components/Select/Select.test.tsx b/packages/core-components/src/components/Select/Select.test.tsx index 41e787a5b4..df29983222 100644 --- a/packages/core-components/src/components/Select/Select.test.tsx +++ b/packages/core-components/src/components/Select/Select.test.tsx @@ -41,7 +41,7 @@ describe('); expect(getByText('Default')).toBeInTheDocument(); - const input = await getByTestId('select'); + const input = getByTestId('select'); expect(input.textContent).toBe('All results'); // Simulate click on input diff --git a/packages/core-components/src/components/WarningPanel/WarningPanel.test.tsx b/packages/core-components/src/components/WarningPanel/WarningPanel.test.tsx index 25cf642c28..5d00784fd1 100644 --- a/packages/core-components/src/components/WarningPanel/WarningPanel.test.tsx +++ b/packages/core-components/src/components/WarningPanel/WarningPanel.test.tsx @@ -18,7 +18,6 @@ import React from 'react'; import { fireEvent, screen } from '@testing-library/react'; import { renderInTestApp } from '@backstage/test-utils'; import Typography from '@material-ui/core/Typography'; - import { WarningPanel, WarningProps } from './WarningPanel'; const propsTitle: WarningProps = { title: 'Mock title' }; @@ -41,7 +40,7 @@ describe('', () => { it('renders title', async () => { await renderInTestApp(); - const expandIcon = await screen.getByText('Warning: Mock title'); + const expandIcon = screen.getByText('Warning: Mock title'); fireEvent.click(expandIcon); expect(screen.getByText('Warning: Mock title')).toBeInTheDocument(); expect(screen.getByText('Some more info')).toBeInTheDocument(); diff --git a/plugins/bitrise/src/components/BitriseBuildDetailsDialog/BitriseBuildDetailsDialog.test.tsx b/plugins/bitrise/src/components/BitriseBuildDetailsDialog/BitriseBuildDetailsDialog.test.tsx index 2dcffc3bb3..7992e08f37 100644 --- a/plugins/bitrise/src/components/BitriseBuildDetailsDialog/BitriseBuildDetailsDialog.test.tsx +++ b/plugins/bitrise/src/components/BitriseBuildDetailsDialog/BitriseBuildDetailsDialog.test.tsx @@ -46,7 +46,7 @@ describe('BitriseArtifactsComponent', () => { const rendered = renderComponent(); const btn = await rendered.findByTestId('btn'); - expect(await rendered.queryByText('VISIBLE')).not.toBeInTheDocument(); + expect(rendered.queryByText('VISIBLE')).not.toBeInTheDocument(); btn.click(); diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.test.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.test.tsx index 3f3a7f82a6..89f3169981 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.test.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.test.tsx @@ -13,64 +13,65 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { render, waitFor } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; + +import { render, screen } from '@testing-library/react'; +import user from '@testing-library/user-event'; import React from 'react'; import { MaxDepthFilter } from './MaxDepthFilter'; describe('', () => { test('should display current value', () => { - const { getByLabelText } = render( - {}} />, - ); + render( {}} />); - expect(getByLabelText('maxp')).toBeInTheDocument(); - expect(getByLabelText('maxp')).toHaveValue(5); + expect(screen.getByLabelText('maxp')).toBeInTheDocument(); + expect(screen.getByLabelText('maxp')).toHaveValue(5); }); test('should display infinite if non finite', () => { - const { getByPlaceholderText, getByLabelText } = render( + render( {}} />, ); - expect(getByPlaceholderText(/Infinite/)).toBeInTheDocument(); - expect(getByLabelText('maxp')).toHaveValue(null); + expect(screen.getByPlaceholderText(/Infinite/)).toBeInTheDocument(); + expect(screen.getByLabelText('maxp')).toHaveValue(null); }); test('should clear max depth', async () => { const onChange = jest.fn(); - const { getByLabelText } = render( - , - ); + render(); - await userEvent.click(getByLabelText('clear max depth')); + expect(onChange).not.toHaveBeenCalled(); + await user.click(screen.getByLabelText('clear max depth')); expect(onChange).toHaveBeenCalledWith(Number.POSITIVE_INFINITY); }); test('should set max depth to undefined if below one', async () => { const onChange = jest.fn(); - const { getByLabelText } = render( - , - ); + render(); - await userEvent.clear(getByLabelText('maxp')); - await userEvent.type(getByLabelText('maxp'), '0'); + await user.clear(screen.getByLabelText('maxp')); + await user.type(screen.getByLabelText('maxp'), '0'); expect(onChange).toHaveBeenCalledWith(Number.POSITIVE_INFINITY); }); test('should select direction', async () => { - const onChange = jest.fn(); - const { getByLabelText } = render( - , + let value = 5; + render( + { + value = v; + }} + />, ); - expect(getByLabelText('maxp')).toHaveValue(5); + expect(screen.getByLabelText('maxp')).toHaveValue(5); + expect(value).toBe(5); - await userEvent.clear(getByLabelText('maxp')); - await userEvent.type(getByLabelText('maxp'), '10'); - waitFor(() => { - expect(onChange).toHaveBeenCalledWith(10); - }); + await user.clear(screen.getByLabelText('maxp')); + expect(value).toBe(Number.POSITIVE_INFINITY); + await user.type(screen.getByLabelText('maxp'), '10'); + expect(value).toBe(10); }); }); diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.tsx index b6b03d8831..e6fb2fbab4 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.tsx +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/MaxDepthFilter.tsx @@ -23,7 +23,7 @@ import { Typography, } from '@material-ui/core'; import ClearIcon from '@material-ui/icons/Clear'; -import React, { useCallback } from 'react'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; export type Props = { value: number; @@ -42,18 +42,37 @@ const useStyles = makeStyles( export const MaxDepthFilter = ({ value, onChange }: Props) => { const classes = useStyles(); + const onChangeRef = useRef(onChange); + const [currentValue, setCurrentValue] = useState(value); + // Keep a fresh reference to the latest callback + useEffect(() => { + onChangeRef.current = onChange; + }, [onChange]); + + // If the value changes externally, update ourselves + useEffect(() => { + setCurrentValue(value); + }, [value]); + + // When the entered text changes, update ourselves and communicate externally const handleChange = useCallback( (event: React.ChangeEvent) => { - const v = Number(event.target.value); - onChange(v <= 0 ? Number.POSITIVE_INFINITY : v); + const newValueNumeric = Number(event.target.value); + const newValue = + Number.isFinite(newValueNumeric) && newValueNumeric > 0 + ? newValueNumeric + : Number.POSITIVE_INFINITY; + setCurrentValue(newValue); + onChangeRef.current(newValue); }, - [onChange], + [], ); const reset = useCallback(() => { - onChange(Number.POSITIVE_INFINITY); - }, [onChange]); + setCurrentValue(Number.POSITIVE_INFINITY); + onChangeRef.current(Number.POSITIVE_INFINITY); + }, [onChangeRef]); return ( @@ -62,7 +81,7 @@ export const MaxDepthFilter = ({ value, onChange }: Props) => { diff --git a/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.test.tsx b/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.test.tsx index 04cfa1b947..f9d7ca216f 100644 --- a/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.test.tsx +++ b/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.test.tsx @@ -75,7 +75,7 @@ describe('ComponentContextMenu', () => { expect(button).toBeInTheDocument(); fireEvent.click(button); - const unregister = await screen.getByText('Unregister entity'); + const unregister = screen.getByText('Unregister entity'); expect(unregister).toBeInTheDocument(); const unregisterSpanItem = getByText(/Unregister entity/); diff --git a/plugins/catalog/src/components/EntityContextMenu/UnregisterEntity.test.tsx b/plugins/catalog/src/components/EntityContextMenu/UnregisterEntity.test.tsx index 95cb601ea0..f1cd8c2546 100644 --- a/plugins/catalog/src/components/EntityContextMenu/UnregisterEntity.test.tsx +++ b/plugins/catalog/src/components/EntityContextMenu/UnregisterEntity.test.tsx @@ -69,7 +69,7 @@ describe('ComponentContextMenu', () => { />, ); - const unregister = await screen.getByText('Unregister entity'); + const unregister = screen.getByText('Unregister entity'); expect(unregister).toBeInTheDocument(); const unregisterSpanItem = getByText(/Unregister entity/); diff --git a/plugins/dynatrace/src/components/Synthetics/SyntheticsLocation/SyntheticsLocation.test.tsx b/plugins/dynatrace/src/components/Synthetics/SyntheticsLocation/SyntheticsLocation.test.tsx index de04f73e36..6d772efc9b 100644 --- a/plugins/dynatrace/src/components/Synthetics/SyntheticsLocation/SyntheticsLocation.test.tsx +++ b/plugins/dynatrace/src/components/Synthetics/SyntheticsLocation/SyntheticsLocation.test.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import React from 'react'; import { SyntheticsLocation } from './SyntheticsLocation'; import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; @@ -60,6 +61,6 @@ describe('SyntheticsLocation', () => { , ); expect(await rendered.findByText(/__location__/)).toBeInTheDocument(); - expect(await rendered.queryByText(/failed/)).not.toBeInTheDocument(); + expect(rendered.queryByText(/failed/)).not.toBeInTheDocument(); }); }); diff --git a/plugins/gocd/src/components/Select/Select.test.tsx b/plugins/gocd/src/components/Select/Select.test.tsx index fb467b946f..9d73194ed8 100644 --- a/plugins/gocd/src/components/Select/Select.test.tsx +++ b/plugins/gocd/src/components/Select/Select.test.tsx @@ -40,7 +40,7 @@ describe('Select', () => { expect(rendered.getAllByText(testLabel)).toHaveLength(2); }); - describe('when the user hasn`t clicked on it', () => { + describe("when the user hasn't clicked on it", () => { it('should only render the current select item', async () => { const rendered = await renderInTestApp( ', () => { it('renders nothing', async () => { const { queryByTestId } = subject(); - expect(await queryByTestId('AuditListTable')).toBeNull(); + expect(queryByTestId('AuditListTable')).toBeNull(); }); }); @@ -137,7 +137,7 @@ describe('', () => { it('renders nothing', async () => { const { queryByTestId } = subject(); - expect(await queryByTestId('AuditListTable')).toBeNull(); + expect(queryByTestId('AuditListTable')).toBeNull(); }); }); }); diff --git a/plugins/lighthouse/src/components/Cards/LastLighthouseAuditCard.test.tsx b/plugins/lighthouse/src/components/Cards/LastLighthouseAuditCard.test.tsx index 58a3033a1f..ab1e2683b6 100644 --- a/plugins/lighthouse/src/components/Cards/LastLighthouseAuditCard.test.tsx +++ b/plugins/lighthouse/src/components/Cards/LastLighthouseAuditCard.test.tsx @@ -151,10 +151,10 @@ describe('', () => { it('renders nothing', async () => { const { queryByTestId } = subject(); - expect(await queryByTestId('AuditListTable')).toBeNull(); + expect(queryByTestId('AuditListTable')).toBeNull(); }); }); - // + describe('where there is no data', () => { beforeEach(() => { (useWebsiteForEntity as jest.Mock).mockReturnValue({ @@ -166,7 +166,7 @@ describe('', () => { it('renders nothing', async () => { const { queryByTestId } = subject(); - expect(await queryByTestId('AuditListTable')).toBeNull(); + expect(queryByTestId('AuditListTable')).toBeNull(); }); }); }); diff --git a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx index b8a499b8fe..21b85ffe5c 100644 --- a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx +++ b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.test.tsx @@ -15,7 +15,8 @@ */ import React from 'react'; -import { fireEvent, render, waitFor } from '@testing-library/react'; +import { render, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { ApiProvider } from '@backstage/core-app-api'; import { catalogApiRef } from '@backstage/plugin-catalog-react'; import { CatalogApi } from '@backstage/catalog-client'; @@ -74,13 +75,13 @@ describe('', () => { , ); - fireEvent.click(getByTestId('group-list-picker-button')); + await userEvent.click(getByTestId('group-list-picker-button')); const input = getByTestId('group-list-picker-input').querySelector('input'); - fireEvent.change(input as HTMLElement, { target: { value: 'GR' } }); + await userEvent.type(input as HTMLElement, 'GR'); await waitFor(async () => { expect(getByText('Group A')).toBeInTheDocument(); - fireEvent.click(getByText('Group A')); + await userEvent.click(getByText('Group A')); expect(getByText('Group A')).toBeInTheDocument(); }); }); diff --git a/plugins/pagerduty/src/api/client.ts b/plugins/pagerduty/src/api/client.ts index 7266d5e9eb..7d99be219d 100644 --- a/plugins/pagerduty/src/api/client.ts +++ b/plugins/pagerduty/src/api/client.ts @@ -73,7 +73,7 @@ export class PagerDutyClient implements PagerDutyApi { url = `${await this.config.discoveryApi.getBaseUrl( 'proxy', )}/pagerduty/services?${commonGetServiceParams}&query=${integrationKey}`; - const { services } = await this.getByUrl(url); + const { services } = await this.findByUrl(url); const service = services[0]; if (!service) throw new NotFoundError(); @@ -84,7 +84,7 @@ export class PagerDutyClient implements PagerDutyApi { 'proxy', )}/pagerduty/services/${serviceId}?${commonGetServiceParams}`; - response = await this.getByUrl(url); + response = await this.findByUrl(url); } else { throw new NotFoundError(); } @@ -100,7 +100,7 @@ export class PagerDutyClient implements PagerDutyApi { 'proxy', )}/pagerduty/incidents?${params}`; - return await this.getByUrl(url); + return await this.findByUrl(url); } async getChangeEventsByServiceId( @@ -111,7 +111,7 @@ export class PagerDutyClient implements PagerDutyApi { 'proxy', )}/pagerduty/services/${serviceId}/change_events?${params}`; - return await this.getByUrl(url); + return await this.findByUrl(url); } async getOnCallByPolicyId( @@ -122,7 +122,7 @@ export class PagerDutyClient implements PagerDutyApi { 'proxy', )}/pagerduty/oncalls?${params}`; - return await this.getByUrl(url); + return await this.findByUrl(url); } triggerAlarm(request: PagerDutyTriggerAlarmRequest): Promise { @@ -158,7 +158,7 @@ export class PagerDutyClient implements PagerDutyApi { return this.request(`${url}/enqueue`, options); } - private async getByUrl(url: string): Promise { + private async findByUrl(url: string): Promise { const options = { method: 'GET', headers: { diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts index 2891ea51cf..fe29378e2e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { Config } from '@backstage/config'; import { assertError, InputError } from '@backstage/errors'; import { @@ -124,6 +125,7 @@ export async function createGithubRepoWithCollaboratorsAndTopics( topics: string[] | undefined, logger: Logger, ) { + // eslint-disable-next-line testing-library/no-await-sync-query const user = await client.rest.users.getByUsername({ username: owner, }); diff --git a/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx b/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx index 837b87437f..57dde13a43 100644 --- a/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx +++ b/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx @@ -236,7 +236,7 @@ describe('', () => { ); await act(async () => { - const allButton = await getByText('All'); + const allButton = getByText('All'); fireEvent.click(allButton); }); diff --git a/plugins/scaffolder/src/components/ListTasksPage/OwnerListPicker.test.tsx b/plugins/scaffolder/src/components/ListTasksPage/OwnerListPicker.test.tsx index 63f943d6dd..7c335a0ef7 100644 --- a/plugins/scaffolder/src/components/ListTasksPage/OwnerListPicker.test.tsx +++ b/plugins/scaffolder/src/components/ListTasksPage/OwnerListPicker.test.tsx @@ -15,7 +15,6 @@ */ import { renderInTestApp } from '@backstage/test-utils'; - import React from 'react'; import { OwnerListPicker } from './OwnerListPicker'; import { fireEvent } from '@testing-library/react'; @@ -29,8 +28,8 @@ describe('', () => { const { getByText } = await renderInTestApp(); - expect(await getByText('Owned')).toBeDefined(); - expect(await getByText('All')).toBeDefined(); + expect(getByText('Owned')).toBeDefined(); + expect(getByText('All')).toBeDefined(); }); it('should call the function on select other item', async () => { @@ -41,7 +40,7 @@ describe('', () => { const { getByText } = await renderInTestApp(); - fireEvent.click(await getByText('All')); + fireEvent.click(getByText('All')); expect(props.onSelectOwner).toHaveBeenCalledWith('all'); }); }); diff --git a/plugins/scaffolder/src/components/TemplatePage/TemplatePage.test.tsx b/plugins/scaffolder/src/components/TemplatePage/TemplatePage.test.tsx index a48644e72d..71f5ffad47 100644 --- a/plugins/scaffolder/src/components/TemplatePage/TemplatePage.test.tsx +++ b/plugins/scaffolder/src/components/TemplatePage/TemplatePage.test.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { MockAnalyticsApi, renderInTestApp, @@ -340,9 +341,9 @@ describe('TemplatePage', () => { }, ); - expect(await queryByText('Name')).not.toBeInTheDocument(); - expect(await queryByText('Description')).toBeInTheDocument(); - expect(await queryByText('Owner')).toBeInTheDocument(); - expect(await queryByText('Send data')).toBeInTheDocument(); + expect(queryByText('Name')).not.toBeInTheDocument(); + expect(queryByText('Description')).toBeInTheDocument(); + expect(queryByText('Owner')).toBeInTheDocument(); + expect(queryByText('Send data')).toBeInTheDocument(); }); }); diff --git a/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.test.tsx b/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.test.tsx index e6022d16fb..a8e377bd3d 100644 --- a/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.test.tsx +++ b/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.test.tsx @@ -34,7 +34,7 @@ describe('RegisterExistingButton', () => { , ); - expect(await queryByText('Pick me')).not.toBeInTheDocument(); + expect(queryByText('Pick me')).not.toBeInTheDocument(); }); it('should not render if permissions are not allowed', async () => { @@ -43,7 +43,7 @@ describe('RegisterExistingButton', () => { , ); - expect(await queryByText('Pick me')).not.toBeInTheDocument(); + expect(queryByText('Pick me')).not.toBeInTheDocument(); }); it('should render the button with the text', async () => { @@ -52,6 +52,6 @@ describe('RegisterExistingButton', () => { , ); - expect(await queryByText('Pick me')).toBeInTheDocument(); + expect(queryByText('Pick me')).toBeInTheDocument(); }); }); diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/ReviewState.test.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/ReviewState.test.tsx index 2b2e706102..c03df8f73c 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/ReviewState.test.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/Stepper/ReviewState.test.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import React from 'react'; import { ReviewState } from './ReviewState'; import { render } from '@testing-library/react'; @@ -97,9 +98,7 @@ describe('ReviewState', () => { , ); - expect( - await queryByRole('row', { name: 'Name ******' }), - ).not.toBeInTheDocument(); + expect(queryByRole('row', { name: 'Name ******' })).not.toBeInTheDocument(); }); it('should allow for masking an option with a set text', () => { diff --git a/plugins/splunk-on-call/src/api/client.ts b/plugins/splunk-on-call/src/api/client.ts index aa655a4772..2c5e122ac8 100644 --- a/plugins/splunk-on-call/src/api/client.ts +++ b/plugins/splunk-on-call/src/api/client.ts @@ -64,7 +64,7 @@ export class SplunkOnCallClient implements SplunkOnCallApi { 'proxy', )}/splunk-on-call/v1/incidents`; - const { incidents } = await this.getByUrl(url); + const { incidents } = await this.findByUrl(url); return incidents; } @@ -73,7 +73,7 @@ export class SplunkOnCallClient implements SplunkOnCallApi { const url = `${await this.config.discoveryApi.getBaseUrl( 'proxy', )}/splunk-on-call/v1/oncall/current`; - const { teamsOnCall } = await this.getByUrl(url); + const { teamsOnCall } = await this.findByUrl(url); return teamsOnCall; } @@ -82,7 +82,7 @@ export class SplunkOnCallClient implements SplunkOnCallApi { const url = `${await this.config.discoveryApi.getBaseUrl( 'proxy', )}/splunk-on-call/v1/team`; - const teams = await this.getByUrl(url); + const teams = await this.findByUrl(url); return teams; } @@ -91,7 +91,7 @@ export class SplunkOnCallClient implements SplunkOnCallApi { const url = `${await this.config.discoveryApi.getBaseUrl( 'proxy', )}/splunk-on-call/v1/org/routing-keys`; - const { routingKeys } = await this.getByUrl(url); + const { routingKeys } = await this.findByUrl(url); return routingKeys; } @@ -100,7 +100,7 @@ export class SplunkOnCallClient implements SplunkOnCallApi { const url = `${await this.config.discoveryApi.getBaseUrl( 'proxy', )}/splunk-on-call/v2/user`; - const { users } = await this.getByUrl(url); + const { users } = await this.findByUrl(url); return users; } @@ -109,7 +109,7 @@ export class SplunkOnCallClient implements SplunkOnCallApi { const url = `${await this.config.discoveryApi.getBaseUrl( 'proxy', )}/splunk-on-call/v1/policies`; - const { policies } = await this.getByUrl(url); + const { policies } = await this.findByUrl(url); return policies; } @@ -146,7 +146,7 @@ export class SplunkOnCallClient implements SplunkOnCallApi { return this.request(url, options); } - private async getByUrl(url: string): Promise { + private async findByUrl(url: string): Promise { const options = { method: 'GET', headers: { diff --git a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx index 051d9de030..704d2d9ed9 100644 --- a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx +++ b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { Entity } from '@backstage/catalog-model'; import { ApiProvider, ConfigReader } from '@backstage/core-app-api'; import { @@ -187,7 +188,7 @@ describe('SplunkOnCallCard', () => { { timeout: 2000 }, ); - const createIncidentButton = await getByText('Create Incident'); + const createIncidentButton = getByText('Create Incident'); await act(async () => { fireEvent.click(createIncidentButton); }); diff --git a/plugins/techdocs-react/api-report.md b/plugins/techdocs-react/api-report.md index d04b852d07..09da4e012c 100644 --- a/plugins/techdocs-react/api-report.md +++ b/plugins/techdocs-react/api-report.md @@ -173,7 +173,7 @@ export const useShadowRootElements: < ) => TReturnedElement[]; // @public -export const useShadowRootSelection: (wait?: number) => Selection | null; +export const useShadowRootSelection: (waitMillis?: number) => Selection | null; // @public export const useTechDocsAddons: () => { diff --git a/plugins/techdocs-react/src/hooks.ts b/plugins/techdocs-react/src/hooks.ts index 560c548156..e8cc7bddc8 100644 --- a/plugins/techdocs-react/src/hooks.ts +++ b/plugins/techdocs-react/src/hooks.ts @@ -57,10 +57,10 @@ const isValidSelection = (newSelection: Selection) => { }; /** - * Hook for retreiving a selection within the ShadowRoot. + * Hook for retrieving a selection within the ShadowRoot. * @public */ -export const useShadowRootSelection = (wait: number = 0) => { +export const useShadowRootSelection = (waitMillis: number = 0) => { const shadowRoot = useShadowRoot(); const [selection, setSelection] = useState(null); const handleSelectionChange = useMemo( @@ -78,8 +78,8 @@ export const useShadowRootSelection = (wait: number = 0) => { } else { setSelection(null); } - }, wait), - [shadowRoot, setSelection, wait], + }, waitMillis), + [shadowRoot, setSelection, waitMillis], ); useEffect(() => { diff --git a/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx b/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx index effd8fe0c5..2837ab340a 100644 --- a/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx +++ b/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.test.tsx @@ -103,10 +103,10 @@ describe('Entity List Docs Grid', () => { }, ); - expect(await screen.queryByText('All Documentation')).toBeInTheDocument(); - expect(await screen.queryByText('Documentation #1')).toBeInTheDocument(); - expect(await screen.queryByText('Documentation #2')).toBeInTheDocument(); - expect(await screen.queryByTestId('doc-not-found')).not.toBeInTheDocument(); + expect(screen.queryByText('All Documentation')).toBeInTheDocument(); + expect(screen.queryByText('Documentation #1')).toBeInTheDocument(); + expect(screen.queryByText('Documentation #2')).toBeInTheDocument(); + expect(screen.queryByTestId('doc-not-found')).not.toBeInTheDocument(); }); it('should render only filtered entities with filtering', async () => { @@ -131,14 +131,10 @@ describe('Entity List Docs Grid', () => { }, ); - expect( - await screen.queryByText('Curated Documentation'), - ).toBeInTheDocument(); - expect(await screen.queryByText('Documentation #1')).toBeInTheDocument(); - expect( - await screen.queryByText('Documentation #2'), - ).not.toBeInTheDocument(); - expect(await screen.queryByTestId('doc-not-found')).not.toBeInTheDocument(); + expect(screen.queryByText('Curated Documentation')).toBeInTheDocument(); + expect(screen.queryByText('Documentation #1')).toBeInTheDocument(); + expect(screen.queryByText('Documentation #2')).not.toBeInTheDocument(); + expect(screen.queryByTestId('doc-not-found')).not.toBeInTheDocument(); }); it('should render nothing with filtering yielding no result', async () => { @@ -163,16 +159,10 @@ describe('Entity List Docs Grid', () => { }, ); - expect( - await screen.queryByText('Curated Documentation'), - ).not.toBeInTheDocument(); - expect( - await screen.queryByText('Documentation #1'), - ).not.toBeInTheDocument(); - expect( - await screen.queryByText('Documentation #2'), - ).not.toBeInTheDocument(); - expect(await screen.queryByTestId('doc-not-found')).not.toBeInTheDocument(); + expect(screen.queryByText('Curated Documentation')).not.toBeInTheDocument(); + expect(screen.queryByText('Documentation #1')).not.toBeInTheDocument(); + expect(screen.queryByText('Documentation #2')).not.toBeInTheDocument(); + expect(screen.queryByTestId('doc-not-found')).not.toBeInTheDocument(); }); it('should render an error without any documentation and without filtering', async () => { @@ -189,15 +179,9 @@ describe('Entity List Docs Grid', () => { }, ); - expect( - await screen.queryByText('All Documentation'), - ).not.toBeInTheDocument(); - expect( - await screen.queryByText('Documentation #1'), - ).not.toBeInTheDocument(); - expect( - await screen.queryByText('Documentation #2'), - ).not.toBeInTheDocument(); - expect(await screen.queryByTestId('doc-not-found')).toBeInTheDocument(); + expect(screen.queryByText('All Documentation')).not.toBeInTheDocument(); + expect(screen.queryByText('Documentation #1')).not.toBeInTheDocument(); + expect(screen.queryByText('Documentation #2')).not.toBeInTheDocument(); + expect(screen.queryByTestId('doc-not-found')).toBeInTheDocument(); }); }); diff --git a/yarn.lock b/yarn.lock index b1531e5db9..1a5617c798 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13990,10 +13990,10 @@ __metadata: languageName: node linkType: hard -"@types/semver@npm:^7.3.8": - version: 7.3.12 - resolution: "@types/semver@npm:7.3.12" - checksum: 35536b2fc5602904f21cae681f6c9498e177dab3f54ae37c92f9a1b7e43c35f18bcd81e1c98c1cf0d33ee046bb06c771e9928c1c00a401d56a03f56549252a15 +"@types/semver@npm:^7.3.12, @types/semver@npm:^7.3.8": + version: 7.3.13 + resolution: "@types/semver@npm:7.3.13" + checksum: 00c0724d54757c2f4bc60b5032fe91cda6410e48689633d5f35ece8a0a66445e3e57fa1d6e07eb780f792e82ac542948ec4d0b76eb3484297b79bd18b8cf1cb0 languageName: node linkType: hard @@ -14446,6 +14446,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:5.43.0": + version: 5.43.0 + resolution: "@typescript-eslint/scope-manager@npm:5.43.0" + dependencies: + "@typescript-eslint/types": 5.43.0 + "@typescript-eslint/visitor-keys": 5.43.0 + checksum: e594c7a32c3fa29e46dd0b0bc62f97f154bd864682ae7da87a14b6f4336f4cb02f6ed0602bbdb15783e4230ecdf8a0ccc6f7c5820850e8f11240c9e4fb0e388d + languageName: node + linkType: hard + "@typescript-eslint/scope-manager@npm:5.9.0": version: 5.9.0 resolution: "@typescript-eslint/scope-manager@npm:5.9.0" @@ -14480,6 +14490,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:5.43.0": + version: 5.43.0 + resolution: "@typescript-eslint/types@npm:5.43.0" + checksum: fc5e5431c305feee4a3faae84f34df482e08d74b910a6f9376b01326c682ceefeeb0e270d03d7778787bc94ef05b3b85ee6d3c9d732290fbdb4a67ae1b110226 + languageName: node + linkType: hard + "@typescript-eslint/types@npm:5.9.0": version: 5.9.0 resolution: "@typescript-eslint/types@npm:5.9.0" @@ -14505,6 +14522,24 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:5.43.0": + version: 5.43.0 + resolution: "@typescript-eslint/typescript-estree@npm:5.43.0" + dependencies: + "@typescript-eslint/types": 5.43.0 + "@typescript-eslint/visitor-keys": 5.43.0 + debug: ^4.3.4 + globby: ^11.1.0 + is-glob: ^4.0.3 + semver: ^7.3.7 + tsutils: ^3.21.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 3479f9413d73369ab3d574580c90a72f74d2ae1ec4afe485eebfad054c3d15c89f23a137bb9d6197dfdae33e444a76a99f6832688787feabbb064e09d39a3f55 + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:5.9.0": version: 5.9.0 resolution: "@typescript-eslint/typescript-estree@npm:5.9.0" @@ -14523,7 +14558,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.36.2, @typescript-eslint/utils@npm:^5.10.0": +"@typescript-eslint/utils@npm:5.36.2": version: 5.36.2 resolution: "@typescript-eslint/utils@npm:5.36.2" dependencies: @@ -14539,6 +14574,24 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/utils@npm:^5.10.0, @typescript-eslint/utils@npm:^5.13.0": + version: 5.43.0 + resolution: "@typescript-eslint/utils@npm:5.43.0" + dependencies: + "@types/json-schema": ^7.0.9 + "@types/semver": ^7.3.12 + "@typescript-eslint/scope-manager": 5.43.0 + "@typescript-eslint/types": 5.43.0 + "@typescript-eslint/typescript-estree": 5.43.0 + eslint-scope: ^5.1.1 + eslint-utils: ^3.0.0 + semver: ^7.3.7 + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + checksum: 4c6b383b51506b57230f2624f883ae21e5d8411d138587c04fe3145f915bf8c289cc2a9f7b0b3faba98345ba230504e5014922bcc578aa0badd594d9eaa8f9ef + languageName: node + linkType: hard + "@typescript-eslint/visitor-keys@npm:5.36.2": version: 5.36.2 resolution: "@typescript-eslint/visitor-keys@npm:5.36.2" @@ -14549,6 +14602,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:5.43.0": + version: 5.43.0 + resolution: "@typescript-eslint/visitor-keys@npm:5.43.0" + dependencies: + "@typescript-eslint/types": 5.43.0 + eslint-visitor-keys: ^3.3.0 + checksum: 4820679e50096dcdaadc7c95d32e5dca3ba8510acf1a865e283822bae3940a2faec02ad8abe793f8a25f75b600f1e7215e1fd3b3ba73779eff737fa90d092550 + languageName: node + linkType: hard + "@typescript-eslint/visitor-keys@npm:5.9.0": version: 5.9.0 resolution: "@typescript-eslint/visitor-keys@npm:5.9.0" @@ -20502,6 +20565,17 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-testing-library@npm:^5.9.1": + version: 5.9.1 + resolution: "eslint-plugin-testing-library@npm:5.9.1" + dependencies: + "@typescript-eslint/utils": ^5.13.0 + peerDependencies: + eslint: ^7.5.0 || ^8.0.0 + checksum: d09f9486945807e9587d52b6979117bc41b750df741567381a06219671096afb318696a0e0db63e253e150fead40e77ef9653ee00f1dda83fc8920e3b3c47107 + languageName: node + linkType: hard + "eslint-scope@npm:5.1.1, eslint-scope@npm:^5.1.1": version: 5.1.1 resolution: "eslint-scope@npm:5.1.1" @@ -32907,6 +32981,7 @@ __metadata: e2e-test: "workspace:*" eslint: ^8.6.0 eslint-plugin-notice: ^0.9.10 + eslint-plugin-testing-library: ^5.9.1 fs-extra: 10.1.0 husky: ^8.0.0 lint-staged: ^13.0.0