add some eslint rules for testing-library use in tests
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
@@ -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
|
||||
+6
-1
@@ -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',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -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', () => {
|
||||
</Wrapper>,
|
||||
);
|
||||
|
||||
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', () => {
|
||||
</Wrapper>,
|
||||
);
|
||||
|
||||
expect(await queryByText('BACKSTAGE!')).not.toBeInTheDocument();
|
||||
expect(queryByText('BACKSTAGE!')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
describe('without', () => {
|
||||
@@ -80,7 +81,7 @@ describe('FeatureFlagged', () => {
|
||||
</Wrapper>,
|
||||
);
|
||||
|
||||
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', () => {
|
||||
</Wrapper>,
|
||||
);
|
||||
|
||||
expect(await queryByText('BACKSTAGE!')).toBeInTheDocument();
|
||||
expect(queryByText('BACKSTAGE!')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+6
-6
@@ -70,8 +70,8 @@ describe('<FeatureCalloutCircular />', () => {
|
||||
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('<FeatureCalloutCircular />', () => {
|
||||
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('<FeatureCalloutCircular />', () => {
|
||||
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(
|
||||
|
||||
@@ -41,7 +41,7 @@ describe('<Select />', () => {
|
||||
const { getByText, getByTestId } = render(<Select {...minProps} />);
|
||||
|
||||
expect(getByText('Default')).toBeInTheDocument();
|
||||
const input = await getByTestId('select');
|
||||
const input = getByTestId('select');
|
||||
expect(input.textContent).toBe('All results');
|
||||
|
||||
// Simulate click on input
|
||||
|
||||
@@ -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('<WarningPanel />', () => {
|
||||
|
||||
it('renders title', async () => {
|
||||
await renderInTestApp(<WarningPanel {...propsTitleMessage} />);
|
||||
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();
|
||||
|
||||
+1
-1
@@ -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();
|
||||
|
||||
|
||||
@@ -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('<MaxDepthFilter/>', () => {
|
||||
test('should display current value', () => {
|
||||
const { getByLabelText } = render(
|
||||
<MaxDepthFilter value={5} onChange={() => {}} />,
|
||||
);
|
||||
render(<MaxDepthFilter value={5} onChange={() => {}} />);
|
||||
|
||||
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(
|
||||
<MaxDepthFilter value={Number.POSITIVE_INFINITY} onChange={() => {}} />,
|
||||
);
|
||||
|
||||
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(
|
||||
<MaxDepthFilter value={10} onChange={onChange} />,
|
||||
);
|
||||
render(<MaxDepthFilter value={10} onChange={onChange} />);
|
||||
|
||||
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(
|
||||
<MaxDepthFilter value={1} onChange={onChange} />,
|
||||
);
|
||||
render(<MaxDepthFilter value={1} onChange={onChange} />);
|
||||
|
||||
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(
|
||||
<MaxDepthFilter value={5} onChange={onChange} />,
|
||||
let value = 5;
|
||||
render(
|
||||
<MaxDepthFilter
|
||||
value={value}
|
||||
onChange={v => {
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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<HTMLInputElement>) => {
|
||||
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 (
|
||||
<Box pb={1} pt={1}>
|
||||
@@ -62,7 +81,7 @@ export const MaxDepthFilter = ({ value, onChange }: Props) => {
|
||||
<OutlinedInput
|
||||
type="number"
|
||||
placeholder="∞ Infinite"
|
||||
value={isFinite(value) ? value : ''}
|
||||
value={Number.isFinite(currentValue) ? String(currentValue) : ''}
|
||||
onChange={handleChange}
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
|
||||
@@ -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/);
|
||||
|
||||
@@ -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/);
|
||||
|
||||
+2
-1
@@ -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', () => {
|
||||
</ApiProvider>,
|
||||
);
|
||||
expect(await rendered.findByText(/__location__/)).toBeInTheDocument();
|
||||
expect(await rendered.queryByText(/failed/)).not.toBeInTheDocument();
|
||||
expect(rendered.queryByText(/failed/)).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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(
|
||||
<SelectComponent
|
||||
|
||||
@@ -122,7 +122,7 @@ describe('<AuditListTableForEntity />', () => {
|
||||
|
||||
it('renders nothing', async () => {
|
||||
const { queryByTestId } = subject();
|
||||
expect(await queryByTestId('AuditListTable')).toBeNull();
|
||||
expect(queryByTestId('AuditListTable')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -137,7 +137,7 @@ describe('<AuditListTableForEntity />', () => {
|
||||
|
||||
it('renders nothing', async () => {
|
||||
const { queryByTestId } = subject();
|
||||
expect(await queryByTestId('AuditListTable')).toBeNull();
|
||||
expect(queryByTestId('AuditListTable')).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -151,10 +151,10 @@ describe('<LastLighthouseAuditCard />', () => {
|
||||
|
||||
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('<LastLighthouseAuditCard />', () => {
|
||||
|
||||
it('renders nothing', async () => {
|
||||
const { queryByTestId } = subject();
|
||||
expect(await queryByTestId('AuditListTable')).toBeNull();
|
||||
expect(queryByTestId('AuditListTable')).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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('<GroupListPicker />', () => {
|
||||
</ApiProvider>,
|
||||
);
|
||||
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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<PagerDutyServicesResponse>(url);
|
||||
const { services } = await this.findByUrl<PagerDutyServicesResponse>(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<PagerDutyServiceResponse>(url);
|
||||
response = await this.findByUrl<PagerDutyServiceResponse>(url);
|
||||
} else {
|
||||
throw new NotFoundError();
|
||||
}
|
||||
@@ -100,7 +100,7 @@ export class PagerDutyClient implements PagerDutyApi {
|
||||
'proxy',
|
||||
)}/pagerduty/incidents?${params}`;
|
||||
|
||||
return await this.getByUrl<PagerDutyIncidentsResponse>(url);
|
||||
return await this.findByUrl<PagerDutyIncidentsResponse>(url);
|
||||
}
|
||||
|
||||
async getChangeEventsByServiceId(
|
||||
@@ -111,7 +111,7 @@ export class PagerDutyClient implements PagerDutyApi {
|
||||
'proxy',
|
||||
)}/pagerduty/services/${serviceId}/change_events?${params}`;
|
||||
|
||||
return await this.getByUrl<PagerDutyChangeEventsResponse>(url);
|
||||
return await this.findByUrl<PagerDutyChangeEventsResponse>(url);
|
||||
}
|
||||
|
||||
async getOnCallByPolicyId(
|
||||
@@ -122,7 +122,7 @@ export class PagerDutyClient implements PagerDutyApi {
|
||||
'proxy',
|
||||
)}/pagerduty/oncalls?${params}`;
|
||||
|
||||
return await this.getByUrl<PagerDutyOnCallsResponse>(url);
|
||||
return await this.findByUrl<PagerDutyOnCallsResponse>(url);
|
||||
}
|
||||
|
||||
triggerAlarm(request: PagerDutyTriggerAlarmRequest): Promise<Response> {
|
||||
@@ -158,7 +158,7 @@ export class PagerDutyClient implements PagerDutyApi {
|
||||
return this.request(`${url}/enqueue`, options);
|
||||
}
|
||||
|
||||
private async getByUrl<T>(url: string): Promise<T> {
|
||||
private async findByUrl<T>(url: string): Promise<T> {
|
||||
const options = {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -236,7 +236,7 @@ describe('<ListTasksPage />', () => {
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
const allButton = await getByText('All');
|
||||
const allButton = getByText('All');
|
||||
fireEvent.click(allButton);
|
||||
});
|
||||
|
||||
|
||||
@@ -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('<OwnerListPicker />', () => {
|
||||
|
||||
const { getByText } = await renderInTestApp(<OwnerListPicker {...props} />);
|
||||
|
||||
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('<OwnerListPicker />', () => {
|
||||
|
||||
const { getByText } = await renderInTestApp(<OwnerListPicker {...props} />);
|
||||
|
||||
fireEvent.click(await getByText('All'));
|
||||
fireEvent.click(getByText('All'));
|
||||
expect(props.onSelectOwner).toHaveBeenCalledWith('all');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -34,7 +34,7 @@ describe('RegisterExistingButton', () => {
|
||||
<RegisterExistingButton title="Pick me" />,
|
||||
);
|
||||
|
||||
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', () => {
|
||||
<RegisterExistingButton title="Pick me" to="blah" />,
|
||||
);
|
||||
|
||||
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', () => {
|
||||
<RegisterExistingButton title="Pick me" to="blah" />,
|
||||
);
|
||||
|
||||
expect(await queryByText('Pick me')).toBeInTheDocument();
|
||||
expect(queryByText('Pick me')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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', () => {
|
||||
<ReviewState formState={formState} schemas={schemas} />,
|
||||
);
|
||||
|
||||
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', () => {
|
||||
|
||||
@@ -64,7 +64,7 @@ export class SplunkOnCallClient implements SplunkOnCallApi {
|
||||
'proxy',
|
||||
)}/splunk-on-call/v1/incidents`;
|
||||
|
||||
const { incidents } = await this.getByUrl<IncidentsResponse>(url);
|
||||
const { incidents } = await this.findByUrl<IncidentsResponse>(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<OnCallsResponse>(url);
|
||||
const { teamsOnCall } = await this.findByUrl<OnCallsResponse>(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<Team[]>(url);
|
||||
const teams = await this.findByUrl<Team[]>(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<ListRoutingKeyResponse>(url);
|
||||
const { routingKeys } = await this.findByUrl<ListRoutingKeyResponse>(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<ListUserResponse>(url);
|
||||
const { users } = await this.findByUrl<ListUserResponse>(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<EscalationPolicyResponse>(url);
|
||||
const { policies } = await this.findByUrl<EscalationPolicyResponse>(url);
|
||||
|
||||
return policies;
|
||||
}
|
||||
@@ -146,7 +146,7 @@ export class SplunkOnCallClient implements SplunkOnCallApi {
|
||||
return this.request(url, options);
|
||||
}
|
||||
|
||||
private async getByUrl<T>(url: string): Promise<T> {
|
||||
private async findByUrl<T>(url: string): Promise<T> {
|
||||
const options = {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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: () => {
|
||||
|
||||
@@ -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<Selection | null>(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(() => {
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user