mirror of
https://github.com/grafana/grafana.git
synced 2025-02-16 18:34:52 -06:00
* update react 18 related deps * fix some types * make sure we're on react-router-dom >= 5.3.3 * Use new root API * Remove StrictMode for now - react 18 double rendering causes issues * fix + ignore some @grafana/ui types * fix some more types * use renderHook from @testing-library/react in almost all cases * fix storybook types * rewrite useDashboardSave to not use useEffect * make props optional * only render if props are provided * add correct type for useCallback * make resourcepicker tests more robust * fix ModalManager rendering * fix some more unit tests * store the click coordinates in a ref as setState is NOT synchronous * fix remaining e2e tests * rewrite dashboardpage tests to avoid act warnings * undo lint ignores * fix ExpanderCell types * set SymbolCell type correctly * fix QueryAndExpressionsStep * looks like the types were actually wrong instead :D * undo this for now... * remove spinner waits * more robust tests * rewrite errorboundary test to not explicitly count the number of renders * make urlParam expect async * increase timeout in waitFor * revert ExplorePage test changes * Update public/app/features/dashboard/containers/DashboardPage.test.tsx Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Update public/app/features/dashboard/containers/PublicDashboardPage.test.tsx Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Update public/app/features/dashboard/containers/PublicDashboardPage.test.tsx Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Update public/app/features/dashboard/containers/PublicDashboardPage.test.tsx Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * skip fakeTimer test, ignore table types for now + other review comments * update package peerDeps * small tweak to resourcepicker test * update lockfile... * increase timeout in sharepublicdashboard tests * ensure ExplorePaneContainer passes correct queries to initializeExplore * fix LokiContextUI test * fix unit tests * make importDashboard flow more consistent * wait for dashboard name before continuing * more test fixes * readd dashboard name to variable e2e tests * wait for switches to be enabled before clicking * fix modal rendering * don't use @testing-library/dom directly * quick fix for rendering of panels in firefox * make PromQueryField test more robust * don't wait for chartData - in react 18 this can happen before the wait code even gets executed --------- Co-authored-by: kay delaney <kay@grafana.com> Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
214 lines
8.5 KiB
TypeScript
214 lines
8.5 KiB
TypeScript
import { render, screen, waitFor, within } from '@testing-library/react';
|
|
import userEvent from '@testing-library/user-event';
|
|
import React from 'react';
|
|
import { Provider } from 'react-redux';
|
|
import { BrowserRouter } from 'react-router-dom';
|
|
import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock';
|
|
|
|
import { GrafanaContext } from 'app/core/context/GrafanaContext';
|
|
|
|
import { configureStore } from '../../../../store/configureStore';
|
|
import { createDashboardModelFixture } from '../../state/__fixtures__/dashboardFixtures';
|
|
import { historySrv } from '../VersionHistory/HistorySrv';
|
|
|
|
import { VersionsSettings, VERSIONS_FETCH_LIMIT } from './VersionsSettings';
|
|
import { versions, diffs } from './__mocks__/versions';
|
|
|
|
jest.mock('../VersionHistory/HistorySrv');
|
|
|
|
const queryByFullText = (text: string) =>
|
|
screen.queryByText((_, node: Element | undefined | null) => {
|
|
if (node) {
|
|
const nodeHasText = (node: HTMLElement | Element) => node.textContent?.includes(text);
|
|
const currentNodeHasText = nodeHasText(node);
|
|
const childrenDontHaveText = Array.from(node.children).every((child) => !nodeHasText(child));
|
|
return Boolean(currentNodeHasText && childrenDontHaveText);
|
|
}
|
|
return false;
|
|
});
|
|
|
|
function setup() {
|
|
const store = configureStore();
|
|
const dashboard = createDashboardModelFixture({
|
|
id: 74,
|
|
version: 11,
|
|
// formatDate: jest.fn(() => 'date'),
|
|
// getRelativeTime: jest.fn(() => 'time ago'),
|
|
});
|
|
|
|
const sectionNav = {
|
|
main: { text: 'Dashboard' },
|
|
node: {
|
|
text: 'Versions',
|
|
},
|
|
};
|
|
|
|
return render(
|
|
<GrafanaContext.Provider value={getGrafanaContextMock()}>
|
|
<Provider store={store}>
|
|
<BrowserRouter>
|
|
<VersionsSettings sectionNav={sectionNav} dashboard={dashboard} />
|
|
</BrowserRouter>
|
|
</Provider>
|
|
</GrafanaContext.Provider>
|
|
);
|
|
}
|
|
|
|
describe('VersionSettings', () => {
|
|
let user: ReturnType<typeof userEvent.setup>;
|
|
|
|
beforeEach(() => {
|
|
// Need to use delay: null here to work with fakeTimers
|
|
// see https://github.com/testing-library/user-event/issues/833
|
|
user = userEvent.setup({ delay: null });
|
|
jest.clearAllMocks();
|
|
jest.useFakeTimers();
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.useRealTimers();
|
|
});
|
|
|
|
test('renders a header and a loading indicator followed by results in a table', async () => {
|
|
// @ts-ignore
|
|
historySrv.getHistoryList.mockResolvedValue(versions);
|
|
setup();
|
|
|
|
expect(screen.getByRole('heading', { name: /versions/i })).toBeInTheDocument();
|
|
expect(screen.queryByText(/fetching history list/i)).toBeInTheDocument();
|
|
|
|
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
|
|
const tableBodyRows = within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row');
|
|
|
|
expect(tableBodyRows.length).toBe(versions.length);
|
|
|
|
const firstRow = within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row')[0];
|
|
|
|
expect(within(firstRow).getByText(/latest/i)).toBeInTheDocument();
|
|
expect(within(screen.getByRole('table')).getAllByText(/latest/i)).toHaveLength(1);
|
|
});
|
|
|
|
test('does not render buttons if versions === 1', async () => {
|
|
// @ts-ignore
|
|
historySrv.getHistoryList.mockResolvedValue(versions.slice(0, 1));
|
|
setup();
|
|
|
|
expect(screen.queryByRole('button', { name: /show more versions/i })).not.toBeInTheDocument();
|
|
expect(screen.queryByRole('button', { name: /compare versions/i })).not.toBeInTheDocument();
|
|
|
|
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
|
|
|
|
expect(screen.queryByRole('button', { name: /show more versions/i })).not.toBeInTheDocument();
|
|
expect(screen.queryByRole('button', { name: /compare versions/i })).not.toBeInTheDocument();
|
|
});
|
|
|
|
test('does not render show more button if versions < VERSIONS_FETCH_LIMIT', async () => {
|
|
// @ts-ignore
|
|
historySrv.getHistoryList.mockResolvedValue(versions.slice(0, VERSIONS_FETCH_LIMIT - 5));
|
|
setup();
|
|
|
|
expect(screen.queryByRole('button', { name: /show more versions/i })).not.toBeInTheDocument();
|
|
expect(screen.queryByRole('button', { name: /compare versions/i })).not.toBeInTheDocument();
|
|
|
|
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
|
|
|
|
expect(screen.queryByRole('button', { name: /show more versions/i })).not.toBeInTheDocument();
|
|
expect(screen.queryByRole('button', { name: /compare versions/i })).toBeInTheDocument();
|
|
});
|
|
|
|
test('renders buttons if versions >= VERSIONS_FETCH_LIMIT', async () => {
|
|
// @ts-ignore
|
|
historySrv.getHistoryList.mockResolvedValue(versions.slice(0, VERSIONS_FETCH_LIMIT));
|
|
setup();
|
|
|
|
expect(screen.queryByRole('button', { name: /show more versions/i })).not.toBeInTheDocument();
|
|
expect(screen.queryByRole('button', { name: /compare versions/i })).not.toBeInTheDocument();
|
|
|
|
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
|
|
const compareButton = screen.getByRole('button', { name: /compare versions/i });
|
|
const showMoreButton = screen.getByRole('button', { name: /show more versions/i });
|
|
|
|
expect(showMoreButton).toBeInTheDocument();
|
|
expect(showMoreButton).toBeEnabled();
|
|
|
|
expect(compareButton).toBeInTheDocument();
|
|
expect(compareButton).toBeDisabled();
|
|
});
|
|
|
|
test('clicking show more appends results to the table', async () => {
|
|
historySrv.getHistoryList
|
|
// @ts-ignore
|
|
.mockImplementationOnce(() => Promise.resolve(versions.slice(0, VERSIONS_FETCH_LIMIT)))
|
|
.mockImplementationOnce(
|
|
() => new Promise((resolve) => setTimeout(() => resolve(versions.slice(VERSIONS_FETCH_LIMIT)), 1000))
|
|
);
|
|
|
|
setup();
|
|
|
|
expect(historySrv.getHistoryList).toBeCalledTimes(1);
|
|
|
|
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
|
|
|
|
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(VERSIONS_FETCH_LIMIT);
|
|
|
|
const showMoreButton = screen.getByRole('button', { name: /show more versions/i });
|
|
await user.click(showMoreButton);
|
|
|
|
expect(historySrv.getHistoryList).toBeCalledTimes(2);
|
|
expect(screen.getByText(/Fetching more entries/i)).toBeInTheDocument();
|
|
jest.advanceTimersByTime(1000);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.queryByText(/Fetching more entries/i)).not.toBeInTheDocument();
|
|
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(versions.length);
|
|
});
|
|
});
|
|
|
|
test('selecting two versions and clicking compare button should render compare view', async () => {
|
|
// @ts-ignore
|
|
historySrv.getHistoryList.mockResolvedValue(versions.slice(0, VERSIONS_FETCH_LIMIT));
|
|
historySrv.getDashboardVersion
|
|
// @ts-ignore
|
|
.mockImplementationOnce(() => Promise.resolve(diffs.lhs))
|
|
.mockImplementationOnce(() => Promise.resolve(diffs.rhs));
|
|
|
|
setup();
|
|
|
|
expect(historySrv.getHistoryList).toBeCalledTimes(1);
|
|
|
|
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
|
|
|
|
const compareButton = screen.getByRole('button', { name: /compare versions/i });
|
|
const tableBody = screen.getAllByRole('rowgroup')[1];
|
|
await user.click(within(tableBody).getAllByRole('checkbox')[0]);
|
|
await user.click(within(tableBody).getAllByRole('checkbox')[VERSIONS_FETCH_LIMIT - 1]);
|
|
|
|
expect(compareButton).toBeEnabled();
|
|
|
|
await user.click(compareButton);
|
|
|
|
await waitFor(() => expect(screen.getByRole('heading', { name: /comparing 2 11/i })).toBeInTheDocument());
|
|
|
|
expect(queryByFullText('Version 11 updated by admin')).toBeInTheDocument();
|
|
expect(queryByFullText('Version 2 updated by admin')).toBeInTheDocument();
|
|
expect(screen.queryByRole('button', { name: /restore to version 2/i })).toBeInTheDocument();
|
|
expect(screen.queryAllByTestId('diffGroup').length).toBe(5);
|
|
|
|
const diffGroups = screen.getAllByTestId('diffGroup');
|
|
|
|
expect(queryByFullText('description added The dashboard description')).toBeInTheDocument();
|
|
expect(queryByFullText('panels changed')).toBeInTheDocument();
|
|
expect(within(diffGroups[1]).queryByRole('list')).toBeInTheDocument();
|
|
expect(within(diffGroups[1]).queryByText(/added title/i)).toBeInTheDocument();
|
|
expect(within(diffGroups[1]).queryByText(/changed id/i)).toBeInTheDocument();
|
|
expect(queryByFullText('tags deleted item 0')).toBeInTheDocument();
|
|
expect(queryByFullText('timepicker added 1 refresh_intervals')).toBeInTheDocument();
|
|
expect(queryByFullText('version changed')).toBeInTheDocument();
|
|
expect(screen.queryByText(/view json diff/i)).toBeInTheDocument();
|
|
|
|
await user.click(screen.getByText(/view json diff/i));
|
|
|
|
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
|
|
});
|
|
});
|