mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
[Chore] Dashboard: Tests for dashboard's add content buttons and menu (#66233)
* add tests for empty dashboard page * add tests for AddPanelButton * export default components * test +Add menu in dashboard page * use userEvent instead of firing an event on the DOM itself * fix test to match new analytic events
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
|
||||
import { defaultDashboard } from '@grafana/schema';
|
||||
|
||||
import { createDashboardModelFixture } from '../../state/__fixtures__/dashboardFixtures';
|
||||
|
||||
import AddPanelButton, { Props } from './AddPanelButton';
|
||||
jest.mock('./AddPanelMenu', () => ({
|
||||
...jest.requireActual('./AddPanelMenu'),
|
||||
__esModule: true,
|
||||
default: () => <div>Menu</div>,
|
||||
}));
|
||||
|
||||
function setup(options?: Partial<Props>) {
|
||||
const props = {
|
||||
dashboard: createDashboardModelFixture(defaultDashboard),
|
||||
};
|
||||
const { rerender } = render(<AddPanelButton dashboard={props.dashboard} />);
|
||||
|
||||
return rerender;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('renders button', () => {
|
||||
setup();
|
||||
|
||||
expect(screen.getByRole('button', { name: 'Add' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders button without menu when menu is not open', () => {
|
||||
setup();
|
||||
|
||||
expect(screen.queryByText('Menu')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders button with menu when menu is open', async () => {
|
||||
const user = userEvent.setup();
|
||||
setup();
|
||||
|
||||
await user.click(screen.getByRole('button', { name: 'Add' }));
|
||||
|
||||
expect(screen.queryByText('Menu')).toBeInTheDocument();
|
||||
});
|
||||
@@ -7,13 +7,13 @@ import { Dropdown, Button, useTheme2, Icon } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { DashboardModel } from 'app/features/dashboard/state';
|
||||
|
||||
import { AddPanelMenu } from './AddPanelMenu';
|
||||
import AddPanelMenu from './AddPanelMenu';
|
||||
|
||||
interface Props {
|
||||
export interface Props {
|
||||
dashboard: DashboardModel;
|
||||
}
|
||||
|
||||
export const AddPanelButton = ({ dashboard }: Props) => {
|
||||
const AddPanelButton = ({ dashboard }: Props) => {
|
||||
const styles = getStyles(useTheme2());
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||
|
||||
@@ -29,7 +29,7 @@ export const AddPanelButton = ({ dashboard }: Props) => {
|
||||
size="lg"
|
||||
fill="text"
|
||||
className={cx(styles.button, styles.buttonIcon, styles.buttonText)}
|
||||
data-testid={selectors.components.PageToolbar.itemButton('Add panel button')}
|
||||
data-testid={selectors.components.PageToolbar.itemButton('Add button')}
|
||||
>
|
||||
<Trans i18nKey="dashboard.toolbar.add">Add</Trans>
|
||||
<Icon name={isMenuOpen ? 'angle-up' : 'angle-down'} size="lg" />
|
||||
@@ -38,6 +38,8 @@ export const AddPanelButton = ({ dashboard }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default AddPanelButton;
|
||||
|
||||
function getStyles(theme: GrafanaTheme2) {
|
||||
return {
|
||||
button: css({
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
import { act, fireEvent, render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
|
||||
import { PluginType } from '@grafana/data';
|
||||
import { locationService, reportInteraction } from '@grafana/runtime';
|
||||
import { defaultDashboard } from '@grafana/schema';
|
||||
import { createDashboardModelFixture } from 'app/features/dashboard/state/__fixtures__/dashboardFixtures';
|
||||
import {
|
||||
onCreateNewPanel,
|
||||
onCreateNewRow,
|
||||
onAddLibraryPanel,
|
||||
getCopiedPanelPlugin,
|
||||
} from 'app/features/dashboard/utils/dashboard';
|
||||
|
||||
import AddPanelMenu from './AddPanelMenu';
|
||||
|
||||
jest.mock('app/types', () => ({
|
||||
...jest.requireActual('app/types'),
|
||||
useDispatch: () => jest.fn(),
|
||||
useSelector: () => jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@grafana/runtime', () => ({
|
||||
...jest.requireActual('@grafana/runtime'),
|
||||
locationService: {
|
||||
partial: jest.fn(),
|
||||
},
|
||||
reportInteraction: jest.fn(),
|
||||
config: {},
|
||||
}));
|
||||
|
||||
jest.mock('app/features/dashboard/utils/dashboard', () => ({
|
||||
onCreateNewPanel: jest.fn(),
|
||||
onCreateNewRow: jest.fn(),
|
||||
onAddLibraryPanel: jest.fn(),
|
||||
getCopiedPanelPlugin: jest.fn(),
|
||||
}));
|
||||
|
||||
function setup() {
|
||||
const props = {
|
||||
dashboard: createDashboardModelFixture(defaultDashboard),
|
||||
};
|
||||
const { rerender } = render(<AddPanelMenu dashboard={props.dashboard} />);
|
||||
|
||||
return rerender;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('renders menu list with correct menu items', () => {
|
||||
setup();
|
||||
|
||||
expect(screen.getByText('visualization', { exact: false })).toBeInTheDocument();
|
||||
expect(screen.getByText('row', { exact: false })).toBeInTheDocument();
|
||||
expect(screen.getByText('library', { exact: false })).toBeInTheDocument();
|
||||
expect(screen.getByText('paste panel', { exact: false })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders with all buttons enabled except paste a panel', () => {
|
||||
// getCopiedPanelPluginMock().mockReset();
|
||||
|
||||
setup();
|
||||
|
||||
expect(screen.getByText('visualization', { exact: false })).not.toBeDisabled();
|
||||
expect(screen.getByText('row', { exact: false })).not.toBeDisabled();
|
||||
expect(screen.getByText('library', { exact: false })).not.toBeDisabled();
|
||||
expect(screen.getByText('paste panel', { exact: false })).toBeDisabled();
|
||||
});
|
||||
|
||||
it('renders with all buttons enabled', () => {
|
||||
(getCopiedPanelPlugin as jest.Mock).mockReturnValue({
|
||||
id: 'someid',
|
||||
name: 'nameofit',
|
||||
type: PluginType.panel,
|
||||
info: {
|
||||
author: {
|
||||
name: 'author name',
|
||||
},
|
||||
description: 'description',
|
||||
links: [],
|
||||
logos: {
|
||||
small: 'small',
|
||||
large: 'large',
|
||||
},
|
||||
updated: 'updated',
|
||||
version: 'version',
|
||||
},
|
||||
module: 'module',
|
||||
baseUrl: 'url',
|
||||
sort: 2,
|
||||
defaults: { gridPos: { w: 200, h: 100 }, title: 'some title' },
|
||||
});
|
||||
|
||||
setup();
|
||||
|
||||
expect(screen.getByText('visualization', { exact: false })).not.toBeDisabled();
|
||||
expect(screen.getByText('row', { exact: false })).not.toBeDisabled();
|
||||
expect(screen.getByText('library', { exact: false })).not.toBeDisabled();
|
||||
expect(screen.getByText('paste panel', { exact: false })).not.toBeDisabled();
|
||||
});
|
||||
|
||||
it('creates new visualization when clicked on menu item Visualization', () => {
|
||||
setup();
|
||||
|
||||
act(() => {
|
||||
fireEvent.click(screen.getByRole('menuitem', { name: 'Visualization' }));
|
||||
});
|
||||
|
||||
expect(reportInteraction).toHaveBeenCalledWith('dashboards_toolbar_add_clicked', { item: 'add_visualization' });
|
||||
expect(locationService.partial).toHaveBeenCalled();
|
||||
expect(onCreateNewPanel).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('creates new row when clicked on menu item Row', () => {
|
||||
setup();
|
||||
|
||||
act(() => {
|
||||
fireEvent.click(screen.getByRole('menuitem', { name: 'Row' }));
|
||||
});
|
||||
|
||||
expect(reportInteraction).toHaveBeenCalledWith('dashboards_toolbar_add_clicked', { item: 'add_row' });
|
||||
expect(locationService.partial).not.toHaveBeenCalled();
|
||||
expect(onCreateNewRow).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('adds a library panel when clicked on menu item Import from library', () => {
|
||||
setup();
|
||||
|
||||
act(() => {
|
||||
fireEvent.click(screen.getByRole('menuitem', { name: 'Import from library' }));
|
||||
});
|
||||
|
||||
expect(reportInteraction).toHaveBeenCalledWith('dashboards_toolbar_add_clicked', { item: 'import_from_library' });
|
||||
expect(locationService.partial).not.toHaveBeenCalled();
|
||||
expect(onAddLibraryPanel).toHaveBeenCalled();
|
||||
});
|
||||
@@ -16,11 +16,11 @@ import { useDispatch, useSelector } from 'app/types';
|
||||
|
||||
import { setInitialDatasource } from '../../state/reducers';
|
||||
|
||||
interface Props {
|
||||
export interface Props {
|
||||
dashboard: DashboardModel;
|
||||
}
|
||||
|
||||
export const AddPanelMenu = ({ dashboard }: Props) => {
|
||||
const AddPanelMenu = ({ dashboard }: Props) => {
|
||||
const copiedPanelPlugin = useMemo(() => getCopiedPanelPlugin(), []);
|
||||
const dispatch = useDispatch();
|
||||
const initialDatasource = useSelector((state) => state.dashboard.initialDatasource);
|
||||
@@ -29,8 +29,8 @@ export const AddPanelMenu = ({ dashboard }: Props) => {
|
||||
<Menu>
|
||||
<Menu.Item
|
||||
key="add-visualisation"
|
||||
testId={selectors.pages.AddDashboard.itemButton('Add new visualization menu item')}
|
||||
label={t('dashboard.add-menu.visualization', 'Visualization')}
|
||||
testId={selectors.components.PageToolbar.itemButton('Add new visualization menu item')}
|
||||
onClick={() => {
|
||||
const id = onCreateNewPanel(dashboard, initialDatasource);
|
||||
reportInteraction('dashboards_toolbar_add_clicked', { item: 'add_visualization' });
|
||||
@@ -40,8 +40,8 @@ export const AddPanelMenu = ({ dashboard }: Props) => {
|
||||
/>
|
||||
<Menu.Item
|
||||
key="add-row"
|
||||
testId={selectors.pages.AddDashboard.itemButton('Add new row menu item')}
|
||||
label={t('dashboard.add-menu.row', 'Row')}
|
||||
testId={selectors.components.PageToolbar.itemButton('Add new row menu item')}
|
||||
onClick={() => {
|
||||
reportInteraction('dashboards_toolbar_add_clicked', { item: 'add_row' });
|
||||
onCreateNewRow(dashboard);
|
||||
@@ -49,8 +49,8 @@ export const AddPanelMenu = ({ dashboard }: Props) => {
|
||||
/>
|
||||
<Menu.Item
|
||||
key="add-panel-lib"
|
||||
testId={selectors.pages.AddDashboard.itemButton('Add new panel from panel library menu item')}
|
||||
label={t('dashboard.add-menu.import', 'Import from library')}
|
||||
testId={selectors.components.PageToolbar.itemButton('Add new panel from panel library menu item')}
|
||||
onClick={() => {
|
||||
reportInteraction('dashboards_toolbar_add_clicked', { item: 'import_from_library' });
|
||||
onAddLibraryPanel(dashboard);
|
||||
@@ -58,8 +58,8 @@ export const AddPanelMenu = ({ dashboard }: Props) => {
|
||||
/>
|
||||
<Menu.Item
|
||||
key="add-panel-clipboard"
|
||||
testId={selectors.pages.AddDashboard.itemButton('Add new panel from clipboard menu item')}
|
||||
label={t('dashboard.add-menu.paste-panel', 'Paste panel')}
|
||||
testId={selectors.components.PageToolbar.itemButton('Add new panel from clipboard menu item')}
|
||||
onClick={() => {
|
||||
reportInteraction('dashboards_toolbar_add_clicked', { item: 'paste_panel' });
|
||||
onPasteCopiedPanel(dashboard, copiedPanelPlugin);
|
||||
@@ -69,3 +69,5 @@ export const AddPanelMenu = ({ dashboard }: Props) => {
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddPanelMenu;
|
||||
|
||||
Reference in New Issue
Block a user