Replace usage of `react-test-renderer` and `@testing-library/react-hooks` (#98152)

* Update dependency @types/react-test-renderer to v19

* replace usage of react-test-renderer

* use renderHook from @testing-library/react in most tests

* update tests to work without @testing-library/react-hooks

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com>
pull/98181/head
renovate[bot] 5 months ago committed by GitHub
parent b710e26a40
commit 89774f3c8d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 3
      package.json
  2. 1
      packages/grafana-prometheus/package.json
  3. 2
      packages/grafana-runtime/src/services/LocationService.test.tsx
  4. 2
      packages/grafana-runtime/src/services/pluginExtensions/usePluginExtensions.test.tsx
  5. 1
      packages/grafana-sql/package.json
  6. 2
      packages/grafana-sql/src/components/configuration/useMigrateDatabaseFields.test.ts
  7. 2
      packages/grafana-ui/package.json
  8. 21
      packages/grafana-ui/src/components/ColorPicker/ColorPicker.test.tsx
  9. 16
      packages/grafana-ui/src/components/CustomScrollbar/CustomScrollbar.test.tsx
  10. 99
      packages/grafana-ui/src/components/CustomScrollbar/__snapshots__/CustomScrollbar.test.tsx.snap
  11. 22
      packages/grafana-ui/src/components/Forms/Legacy/Select/SelectOption.test.tsx
  12. 35
      packages/grafana-ui/src/components/Forms/Legacy/Select/__snapshots__/SelectOption.test.tsx.snap
  13. 26
      packages/grafana-ui/src/components/TableInputCSV/TableInputCSV.test.tsx
  14. 2
      public/app/features/alerting/unified/hooks/usePagination.test.tsx
  15. 2
      public/app/features/alerting/unified/utils/rule-id.test.tsx
  16. 26
      public/app/features/explore/Graph/useStructureRev.test.ts
  17. 3
      public/app/features/explore/Logs/LogsTableWrap.test.tsx
  18. 2
      public/app/features/explore/hooks/useSplitSizeUpdater.test.tsx
  19. 282
      public/app/features/explore/hooks/useStateSync/index.test.tsx
  20. 3
      public/app/features/plugins/extensions/usePluginComponent.test.tsx
  21. 3
      public/app/features/plugins/extensions/usePluginComponents.test.tsx
  22. 3
      public/app/features/plugins/extensions/usePluginExtensions.test.tsx
  23. 3
      public/app/features/plugins/extensions/usePluginLinks.test.tsx
  24. 16
      public/app/plugins/datasource/cloud-monitoring/components/VariableQueryEditor.test.tsx
  25. 152
      public/app/plugins/datasource/cloud-monitoring/components/__snapshots__/VariableQueryEditor.test.tsx.snap
  26. 2
      public/app/plugins/datasource/cloud-monitoring/package.json
  27. 11
      public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.test.tsx
  28. 10
      public/app/plugins/datasource/elasticsearch/hooks/useStatelessReducer.test.tsx
  29. 22
      public/app/plugins/panel/logs/useDatasourcesFromTargets.test.ts
  30. 3
      public/app/plugins/panel/nodeGraph/layout.test.ts
  31. 78
      yarn.lock

@ -138,7 +138,6 @@
"@types/react-router": "5.1.20",
"@types/react-router-dom": "5.3.3",
"@types/react-table": "7.7.20",
"@types/react-test-renderer": "18.3.0",
"@types/react-transition-group": "4.4.12",
"@types/react-virtualized-auto-sizer": "1.0.4",
"@types/react-window": "1.8.8",
@ -224,7 +223,6 @@
"pseudoizer": "^0.1.0",
"react-refresh": "0.14.0",
"react-select-event": "5.5.1",
"react-test-renderer": "18.2.0",
"redux-mock-store": "1.5.5",
"rimraf": "6.0.1",
"rudder-sdk-js": "2.48.42",
@ -301,7 +299,6 @@
"@react-aria/utils": "3.26.0",
"@react-awesome-query-builder/ui": "6.6.4",
"@reduxjs/toolkit": "2.5.0",
"@testing-library/react-hooks": "^8.0.1",
"@visx/event": "3.12.0",
"@visx/gradient": "3.12.0",
"@visx/group": "3.12.0",

@ -125,7 +125,6 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-select-event": "5.5.1",
"react-test-renderer": "18.2.0",
"rollup": "^4.22.4",
"rollup-plugin-dts": "^6.1.1",
"rollup-plugin-esbuild": "6.1.1",

@ -1,4 +1,4 @@
import { renderHook } from '@testing-library/react-hooks';
import { renderHook } from '@testing-library/react';
import { locationService, HistoryWrapper, useLocationService, LocationServiceProvider } from './LocationService';

@ -1,4 +1,4 @@
import { renderHook } from '@testing-library/react-hooks';
import { renderHook } from '@testing-library/react';
import { PluginExtension, PluginExtensionTypes } from '@grafana/data';

@ -38,7 +38,6 @@
"@testing-library/dom": "10.4.0",
"@testing-library/jest-dom": "^6.1.2",
"@testing-library/react": "16.1.0",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "14.5.2",
"@types/jest": "^29.5.4",
"@types/lodash": "4.17.13",

@ -1,4 +1,4 @@
import { renderHook } from '@testing-library/react-hooks';
import { renderHook } from '@testing-library/react';
import { DataSourceSettings } from '@grafana/data';

@ -150,7 +150,6 @@
"@types/react-color": "3.0.13",
"@types/react-dom": "18.2.25",
"@types/react-highlight-words": "0.20.0",
"@types/react-test-renderer": "18.3.0",
"@types/react-transition-group": "4.4.12",
"@types/react-window": "1.8.8",
"@types/slate": "0.47.11",
@ -171,7 +170,6 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-select-event": "^5.1.0",
"react-test-renderer": "18.2.0",
"rimraf": "6.0.1",
"rollup": "^4.22.4",
"rollup-plugin-copy": "3.5.0",

@ -1,15 +1,12 @@
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import renderer from 'react-test-renderer';
import { ColorPicker } from './ColorPicker';
import { ColorSwatch } from './ColorSwatch';
describe('ColorPicker', () => {
it('renders ColorPickerTrigger component by default', () => {
expect(
renderer.create(<ColorPicker color="#EAB839" onChange={() => {}} />).root.findByType(ColorSwatch)
).toBeTruthy();
render(<ColorPicker color="#EAB839" onChange={() => {}} />);
expect(screen.getByRole('button', { name: '#EAB839 color' })).toBeInTheDocument();
});
it('should not have buttons with default submit type', async () => {
@ -24,13 +21,11 @@ describe('ColorPicker', () => {
});
it('renders custom trigger when supplied', () => {
const div = renderer
.create(
<ColorPicker color="#EAB839" onChange={() => {}}>
{() => <div>Custom trigger</div>}
</ColorPicker>
)
.root.findByType('div');
expect(div.children[0]).toBe('Custom trigger');
render(
<ColorPicker color="#EAB839" onChange={() => {}}>
{() => <div>Custom trigger</div>}
</ColorPicker>
);
expect(screen.getByText('Custom trigger')).toBeInTheDocument();
});
});

@ -1,16 +1,14 @@
import renderer from 'react-test-renderer';
import { render } from '@testing-library/react';
import { CustomScrollbar } from './CustomScrollbar';
describe('CustomScrollbar', () => {
it('renders correctly', () => {
const tree = renderer
.create(
<CustomScrollbar>
<p>Scrollable content</p>
</CustomScrollbar>
)
.toJSON();
expect(tree).toMatchSnapshot();
const { container } = render(
<CustomScrollbar>
<p>Scrollable content</p>
</CustomScrollbar>
);
expect(container).toMatchSnapshot();
});
});

@ -1,82 +1,37 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`CustomScrollbar renders correctly 1`] = `
<div
className="css-rzpihd"
style={
{
"height": "auto",
"maxHeight": "100%",
"minHeight": "0",
"overflow": "hidden",
"position": "relative",
"width": "100%",
}
}
>
<div>
<div
className="scrollbar-view"
style={
{
"WebkitOverflowScrolling": "auto",
"bottom": undefined,
"left": undefined,
"marginBottom": 0,
"marginRight": 0,
"maxHeight": "calc(100% + 0px)",
"minHeight": "calc(0 + 0px)",
"overflow": "scroll",
"position": "relative",
"right": undefined,
"top": undefined,
}
}
>
<p>
Scrollable content
</p>
</div>
<div
className="track-horizontal"
style={
{
"display": "none",
"height": 6,
"position": "absolute",
}
}
class="css-rzpihd"
style="position: relative; overflow: hidden; width: 100%; height: auto; min-height: 0; max-height: 100%;"
>
<div
className="thumb-horizontal"
style={
{
"display": "block",
"height": "100%",
"position": "relative",
}
}
/>
</div>
<div
className="track-vertical"
style={
{
"display": "none",
"position": "absolute",
"width": 6,
}
}
>
class="scrollbar-view"
style="position: relative; overflow: scroll; margin-right: 0px; margin-bottom: 0px; min-height: calc(0 + 0px); max-height: calc(100% + 0px);"
>
<p>
Scrollable content
</p>
</div>
<div
class="track-horizontal"
style="position: absolute; height: 6px; display: none;"
>
<div
class="thumb-horizontal"
style="position: relative; display: block; height: 100%;"
/>
</div>
<div
className="thumb-vertical"
style={
{
"display": "block",
"position": "relative",
"width": "100%",
}
}
/>
class="track-vertical"
style="position: absolute; width: 6px; display: none;"
>
<div
class="thumb-vertical"
style="position: relative; display: block; width: 100%;"
/>
</div>
</div>
</div>
`;

@ -1,5 +1,5 @@
import { render } from '@testing-library/react';
import { OptionProps } from 'react-select';
import renderer from 'react-test-renderer';
import SelectOption from './SelectOption';
@ -37,16 +37,14 @@ const model: OptionProps = {
describe('SelectOption', () => {
it('renders correctly', () => {
const tree = renderer
.create(
<SelectOption
{...model}
data={{
imgUrl: 'url/to/avatar',
}}
/>
)
.toJSON();
expect(tree).toMatchSnapshot();
const { container } = render(
<SelectOption
{...model}
data={{
imgUrl: 'url/to/avatar',
}}
/>
);
expect(container).toMatchSnapshot();
});
});

@ -1,28 +1,27 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SelectOption renders correctly 1`] = `
<div
aria-disabled={false}
className="css-0"
id=""
onClick={[MockFunction]}
onMouseMove={[MockFunction]}
onMouseOver={[MockFunction]}
tabIndex={1}
>
<div>
<div
className="gf-form-select-box__desc-option"
aria-disabled="false"
class="css-0"
id=""
tabindex="1"
>
<img
alt=""
className="gf-form-select-box__desc-option__img"
src="url/to/avatar"
/>
<div
className="gf-form-select-box__desc-option__body"
class="gf-form-select-box__desc-option"
>
<div>
Model title
<img
alt=""
class="gf-form-select-box__desc-option__img"
src="url/to/avatar"
/>
<div
class="gf-form-select-box__desc-option__body"
>
<div>
Model title
</div>
</div>
</div>
</div>

@ -1,4 +1,4 @@
import renderer from 'react-test-renderer';
import { render, screen } from '@testing-library/react';
import { DataFrame } from '@grafana/data';
@ -6,19 +6,15 @@ import { TableInputCSV } from './TableInputCSV';
describe('TableInputCSV', () => {
it('renders correctly', () => {
const tree = renderer
.create(
<TableInputCSV
width={'100%'}
height={200}
text={'a,b,c\n1,2,3'}
onSeriesParsed={(data: DataFrame[], text: string) => {
// console.log('Table:', table, 'from:', text);
}}
/>
)
.toJSON();
//expect(tree).toMatchSnapshot();
expect(tree).toBeDefined();
render(
<TableInputCSV
width={'100%'}
height={200}
text={'a,b,c\n1,2,3'}
onSeriesParsed={(data: DataFrame[], text: string) => {}}
/>
);
expect(screen.getByRole('textbox')).toBeInTheDocument();
expect(screen.getByText('Rows:1, Columns:3')).toBeInTheDocument();
});
});

@ -1,4 +1,4 @@
import { act, renderHook } from '@testing-library/react-hooks';
import { act, renderHook } from '@testing-library/react';
import { usePagination } from './usePagination';

@ -1,4 +1,4 @@
import { renderHook } from '@testing-library/react-hooks';
import { renderHook } from '@testing-library/react';
import { TestProvider } from 'test/helpers/TestProvider';
import { config, locationService } from '@grafana/runtime';

@ -7,7 +7,7 @@ declare global {
}
}
import { renderHook } from '@testing-library/react-hooks';
import { renderHook } from '@testing-library/react';
import { DataFrame, FieldType, toDataFrame } from '@grafana/data';
@ -62,7 +62,7 @@ describe('useStructureRev', () => {
// mirrors the logic in componentDidUpdate in packages/grafana-ui/src/components/GraphNG/GraphNG.tsx,
// which treats all falsy values for structureRev as a signal to reconfig the graph
it('should start from a thruthy value', () => {
it('should start from a truthy value', () => {
let frames: DataFrame[] = [toDataFrame({ fields: [{ name: 'time', type: FieldType.time, values: [1, 2, 3] }] })];
const { result } = renderHook((frames) => useStructureRev(frames), { initialProps: frames });
@ -70,14 +70,22 @@ describe('useStructureRev', () => {
});
it('should increment only when relevant fields in frame change', () => {
let all: number[] = [];
let frames: DataFrame[] = [toDataFrame({ fields: [{ name: 'time', type: FieldType.time, values: [1, 2, 3] }] })];
const { result, rerender } = renderHook((frames) => useStructureRev(frames), { initialProps: frames });
const { result, rerender } = renderHook(
(frames) => {
const result = useStructureRev(frames);
all.push(result);
return result;
},
{ initialProps: frames }
);
startCounters(result.current);
// When changing number of frames, the structureRev should increment
frames = [...frames, toDataFrame({ fields: [{ name: 'time', type: FieldType.time, values: [1, 2, 3] }] })];
rerender(frames);
expect(result.all).toHaveIncremented();
expect(all).toHaveIncremented();
// Changing RefId should not increment the structure revision
frames[0] = toDataFrame({
@ -85,7 +93,7 @@ describe('useStructureRev', () => {
fields: [{ name: 'time', type: FieldType.time, values: [1, 2, 3] }],
});
rerender([...frames]);
expect(result.all).not.toHaveIncremented();
expect(all).not.toHaveIncremented();
// Changing frame name should increment the structure revision
frames[0] = toDataFrame({
@ -94,7 +102,7 @@ describe('useStructureRev', () => {
fields: [{ name: 'time', type: FieldType.time, values: [1, 2, 3] }],
});
rerender([...frames]);
expect(result.all).toHaveIncremented();
expect(all).toHaveIncremented();
// Changing frame's fields number should increment the structure revision
frames[0] = toDataFrame({
@ -106,7 +114,7 @@ describe('useStructureRev', () => {
],
});
rerender([...frames]);
expect(result.all).toHaveIncremented();
expect(all).toHaveIncremented();
// Changing a frame's field's config should increment the structure revision
frames[0] = toDataFrame({
@ -118,7 +126,7 @@ describe('useStructureRev', () => {
],
});
rerender([...frames]);
expect(result.all).toHaveIncremented();
expect(all).toHaveIncremented();
// Changing a frame's field's name should increment the structure revision
frames[0] = toDataFrame({
@ -130,6 +138,6 @@ describe('useStructureRev', () => {
],
});
rerender([...frames]);
expect(result.all).toHaveIncremented();
expect(all).toHaveIncremented();
});
});

@ -1,6 +1,5 @@
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
import { ComponentProps } from 'react';
import { act } from 'react-test-renderer';
import {
createTheme,

@ -1,4 +1,4 @@
import { renderHook, act } from '@testing-library/react-hooks';
import { renderHook, act } from '@testing-library/react';
import { ReactNode } from 'react';
import { TestProvider } from 'test/helpers/TestProvider';

@ -1,12 +1,11 @@
import { act, waitFor } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import { act, waitFor, renderHook } from '@testing-library/react';
import { createMemoryHistory } from 'history';
import { stringify } from 'querystring';
import { ReactNode } from 'react';
import { TestProvider } from 'test/helpers/TestProvider';
import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock';
import { DataSourceApi, UrlQueryMap } from '@grafana/data';
import { DataQuery, DataSourceApi, UrlQueryMap } from '@grafana/data';
import { HistoryWrapper, setDataSourceSrv, DataSourceSrv } from '@grafana/runtime';
import { setLastUsedDatasourceUID } from 'app/core/utils/explore';
import { MIXED_DATASOURCE_NAME } from 'app/plugins/datasource/mixed/MixedDataSource';
@ -108,7 +107,7 @@ function setup({ queryParams = {}, datasourceGetter = defaultDsGetter }: SetupPa
);
return {
...renderHook<{ params: UrlQueryMap; children: ReactNode }, void>(({ params }) => useStateSync(params), {
...renderHook(({ params }) => useStateSync(params), {
wrapper,
initialProps: {
children: null,
@ -122,20 +121,19 @@ function setup({ queryParams = {}, datasourceGetter = defaultDsGetter }: SetupPa
describe('useStateSync', () => {
it('does not push a new entry to history on first render', async () => {
const { location, waitForNextUpdate } = setup({});
const { location } = setup({});
const initialHistoryLength = location.getHistory().length;
await waitForNextUpdate();
expect(location.getHistory().length).toBe(initialHistoryLength);
const search = location.getSearchObject();
expect(search.panes).toBeDefined();
await waitFor(() => {
expect(location.getHistory().length).toBe(initialHistoryLength);
const search = location.getSearchObject();
expect(search.panes).toBeDefined();
});
});
it('correctly inits an explore pane for each key in the panes search object', async () => {
const { location, waitForNextUpdate, store } = setup({
const { location, store } = setup({
queryParams: {
panes: JSON.stringify({
one: {
@ -180,30 +178,31 @@ describe('useStateSync', () => {
const initialHistoryLength = location.getHistory().length;
await waitForNextUpdate();
expect(location.getHistory().length).toBe(initialHistoryLength);
const panes = location.getSearch().get('panes');
expect(panes).not.toBeNull();
if (panes) {
// check if the URL is properly encoded when finishing rendering the hook. (this would be '1 2' otherwise)
expect(JSON.parse(panes)['one'].queries[0].refId).toBe('1+2');
expect(JSON.parse(panes)['one'].queries[0].datasource?.uid).toBe('loki-uid');
// we expect panes in the state to be in the same order as the ones in the URL
expect(Object.keys(store.getState().explore.panes)).toStrictEqual(Object.keys(JSON.parse(panes)));
// check that the datasources for the queries resolved correctly when set to a name or uid
expect(JSON.parse(panes)['one'].queries[1].refId).toBe('3');
expect(JSON.parse(panes)['one'].queries[1].datasource?.uid).toBe('loki-uid');
expect(JSON.parse(panes)['one'].queries[2].refId).toBe('4');
expect(JSON.parse(panes)['one'].queries[2].datasource?.uid).toBe('loki-uid');
}
// await waitForNextUpdate();
await waitFor(() => {
expect(location.getHistory().length).toBe(initialHistoryLength);
const panes = location.getSearch().get('panes');
expect(panes).not.toBeNull();
if (panes) {
// check if the URL is properly encoded when finishing rendering the hook. (this would be '1 2' otherwise)
expect(JSON.parse(panes)['one'].queries[0].refId).toBe('1+2');
expect(JSON.parse(panes)['one'].queries[0].datasource?.uid).toBe('loki-uid');
// we expect panes in the state to be in the same order as the ones in the URL
expect(Object.keys(store.getState().explore.panes)).toStrictEqual(Object.keys(JSON.parse(panes)));
// check that the datasources for the queries resolved correctly when set to a name or uid
expect(JSON.parse(panes)['one'].queries[1].refId).toBe('3');
expect(JSON.parse(panes)['one'].queries[1].datasource?.uid).toBe('loki-uid');
expect(JSON.parse(panes)['one'].queries[2].refId).toBe('4');
expect(JSON.parse(panes)['one'].queries[2].datasource?.uid).toBe('loki-uid');
}
});
});
it('inits with a default query from the root level datasource when there are no valid queries in the URL', async () => {
const { location, waitForNextUpdate, store } = setup({
const { location, store } = setup({
queryParams: {
panes: JSON.stringify({
one: { datasource: 'loki-uid', queries: [{ datasource: { name: 'UNKNOWN', uid: 'UNKNOWN-DS' } }] },
@ -214,21 +213,21 @@ describe('useStateSync', () => {
const initialHistoryLength = location.getHistory().length;
await waitForNextUpdate();
expect(location.getHistory().length).toBe(initialHistoryLength);
await waitFor(() => {
expect(location.getHistory().length).toBe(initialHistoryLength);
const search = location.getSearchObject();
expect(search.panes).toBeDefined();
const search = location.getSearchObject();
expect(search.panes).toBeDefined();
const queries = store.getState().explore.panes['one']?.queries;
expect(queries).toHaveLength(1);
const queries = store.getState().explore.panes['one']?.queries;
expect(queries).toHaveLength(1);
expect(queries?.[0].datasource?.uid).toBe('loki-uid');
expect(queries?.[0].datasource?.uid).toBe('loki-uid');
});
});
it('inits with mixed datasource if there are multiple datasources in queries and no root level datasource is defined', async () => {
const { location, waitForNextUpdate, store } = setup({
const { location, store } = setup({
queryParams: {
panes: JSON.stringify({
one: {
@ -244,23 +243,23 @@ describe('useStateSync', () => {
const initialHistoryLength = location.getHistory().length;
await waitForNextUpdate();
expect(location.getHistory().length).toBe(initialHistoryLength);
await waitFor(() => {
expect(location.getHistory().length).toBe(initialHistoryLength);
const search = location.getSearchObject();
expect(search.panes).toBeDefined();
const search = location.getSearchObject();
expect(search.panes).toBeDefined();
const paneState = store.getState().explore.panes['one'];
expect(paneState?.datasourceInstance?.name).toBe(MIXED_DATASOURCE_NAME);
const paneState = store.getState().explore.panes['one'];
expect(paneState?.datasourceInstance?.name).toBe(MIXED_DATASOURCE_NAME);
expect(paneState?.queries).toHaveLength(2);
expect(paneState?.queries?.[0].datasource?.uid).toBe('loki-uid');
expect(paneState?.queries?.[1].datasource?.uid).toBe('elastic-uid');
expect(paneState?.queries).toHaveLength(2);
expect(paneState?.queries?.[0].datasource?.uid).toBe('loki-uid');
expect(paneState?.queries?.[1].datasource?.uid).toBe('elastic-uid');
});
});
it("inits with a query's datasource if there are multiple datasources in queries, no root level datasource, and only one query has a valid datsource", async () => {
const { location, waitForNextUpdate, store } = setup({
const { location, store } = setup({
queryParams: {
panes: JSON.stringify({
one: {
@ -276,44 +275,44 @@ describe('useStateSync', () => {
const initialHistoryLength = location.getHistory().length;
await waitForNextUpdate();
expect(location.getHistory().length).toBe(initialHistoryLength);
await waitFor(() => {
expect(location.getHistory().length).toBe(initialHistoryLength);
const search = location.getSearchObject();
expect(search.panes).toBeDefined();
const search = location.getSearchObject();
expect(search.panes).toBeDefined();
const paneState = store.getState().explore.panes['one'];
expect(paneState?.datasourceInstance?.getRef().uid).toBe('loki-uid');
const paneState = store.getState().explore.panes['one'];
expect(paneState?.datasourceInstance?.getRef().uid).toBe('loki-uid');
expect(paneState?.queries).toHaveLength(1);
expect(paneState?.queries?.[0].datasource?.uid).toBe('loki-uid');
expect(paneState?.queries).toHaveLength(1);
expect(paneState?.queries?.[0].datasource?.uid).toBe('loki-uid');
});
});
it('inits with the last used datasource from localStorage', async () => {
setLastUsedDatasourceUID(1, 'elastic-uid');
const { waitForNextUpdate, store } = setup({
const { store } = setup({
queryParams: {},
});
await waitForNextUpdate();
expect(Object.values(store.getState().explore.panes)[0]?.datasourceInstance?.uid).toBe('elastic-uid');
await waitFor(() => {
expect(Object.values(store.getState().explore.panes)[0]?.datasourceInstance?.uid).toBe('elastic-uid');
});
});
it('inits with the default datasource if the last used in localStorage does not exits', async () => {
setLastUsedDatasourceUID(1, 'unknown-ds-uid');
const { waitForNextUpdate, store } = setup({
const { store } = setup({
queryParams: {},
});
await waitForNextUpdate();
expect(Object.values(store.getState().explore.panes)[0]?.datasourceInstance?.uid).toBe('loki-uid');
await waitFor(() => {
expect(Object.values(store.getState().explore.panes)[0]?.datasourceInstance?.uid).toBe('loki-uid');
});
});
it('updates the state with correct queries from URL', async () => {
const { waitForNextUpdate, rerender, store } = setup({
const { rerender, store } = setup({
queryParams: {
panes: JSON.stringify({
one: { datasource: 'loki-uid', queries: [{ expr: 'a' }] },
@ -322,11 +321,12 @@ describe('useStateSync', () => {
},
});
await waitForNextUpdate();
let queries = store.getState().explore.panes['one']?.queries;
expect(queries).toHaveLength(1);
expect(queries?.[0]).toMatchObject({ expr: 'a' });
let queries: DataQuery[] | undefined;
await waitFor(() => {
queries = store.getState().explore.panes['one']?.queries;
expect(queries).toHaveLength(1);
expect(queries?.[0]).toMatchObject({ expr: 'a' });
});
rerender({
children: null,
@ -338,12 +338,12 @@ describe('useStateSync', () => {
},
});
await waitForNextUpdate();
queries = store.getState().explore.panes['one']?.queries;
expect(queries).toHaveLength(2);
expect(queries?.[0]).toMatchObject({ expr: 'a' });
expect(queries?.[1]).toMatchObject({ expr: 'b' });
await waitFor(() => {
queries = store.getState().explore.panes['one']?.queries;
expect(queries).toHaveLength(2);
expect(queries?.[0]).toMatchObject({ expr: 'a' });
expect(queries?.[1]).toMatchObject({ expr: 'b' });
});
rerender({
children: null,
@ -355,15 +355,15 @@ describe('useStateSync', () => {
},
});
await waitForNextUpdate();
queries = store.getState().explore.panes['one']?.queries;
expect(queries).toHaveLength(1);
expect(queries?.[0]).toMatchObject({ expr: 'a' });
await waitFor(() => {
queries = store.getState().explore.panes['one']?.queries;
expect(queries).toHaveLength(1);
expect(queries?.[0]).toMatchObject({ expr: 'a' });
});
});
it('Opens and closes the split pane if an a new pane is added or removed in the URL', async () => {
const { waitForNextUpdate, rerender, store } = setup({
const { rerender, store } = setup({
queryParams: {
panes: JSON.stringify({
one: { datasource: 'loki-uid', queries: [{ expr: 'a' }] },
@ -372,10 +372,10 @@ describe('useStateSync', () => {
},
});
await waitForNextUpdate();
let panes = Object.keys(store.getState().explore.panes);
expect(panes).toHaveLength(1);
await waitFor(() => {
let panes = Object.keys(store.getState().explore.panes);
expect(panes).toHaveLength(1);
});
rerender({
children: null,
@ -388,9 +388,9 @@ describe('useStateSync', () => {
},
});
await waitForNextUpdate();
expect(Object.keys(store.getState().explore.panes)).toHaveLength(2);
await waitFor(() => {
expect(Object.keys(store.getState().explore.panes)).toHaveLength(2);
});
rerender({
children: null,
@ -402,15 +402,13 @@ describe('useStateSync', () => {
},
});
await waitForNextUpdate();
await waitFor(() => {
expect(Object.keys(store.getState().explore.panes)).toHaveLength(1);
});
});
it('Changes datasource when the datasource in the URL is updated', async () => {
const { waitForNextUpdate, rerender, store } = setup({
const { rerender, store } = setup({
queryParams: {
panes: JSON.stringify({
one: { datasource: 'loki-uid', queries: [{ expr: 'a' }] },
@ -419,11 +417,11 @@ describe('useStateSync', () => {
},
});
await waitForNextUpdate();
expect(store.getState().explore.panes['one']?.datasourceInstance?.getRef()).toMatchObject({
type: 'logs',
uid: 'loki-uid',
await waitFor(() => {
expect(store.getState().explore.panes['one']?.datasourceInstance?.getRef()).toMatchObject({
type: 'logs',
uid: 'loki-uid',
});
});
rerender({
@ -436,16 +434,16 @@ describe('useStateSync', () => {
},
});
await waitForNextUpdate();
expect(store.getState().explore.panes['one']?.datasourceInstance?.getRef()).toMatchObject({
type: 'logs',
uid: 'elastic-uid',
await waitFor(() => {
expect(store.getState().explore.panes['one']?.datasourceInstance?.getRef()).toMatchObject({
type: 'logs',
uid: 'elastic-uid',
});
});
});
it('Changes time rage when the range in the URL is updated', async () => {
const { waitForNextUpdate, rerender, store } = setup({
const { rerender, store } = setup({
queryParams: {
panes: JSON.stringify({
one: { datasource: 'loki-uid', queries: [{ expr: 'a' }], range: { from: 'now-1h', to: 'now' } },
@ -454,9 +452,9 @@ describe('useStateSync', () => {
},
});
await waitForNextUpdate();
expect(store.getState().explore.panes['one']?.range.raw).toMatchObject({ from: 'now-1h', to: 'now' });
await waitFor(() => {
expect(store.getState().explore.panes['one']?.range.raw).toMatchObject({ from: 'now-1h', to: 'now' });
});
rerender({
children: null,
@ -468,13 +466,13 @@ describe('useStateSync', () => {
},
});
await waitForNextUpdate();
expect(store.getState().explore.panes['one']?.range.raw).toMatchObject({ from: 'now-6h', to: 'now' });
await waitFor(() => {
expect(store.getState().explore.panes['one']?.range.raw).toMatchObject({ from: 'now-6h', to: 'now' });
});
});
it('Changes time range when the range in the URL is updated to absolute range', async () => {
const { waitForNextUpdate, rerender, store } = setup({
const { rerender, store } = setup({
queryParams: {
panes: JSON.stringify({
one: { datasource: 'loki-uid', queries: [{ expr: 'a' }], range: { from: 'now-1h', to: 'now' } },
@ -483,9 +481,9 @@ describe('useStateSync', () => {
},
});
await waitForNextUpdate();
expect(store.getState().explore.panes['one']?.range.raw).toMatchObject({ from: 'now-1h', to: 'now' });
await waitFor(() => {
expect(store.getState().explore.panes['one']?.range.raw).toMatchObject({ from: 'now-1h', to: 'now' });
});
rerender({
children: null,
@ -501,14 +499,14 @@ describe('useStateSync', () => {
},
});
await waitForNextUpdate();
expect(store.getState().explore.panes['one']?.range.raw.from.valueOf().toString()).toEqual('1500000000000');
expect(store.getState().explore.panes['one']?.range.raw.to.valueOf().toString()).toEqual('1500000001000');
await waitFor(() => {
expect(store.getState().explore.panes['one']?.range.raw.from.valueOf().toString()).toEqual('1500000000000');
expect(store.getState().explore.panes['one']?.range.raw.to.valueOf().toString()).toEqual('1500000001000');
});
});
it('uses the first query datasource if no root datasource is specified in the URL', async () => {
const { waitForNextUpdate, store } = setup({
const { store } = setup({
queryParams: {
panes: JSON.stringify({
one: {
@ -519,16 +517,16 @@ describe('useStateSync', () => {
},
});
await waitForNextUpdate();
expect(store.getState().explore.panes['one']?.datasourceInstance?.getRef()).toMatchObject({
uid: 'loki-uid',
type: 'logs',
await waitFor(() => {
expect(store.getState().explore.panes['one']?.datasourceInstance?.getRef()).toMatchObject({
uid: 'loki-uid',
type: 'logs',
});
});
});
it('updates the URL opening and closing a pane datasource changes', async () => {
const { waitForNextUpdate, store, location } = setup({
const { store, location } = setup({
queryParams: {
panes: JSON.stringify({
one: {
@ -540,22 +538,20 @@ describe('useStateSync', () => {
},
});
await waitForNextUpdate();
expect(location.getHistory().length).toBe(1);
await waitFor(() => {
expect(location.getHistory().length).toBe(1);
expect(store.getState().explore.panes['one']?.datasourceInstance?.uid).toBe('loki-uid');
expect(store.getState().explore.panes['one']?.datasourceInstance?.uid).toBe('loki-uid');
});
act(() => {
store.dispatch(splitOpen());
});
await waitForNextUpdate();
await waitFor(async () => {
await waitFor(() => {
expect(location.getHistory().length).toBe(2);
expect(Object.keys(store.getState().explore.panes)).toHaveLength(2);
});
expect(Object.keys(store.getState().explore.panes)).toHaveLength(2);
act(() => {
store.dispatch(splitClose('one'));
@ -567,7 +563,7 @@ describe('useStateSync', () => {
});
it('filters out queries from the URL that do not have a datasource', async () => {
const { waitForNextUpdate, store } = setup({
const { store } = setup({
queryParams: {
panes: JSON.stringify({
one: {
@ -582,9 +578,9 @@ describe('useStateSync', () => {
},
});
await waitForNextUpdate();
expect(store.getState().explore.panes['one']?.queries.length).toBe(1);
expect(store.getState().explore.panes['one']?.queries[0]).toMatchObject({ expr: 'b', refId: 'B' });
await waitFor(() => {
expect(store.getState().explore.panes['one']?.queries.length).toBe(1);
expect(store.getState().explore.panes['one']?.queries[0]).toMatchObject({ expr: 'b', refId: 'B' });
});
});
});

@ -1,5 +1,4 @@
import { act, render, screen, waitFor } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import { act, render, renderHook, screen, waitFor } from '@testing-library/react';
import { PluginContextProvider, PluginLoadingStrategy, PluginMeta, PluginType } from '@grafana/data';
import { config } from '@grafana/runtime';

@ -1,5 +1,4 @@
import { act, render, screen } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import { act, render, renderHook, screen } from '@testing-library/react';
import { PluginContextProvider, PluginMeta, PluginType } from '@grafana/data';

@ -1,5 +1,4 @@
import { act } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import { act, renderHook } from '@testing-library/react';
import { AddedComponentsRegistry } from './registry/AddedComponentsRegistry';
import { AddedLinksRegistry } from './registry/AddedLinksRegistry';

@ -1,5 +1,4 @@
import { act } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import { act, renderHook } from '@testing-library/react';
import { PluginContextProvider, PluginMeta, PluginType } from '@grafana/data';

@ -1,4 +1,4 @@
import renderer from 'react-test-renderer';
import { render, screen, waitFor } from '@testing-library/react';
import { VariableModel } from '@grafana/data';
@ -39,9 +39,13 @@ const props: Props = {
};
describe('VariableQueryEditor', () => {
it('renders correctly', () => {
const tree = renderer.create(<CloudMonitoringVariableQueryEditor {...props} />).toJSON();
expect(tree).toMatchSnapshot();
it('renders correctly', async () => {
const { container } = render(<CloudMonitoringVariableQueryEditor {...props} />);
const select = await screen.findByRole('combobox');
waitFor(() => {
expect(select).toHaveValue('projects');
});
expect(container).toMatchSnapshot();
});
describe('and a new variable is created', () => {
@ -50,7 +54,7 @@ describe('VariableQueryEditor', () => {
expect(query.selectedQueryType).toBe('projects');
done();
};
renderer.create(<CloudMonitoringVariableQueryEditor {...props} />).toJSON();
render(<CloudMonitoringVariableQueryEditor {...props} />);
});
});
@ -61,7 +65,7 @@ describe('VariableQueryEditor', () => {
expect(query.selectedQueryType).toBe('labelKeys');
done();
};
renderer.create(<CloudMonitoringVariableQueryEditor {...props} />).toJSON();
render(<CloudMonitoringVariableQueryEditor {...props} />);
});
});
});

@ -1,109 +1,85 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`VariableQueryEditor renders correctly 1`] = `
<div
className="css-1rplq84"
>
<div>
<div
className="css-l4ykjo-Label"
class="css-1rplq84"
>
<label>
<div
className="css-70qvj9"
>
Query Type
</div>
</label>
</div>
<div>
<div
class="css-l4ykjo-Label"
>
<label>
<div
class="css-70qvj9"
>
Query Type
</div>
</label>
</div>
<div>
<div
className="css-1nmqu8c-input-wrapper css-smf98s"
onKeyDown={[Function]}
>
<span
className="css-1f43avz-a11yText-A11yText"
id="react-select-2-live-region"
/>
<span
aria-atomic="false"
aria-live="polite"
aria-relevant="additions text"
className="css-1f43avz-a11yText-A11yText"
role="log"
/>
<div>
<div
className="css-1i88p6p"
onMouseDown={[Function]}
onTouchEnd={[Function]}
class="css-1nmqu8c-input-wrapper css-smf98s"
>
<span
class="css-1f43avz-a11yText-A11yText"
id="react-select-2-live-region"
/>
<span
aria-atomic="false"
aria-live="polite"
aria-relevant="additions text"
class="css-1f43avz-a11yText-A11yText"
role="log"
/>
<div
className="css-1q0c0d5-grafana-select-value-container"
class="css-1i88p6p"
>
<div
className="css-8nwx1l-singleValue css-0"
class="css-1q0c0d5-grafana-select-value-container"
>
Loading...
<div
class="css-8nwx1l-singleValue css-0"
>
Loading...
</div>
<div
class="css-1eu65zc"
data-value=""
>
<input
aria-activedescendant=""
aria-autocomplete="list"
aria-expanded="false"
aria-haspopup="true"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
class=""
id="react-select-2-input"
role="combobox"
spellcheck="false"
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
tabindex="0"
type="text"
value=""
/>
</div>
</div>
<div
className="css-1eu65zc"
data-value=""
class="css-zyjsuv-input-suffix"
>
<input
aria-activedescendant=""
aria-autocomplete="list"
aria-expanded={false}
aria-haspopup={true}
autoCapitalize="none"
autoComplete="off"
autoCorrect="off"
className=""
disabled={false}
id="react-select-2-input"
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
role="combobox"
spellCheck="false"
style={
{
"background": 0,
"border": 0,
"color": "inherit",
"font": "inherit",
"gridArea": "1 / 2",
"label": "input",
"margin": 0,
"minWidth": "2px",
"opacity": 1,
"outline": 0,
"padding": 0,
"width": "100%",
}
}
tabIndex={0}
type="text"
value=""
<svg
aria-hidden="true"
class="css-1d3xu67-Icon"
height="16"
id="public/img/icons/unicons/angle-down.svg"
loader="[object Object]"
title=""
width="16"
/>
</div>
</div>
<div
className="css-zyjsuv-input-suffix"
>
<svg
aria-hidden={true}
className="css-1d3xu67-Icon"
height={16}
id="public/img/icons/unicons/angle-down.svg"
loader={
<div
className="css-ua55tz-Icon"
/>
}
title=""
width={16}
/>
</div>
</div>
</div>
</div>

@ -39,9 +39,7 @@
"@types/prismjs": "1.26.5",
"@types/react": "18.3.3",
"@types/react-dom": "18.2.25",
"@types/react-test-renderer": "18.3.0",
"react-select-event": "5.5.1",
"react-test-renderer": "18.2.0",
"ts-node": "10.9.2",
"typescript": "5.5.4",
"webpack": "5.97.1"

@ -1,5 +1,4 @@
import { render } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import { render, renderHook } from '@testing-library/react';
import { PropsWithChildren } from 'react';
import { getDefaultTimeRange } from '@grafana/data';
@ -47,9 +46,11 @@ describe('ElasticsearchQueryContext', () => {
// the following applies to all hooks in ElasticsearchQueryContext as they all share the same code.
describe('useQuery Hook', () => {
it('Should throw when used outside of ElasticsearchQueryContext', () => {
const { result } = renderHook(() => useQuery());
expect(result.error).toBeTruthy();
jest.spyOn(console, 'error').mockImplementation(() => {});
expect(() => {
renderHook(() => useQuery());
}).toThrow();
expect(console.error).toHaveBeenCalled();
});
it('Should return the current query object', () => {

@ -1,4 +1,4 @@
import { renderHook } from '@testing-library/react-hooks';
import { renderHook } from '@testing-library/react';
import { PropsWithChildren } from 'react';
import { useStatelessReducer, useDispatch, DispatchContext, combineReducers } from './useStatelessReducer';
@ -33,9 +33,11 @@ describe('useStatelessReducer Hook', () => {
describe('useDispatch Hook', () => {
it('Should throw when used outside of DispatchContext', () => {
const { result } = renderHook(() => useDispatch());
expect(result.error).toBeTruthy();
jest.spyOn(console, 'error').mockImplementation(() => {});
expect(() => {
renderHook(() => useDispatch());
}).toThrow();
expect(console.error).toHaveBeenCalled();
});
it('Should return a dispatch function', () => {

@ -1,5 +1,5 @@
// CustomHook.test.js
import { renderHook } from '@testing-library/react-hooks';
import { renderHook, waitFor } from '@testing-library/react';
import { MockDataSourceApi, DatasourceSrvMock } from 'test/mocks/datasource_srv';
import { useDatasourcesFromTargets } from './useDatasourcesFromTargets'; // Update the path accordingly
@ -20,11 +20,11 @@ jest.mock('@grafana/runtime', () => ({
describe('useDatasourcesFromTargets', () => {
it('returns an empty map when targets are not provided', async () => {
const { result, waitForNextUpdate } = renderHook(() => useDatasourcesFromTargets(undefined));
const { result } = renderHook(() => useDatasourcesFromTargets(undefined));
await waitForNextUpdate();
expect(result.current.size).toBe(0);
await waitFor(() => {
expect(result.current.size).toBe(0);
});
});
it('fetches and returns the data sources map', async () => {
@ -33,12 +33,12 @@ describe('useDatasourcesFromTargets', () => {
{ refId: '2', datasource: { uid: 'dataSource2' } },
];
const { result, waitForNextUpdate } = renderHook(() => useDatasourcesFromTargets(mockTargets));
await waitForNextUpdate();
const { result } = renderHook(() => useDatasourcesFromTargets(mockTargets));
expect(result.current.size).toBe(2);
expect(result.current.get('1')).toEqual(ds1);
expect(result.current.get('2')).toEqual(ds2);
await waitFor(() => {
expect(result.current.size).toBe(2);
expect(result.current.get('1')).toEqual(ds1);
expect(result.current.get('2')).toEqual(ds2);
});
});
});

@ -1,5 +1,4 @@
import { renderHook } from '@testing-library/react';
import { act } from 'react-test-renderer';
import { act, renderHook } from '@testing-library/react';
import { useLayout } from './layout';
import { EdgeDatum, NodeDatum } from './types';

@ -3131,7 +3131,6 @@ __metadata:
"@types/prismjs": "npm:1.26.5"
"@types/react": "npm:18.3.3"
"@types/react-dom": "npm:18.2.25"
"@types/react-test-renderer": "npm:18.3.0"
debounce-promise: "npm:3.1.2"
fast-deep-equal: "npm:^3.1.3"
i18next: "npm:^23.0.0"
@ -3143,7 +3142,6 @@ __metadata:
react-dom: "npm:18.2.0"
react-select: "npm:5.9.0"
react-select-event: "npm:5.5.1"
react-test-renderer: "npm:18.2.0"
react-use: "npm:17.6.0"
rxjs: "npm:7.8.1"
ts-node: "npm:10.9.2"
@ -3725,7 +3723,6 @@ __metadata:
react-highlight-words: "npm:0.20.0"
react-select: "npm:5.9.0"
react-select-event: "npm:5.5.1"
react-test-renderer: "npm:18.2.0"
react-use: "npm:17.6.0"
react-window: "npm:1.8.11"
rollup: "npm:^4.22.4"
@ -3904,7 +3901,6 @@ __metadata:
"@testing-library/dom": "npm:10.4.0"
"@testing-library/jest-dom": "npm:^6.1.2"
"@testing-library/react": "npm:16.1.0"
"@testing-library/react-hooks": "npm:^8.0.1"
"@testing-library/user-event": "npm:14.5.2"
"@types/jest": "npm:^29.5.4"
"@types/lodash": "npm:4.17.13"
@ -4002,7 +3998,6 @@ __metadata:
"@types/react-dom": "npm:18.2.25"
"@types/react-highlight-words": "npm:0.20.0"
"@types/react-table": "npm:7.7.20"
"@types/react-test-renderer": "npm:18.3.0"
"@types/react-transition-group": "npm:4.4.12"
"@types/react-window": "npm:1.8.8"
"@types/slate": "npm:0.47.11"
@ -4057,7 +4052,6 @@ __metadata:
react-select: "npm:5.9.0"
react-select-event: "npm:^5.1.0"
react-table: "npm:7.8.0"
react-test-renderer: "npm:18.2.0"
react-transition-group: "npm:4.4.5"
react-use: "npm:17.6.0"
react-window: "npm:1.8.11"
@ -8544,28 +8538,6 @@ __metadata:
languageName: node
linkType: hard
"@testing-library/react-hooks@npm:^8.0.1":
version: 8.0.1
resolution: "@testing-library/react-hooks@npm:8.0.1"
dependencies:
"@babel/runtime": "npm:^7.12.5"
react-error-boundary: "npm:^3.1.0"
peerDependencies:
"@types/react": ^16.9.0 || ^17.0.0
react: ^16.9.0 || ^17.0.0
react-dom: ^16.9.0 || ^17.0.0
react-test-renderer: ^16.9.0 || ^17.0.0
peerDependenciesMeta:
"@types/react":
optional: true
react-dom:
optional: true
react-test-renderer:
optional: true
checksum: 10/f7b69373feebe99bc7d60595822cc5c00a1a5a4801bc4f99b597256a5c1d23c45a51f359051dd8a7bdffcc23b26f324c582e9433c25804934fd351a886812790
languageName: node
linkType: hard
"@testing-library/react@npm:16.1.0":
version: 16.1.0
resolution: "@testing-library/react@npm:16.1.0"
@ -9782,15 +9754,6 @@ __metadata:
languageName: node
linkType: hard
"@types/react-test-renderer@npm:18.3.0":
version: 18.3.0
resolution: "@types/react-test-renderer@npm:18.3.0"
dependencies:
"@types/react": "npm:*"
checksum: 10/c53683990bd194cb68e3987bda79c78eff41517f7a747e92f3e54217c2ce3addd031b8a45bf631982c909cc2caeeb905372f322758e05bb76c03754a3f24426e
languageName: node
linkType: hard
"@types/react-transition-group@npm:4.4.12, @types/react-transition-group@npm:^4.4.0":
version: 4.4.12
resolution: "@types/react-transition-group@npm:4.4.12"
@ -17603,7 +17566,6 @@ __metadata:
"@testing-library/dom": "npm:10.4.0"
"@testing-library/jest-dom": "npm:6.6.3"
"@testing-library/react": "npm:16.1.0"
"@testing-library/react-hooks": "npm:^8.0.1"
"@testing-library/user-event": "npm:14.5.2"
"@types/angular": "npm:1.8.9"
"@types/angular-route": "npm:1.7.6"
@ -17644,7 +17606,6 @@ __metadata:
"@types/react-router": "npm:5.1.20"
"@types/react-router-dom": "npm:5.3.3"
"@types/react-table": "npm:7.7.20"
"@types/react-test-renderer": "npm:18.3.0"
"@types/react-transition-group": "npm:4.4.12"
"@types/react-virtualized-auto-sizer": "npm:1.0.4"
"@types/react-window": "npm:1.8.8"
@ -17816,7 +17777,6 @@ __metadata:
react-select-event: "npm:5.5.1"
react-split-pane: "npm:0.1.92"
react-table: "npm:7.8.0"
react-test-renderer: "npm:18.2.0"
react-transition-group: "npm:4.4.5"
react-use: "npm:17.6.0"
react-virtual: "npm:2.10.4"
@ -25423,17 +25383,6 @@ __metadata:
languageName: node
linkType: hard
"react-error-boundary@npm:^3.1.0":
version: 3.1.4
resolution: "react-error-boundary@npm:3.1.4"
dependencies:
"@babel/runtime": "npm:^7.12.5"
peerDependencies:
react: ">=16.13.1"
checksum: 10/7418637bf352b88f35ff3798e6faa094ee046df9d422fc08f54c017892c3c0738dac661ba3d64d97209464e7a60e7fbbeffdbeaee5edc38f3aaf5f1f4a8bf610
languageName: node
linkType: hard
"react-fast-compare@npm:^3.0.1":
version: 3.2.0
resolution: "react-fast-compare@npm:3.2.0"
@ -25575,7 +25524,7 @@ __metadata:
languageName: node
linkType: hard
"react-is@npm:18.2.0, react-is@npm:^16.12.0 || ^17.0.0 || ^18.0.0, react-is@npm:^18.0.0, react-is@npm:^18.2.0":
"react-is@npm:18.2.0, react-is@npm:^18.0.0, react-is@npm:^18.2.0":
version: 18.2.0
resolution: "react-is@npm:18.2.0"
checksum: 10/200cd65bf2e0be7ba6055f647091b725a45dd2a6abef03bf2380ce701fd5edccee40b49b9d15edab7ac08a762bf83cb4081e31ec2673a5bfb549a36ba21570df
@ -25889,18 +25838,6 @@ __metadata:
languageName: node
linkType: hard
"react-shallow-renderer@npm:^16.15.0":
version: 16.15.0
resolution: "react-shallow-renderer@npm:16.15.0"
dependencies:
object-assign: "npm:^4.1.1"
react-is: "npm:^16.12.0 || ^17.0.0 || ^18.0.0"
peerDependencies:
react: ^16.0.0 || ^17.0.0 || ^18.0.0
checksum: 10/06457fe5bcaa44aeca998905b6849304742ea1cc2d3841e4a0964c745ff392bc4dec07f8c779f317faacce3a0bf6f84e15020ac0fa81adb931067dbb0baf707b
languageName: node
linkType: hard
"react-split-pane@npm:0.1.92":
version: 0.1.92
resolution: "react-split-pane@npm:0.1.92"
@ -25962,19 +25899,6 @@ __metadata:
languageName: node
linkType: hard
"react-test-renderer@npm:18.2.0":
version: 18.2.0
resolution: "react-test-renderer@npm:18.2.0"
dependencies:
react-is: "npm:^18.2.0"
react-shallow-renderer: "npm:^16.15.0"
scheduler: "npm:^0.23.0"
peerDependencies:
react: ^18.2.0
checksum: 10/39473e43f64eec92da35db9d4411f3887b368038670787d49dd23172eb3a29953eb13767d1bfa34cbe2665b6e25632cad146e362e8910ce33755d343537763ae
languageName: node
linkType: hard
"react-transition-group@npm:4.4.5, react-transition-group@npm:^4.3.0":
version: 4.4.5
resolution: "react-transition-group@npm:4.4.5"

Loading…
Cancel
Save