mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Upgrade @testing-library/user-event
to v14 (#47898)
* Update dependency @testing-library/user-event to v14
* everything is async...
* everything is async pt.2
* Fix cascader tests
* hack the yarn.lock file to remove the old version of @testing-library/dom
* some more fixes!
* MOAR FIXES
* more fixes
* remove a bunch of places where we're wrapping in act()
* down to 7 failing tests...
* Fix arrow tests
* Fix rest of NavBarItem tests
* Fix last tests
* Use {Enter} instead of {enter}
* Revert "Use {Enter} instead of {enter}"
This reverts commit e72453bb52
.
* remove some unused act imports
* Fix LibraryPanelsSearch tests
* more stable test
* More consistent test...
Co-authored-by: Renovate Bot <bot@renovateapp.com>
This commit is contained in:
@@ -113,7 +113,7 @@
|
|||||||
"@testing-library/jest-dom": "5.16.2",
|
"@testing-library/jest-dom": "5.16.2",
|
||||||
"@testing-library/react": "12.1.4",
|
"@testing-library/react": "12.1.4",
|
||||||
"@testing-library/react-hooks": "7.0.2",
|
"@testing-library/react-hooks": "7.0.2",
|
||||||
"@testing-library/user-event": "13.5.0",
|
"@testing-library/user-event": "14.0.0",
|
||||||
"@types/angular": "1.8.4",
|
"@types/angular": "1.8.4",
|
||||||
"@types/angular-route": "1.7.2",
|
"@types/angular-route": "1.7.2",
|
||||||
"@types/classnames": "2.3.0",
|
"@types/classnames": "2.3.0",
|
||||||
|
@@ -51,7 +51,7 @@
|
|||||||
"@testing-library/jest-dom": "5.16.2",
|
"@testing-library/jest-dom": "5.16.2",
|
||||||
"@testing-library/react": "12.1.4",
|
"@testing-library/react": "12.1.4",
|
||||||
"@testing-library/react-hooks": "7.0.2",
|
"@testing-library/react-hooks": "7.0.2",
|
||||||
"@testing-library/user-event": "13.5.0",
|
"@testing-library/user-event": "14.0.0",
|
||||||
"@types/history": "4.7.11",
|
"@types/history": "4.7.11",
|
||||||
"@types/jest": "27.4.1",
|
"@types/jest": "27.4.1",
|
||||||
"@types/jquery": "3.5.14",
|
"@types/jquery": "3.5.14",
|
||||||
|
@@ -40,7 +40,7 @@
|
|||||||
"@rollup/plugin-node-resolve": "13.1.3",
|
"@rollup/plugin-node-resolve": "13.1.3",
|
||||||
"@testing-library/dom": "8.13.0",
|
"@testing-library/dom": "8.13.0",
|
||||||
"@testing-library/react": "12.1.4",
|
"@testing-library/react": "12.1.4",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "14.0.0",
|
||||||
"@types/angular": "1.8.4",
|
"@types/angular": "1.8.4",
|
||||||
"@types/history": "4.7.11",
|
"@types/history": "4.7.11",
|
||||||
"@types/jest": "27.4.1",
|
"@types/jest": "27.4.1",
|
||||||
|
@@ -12,7 +12,7 @@ describe('DataSourcePicker', () => {
|
|||||||
const select = render(<DataSourcePicker onClear={onClear} />);
|
const select = render(<DataSourcePicker onClear={onClear} />);
|
||||||
|
|
||||||
const clearButton = select.getByLabelText('select-clear-value');
|
const clearButton = select.getByLabelText('select-clear-value');
|
||||||
userEvent.click(clearButton);
|
await userEvent.click(clearButton);
|
||||||
expect(onClear).toHaveBeenCalled();
|
expect(onClear).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -118,7 +118,7 @@
|
|||||||
"@testing-library/jest-dom": "5.16.2",
|
"@testing-library/jest-dom": "5.16.2",
|
||||||
"@testing-library/react": "12.1.4",
|
"@testing-library/react": "12.1.4",
|
||||||
"@testing-library/react-hooks": "7.0.2",
|
"@testing-library/react-hooks": "7.0.2",
|
||||||
"@testing-library/user-event": "13.5.0",
|
"@testing-library/user-event": "14.0.0",
|
||||||
"@types/classnames": "2.3.0",
|
"@types/classnames": "2.3.0",
|
||||||
"@types/common-tags": "^1.8.0",
|
"@types/common-tags": "^1.8.0",
|
||||||
"@types/d3": "7.1.0",
|
"@types/d3": "7.1.0",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Cascader, CascaderOption, CascaderProps } from './Cascader';
|
import { Cascader, CascaderOption, CascaderProps } from './Cascader';
|
||||||
import { act, render, screen } from '@testing-library/react';
|
import { act, render, screen } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event';
|
||||||
|
import { UserEvent } from '@testing-library/user-event/dist/types/setup';
|
||||||
|
|
||||||
const options = [
|
const options = [
|
||||||
{
|
{
|
||||||
@@ -45,78 +46,86 @@ describe('Cascader', () => {
|
|||||||
const placeholder = 'cascader-placeholder';
|
const placeholder = 'cascader-placeholder';
|
||||||
|
|
||||||
describe('options from state change', () => {
|
describe('options from state change', () => {
|
||||||
|
let user: UserEvent;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.useFakeTimers('modern');
|
jest.useFakeTimers('modern');
|
||||||
|
// 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 });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays updated options', () => {
|
afterEach(() => {
|
||||||
|
jest.useRealTimers();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('displays updated options', async () => {
|
||||||
render(<CascaderWithOptionsStateUpdate placeholder={placeholder} onSelect={jest.fn()} />);
|
render(<CascaderWithOptionsStateUpdate placeholder={placeholder} onSelect={jest.fn()} />);
|
||||||
|
|
||||||
act(() => {
|
await user.click(screen.getByPlaceholderText(placeholder));
|
||||||
userEvent.click(screen.getByPlaceholderText(placeholder));
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(screen.getByText('Initial state option')).toBeInTheDocument();
|
expect(screen.getByText('Initial state option')).toBeInTheDocument();
|
||||||
expect(screen.queryByText('First')).not.toBeInTheDocument();
|
expect(screen.queryByText('First')).not.toBeInTheDocument();
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
userEvent.click(screen.getByPlaceholderText(placeholder));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await user.click(screen.getByPlaceholderText(placeholder));
|
||||||
|
|
||||||
expect(screen.queryByText('Initial state option')).not.toBeInTheDocument();
|
expect(screen.queryByText('Initial state option')).not.toBeInTheDocument();
|
||||||
expect(screen.getByText('First')).toBeInTheDocument();
|
expect(screen.getByText('First')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('filters updated results when searching', () => {
|
it('filters updated results when searching', async () => {
|
||||||
render(<CascaderWithOptionsStateUpdate placeholder={placeholder} onSelect={jest.fn()} />);
|
render(<CascaderWithOptionsStateUpdate placeholder={placeholder} onSelect={jest.fn()} />);
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
userEvent.type(screen.getByPlaceholderText(placeholder), 'Third');
|
await user.type(screen.getByPlaceholderText(placeholder), 'Third');
|
||||||
expect(screen.queryByText('Second')).not.toBeInTheDocument();
|
expect(screen.queryByText('Second')).not.toBeInTheDocument();
|
||||||
expect(screen.getByText('First / Third')).toBeInTheDocument();
|
expect(screen.getByText('First / Third')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('filters results when searching', () => {
|
it('filters results when searching', async () => {
|
||||||
render(<Cascader placeholder={placeholder} options={options} onSelect={jest.fn()} />);
|
render(<Cascader placeholder={placeholder} options={options} onSelect={jest.fn()} />);
|
||||||
|
|
||||||
userEvent.type(screen.getByPlaceholderText(placeholder), 'Third');
|
await userEvent.type(screen.getByPlaceholderText(placeholder), 'Third');
|
||||||
|
|
||||||
expect(screen.queryByText('Second')).not.toBeInTheDocument();
|
expect(screen.queryByText('Second')).not.toBeInTheDocument();
|
||||||
expect(screen.getByText('First / Third')).toBeInTheDocument();
|
expect(screen.getByText('First / Third')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays selected value with all levels when displayAllSelectedLevels is true and selecting a value from the search', () => {
|
it('displays selected value with all levels when displayAllSelectedLevels is true and selecting a value from the search', async () => {
|
||||||
render(
|
render(
|
||||||
<Cascader displayAllSelectedLevels={true} placeholder={placeholder} options={options} onSelect={jest.fn()} />
|
<Cascader displayAllSelectedLevels={true} placeholder={placeholder} options={options} onSelect={jest.fn()} />
|
||||||
);
|
);
|
||||||
|
|
||||||
userEvent.type(screen.getByPlaceholderText(placeholder), 'Third');
|
await userEvent.type(screen.getByPlaceholderText(placeholder), 'Third');
|
||||||
userEvent.click(screen.getByText('First / Third'));
|
await userEvent.click(screen.getByText('First / Third'));
|
||||||
|
|
||||||
expect(screen.getByDisplayValue('First / Third')).toBeInTheDocument();
|
expect(screen.getByDisplayValue('First / Third')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays all levels selected with default separator when displayAllSelectedLevels is true', () => {
|
it('displays all levels selected with default separator when displayAllSelectedLevels is true', async () => {
|
||||||
render(
|
render(
|
||||||
<Cascader displayAllSelectedLevels={true} placeholder={placeholder} options={options} onSelect={() => {}} />
|
<Cascader displayAllSelectedLevels={true} placeholder={placeholder} options={options} onSelect={() => {}} />
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(screen.queryByDisplayValue('First/Second')).not.toBeInTheDocument();
|
expect(screen.queryByDisplayValue('First/Second')).not.toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getByPlaceholderText(placeholder));
|
await userEvent.click(screen.getByPlaceholderText(placeholder));
|
||||||
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
||||||
userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true });
|
await userEvent.click(screen.getByText('First'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
|
||||||
userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true });
|
await userEvent.click(screen.getByText('Second'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
|
||||||
|
|
||||||
expect(screen.getByDisplayValue('First/Second')).toBeInTheDocument();
|
expect(screen.getByDisplayValue('First/Second')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays all levels selected with separator passed in when displayAllSelectedLevels is true', () => {
|
it('displays all levels selected with separator passed in when displayAllSelectedLevels is true', async () => {
|
||||||
const separator = ',';
|
const separator = ',';
|
||||||
|
|
||||||
render(
|
render(
|
||||||
@@ -131,34 +140,34 @@ describe('Cascader', () => {
|
|||||||
|
|
||||||
expect(screen.queryByDisplayValue('First/Second')).not.toBeInTheDocument();
|
expect(screen.queryByDisplayValue('First/Second')).not.toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getByPlaceholderText(placeholder));
|
await userEvent.click(screen.getByPlaceholderText(placeholder));
|
||||||
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
||||||
userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true });
|
await userEvent.click(screen.getByText('First'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
|
||||||
userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true });
|
await userEvent.click(screen.getByText('Second'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
|
||||||
|
|
||||||
expect(screen.getByDisplayValue(`First${separator}Second`)).toBeInTheDocument();
|
expect(screen.getByDisplayValue(`First${separator}Second`)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays last level selected when displayAllSelectedLevels is false', () => {
|
it('displays last level selected when displayAllSelectedLevels is false', async () => {
|
||||||
render(
|
render(
|
||||||
<Cascader displayAllSelectedLevels={false} placeholder={placeholder} options={options} onSelect={jest.fn()} />
|
<Cascader displayAllSelectedLevels={false} placeholder={placeholder} options={options} onSelect={jest.fn()} />
|
||||||
);
|
);
|
||||||
|
|
||||||
userEvent.click(screen.getByPlaceholderText(placeholder));
|
await userEvent.click(screen.getByPlaceholderText(placeholder));
|
||||||
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
||||||
userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true });
|
await userEvent.click(screen.getByText('First'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
|
||||||
userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true });
|
await userEvent.click(screen.getByText('Second'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
|
||||||
|
|
||||||
expect(screen.getByDisplayValue('Second')).toBeInTheDocument();
|
expect(screen.getByDisplayValue('Second')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays last level selected when displayAllSelectedLevels is not passed in', () => {
|
it('displays last level selected when displayAllSelectedLevels is not passed in', async () => {
|
||||||
render(<Cascader placeholder={placeholder} options={options} onSelect={jest.fn()} />);
|
render(<Cascader placeholder={placeholder} options={options} onSelect={jest.fn()} />);
|
||||||
|
|
||||||
userEvent.click(screen.getByPlaceholderText(placeholder));
|
await userEvent.click(screen.getByPlaceholderText(placeholder));
|
||||||
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
||||||
userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true });
|
await userEvent.click(screen.getByText('First'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
|
||||||
userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true });
|
await userEvent.click(screen.getByText('Second'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
|
||||||
|
|
||||||
expect(screen.getByDisplayValue('Second')).toBeInTheDocument();
|
expect(screen.getByDisplayValue('Second')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act, render, screen } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
import { ColorPickerPopover } from './ColorPickerPopover';
|
import { ColorPickerPopover } from './ColorPickerPopover';
|
||||||
import { createTheme } from '@grafana/data';
|
import { createTheme } from '@grafana/data';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
@@ -7,24 +7,20 @@ import userEvent from '@testing-library/user-event';
|
|||||||
describe('ColorPickerPopover', () => {
|
describe('ColorPickerPopover', () => {
|
||||||
const theme = createTheme();
|
const theme = createTheme();
|
||||||
|
|
||||||
it('should be tabbable', () => {
|
it('should be tabbable', async () => {
|
||||||
render(<ColorPickerPopover color={'red'} onChange={() => {}} />);
|
render(<ColorPickerPopover color={'red'} onChange={() => {}} />);
|
||||||
const color = screen.getByRole('button', { name: 'dark-red color' });
|
const color = screen.getByRole('button', { name: 'dark-red color' });
|
||||||
const customTab = screen.getByRole('button', { name: 'Custom' });
|
const customTab = screen.getByRole('button', { name: 'Custom' });
|
||||||
|
|
||||||
act(() => {
|
await userEvent.tab();
|
||||||
userEvent.tab();
|
|
||||||
});
|
|
||||||
expect(customTab).toHaveFocus();
|
expect(customTab).toHaveFocus();
|
||||||
|
|
||||||
act(() => {
|
await userEvent.tab();
|
||||||
userEvent.tab();
|
|
||||||
});
|
|
||||||
expect(color).toHaveFocus();
|
expect(color).toHaveFocus();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('rendering', () => {
|
describe('rendering', () => {
|
||||||
it('should render provided color as selected if color provided by name', () => {
|
it('should render provided color as selected if color provided by name', async () => {
|
||||||
render(<ColorPickerPopover color={'green'} onChange={() => {}} />);
|
render(<ColorPickerPopover color={'green'} onChange={() => {}} />);
|
||||||
const color = screen.getByRole('button', { name: 'green color' });
|
const color = screen.getByRole('button', { name: 'green color' });
|
||||||
const colorSwatchWrapper = screen.getAllByTestId('data-testid-colorswatch');
|
const colorSwatchWrapper = screen.getAllByTestId('data-testid-colorswatch');
|
||||||
@@ -32,9 +28,7 @@ describe('ColorPickerPopover', () => {
|
|||||||
expect(color).toBeInTheDocument();
|
expect(color).toBeInTheDocument();
|
||||||
expect(colorSwatchWrapper[0]).toBeInTheDocument();
|
expect(colorSwatchWrapper[0]).toBeInTheDocument();
|
||||||
|
|
||||||
act(() => {
|
await userEvent.click(colorSwatchWrapper[0]);
|
||||||
userEvent.click(colorSwatchWrapper[0]);
|
|
||||||
});
|
|
||||||
expect(color).toHaveStyle('box-shadow: inset 0 0 0 2px #73BF69,inset 0 0 0 4px #000000');
|
expect(color).toHaveStyle('box-shadow: inset 0 0 0 2px #73BF69,inset 0 0 0 4px #000000');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -42,23 +36,19 @@ describe('ColorPickerPopover', () => {
|
|||||||
describe('named colors support', () => {
|
describe('named colors support', () => {
|
||||||
const onChangeSpy = jest.fn();
|
const onChangeSpy = jest.fn();
|
||||||
|
|
||||||
it('should pass hex color value to onChange prop by default', () => {
|
it('should pass hex color value to onChange prop by default', async () => {
|
||||||
render(<ColorPickerPopover color={'red'} onChange={onChangeSpy} />);
|
render(<ColorPickerPopover color={'red'} onChange={onChangeSpy} />);
|
||||||
const color = screen.getByRole('button', { name: 'red color' });
|
const color = screen.getByRole('button', { name: 'red color' });
|
||||||
act(() => {
|
await userEvent.click(color);
|
||||||
userEvent.click(color);
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(onChangeSpy).toBeCalledTimes(1);
|
expect(onChangeSpy).toBeCalledTimes(1);
|
||||||
expect(onChangeSpy).toBeCalledWith(theme.visualization.getColorByName('red'));
|
expect(onChangeSpy).toBeCalledWith(theme.visualization.getColorByName('red'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should pass color name to onChange prop when named colors enabled', () => {
|
it('should pass color name to onChange prop when named colors enabled', async () => {
|
||||||
render(<ColorPickerPopover color={'red'} enableNamedColors onChange={onChangeSpy} />);
|
render(<ColorPickerPopover color={'red'} enableNamedColors onChange={onChangeSpy} />);
|
||||||
const color = screen.getByRole('button', { name: 'red color' });
|
const color = screen.getByRole('button', { name: 'red color' });
|
||||||
act(() => {
|
await userEvent.click(color);
|
||||||
userEvent.click(color);
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(onChangeSpy).toBeCalledTimes(2);
|
expect(onChangeSpy).toBeCalledTimes(2);
|
||||||
expect(onChangeSpy).toBeCalledWith(theme.visualization.getColorByName('red'));
|
expect(onChangeSpy).toBeCalledWith(theme.visualization.getColorByName('red'));
|
||||||
|
@@ -6,7 +6,7 @@ import { ConfirmButton } from './ConfirmButton';
|
|||||||
import { expect } from '../../../../../public/test/lib/common';
|
import { expect } from '../../../../../public/test/lib/common';
|
||||||
|
|
||||||
describe('ConfirmButton', () => {
|
describe('ConfirmButton', () => {
|
||||||
it('should show confirm delete when clicked', () => {
|
it('should show confirm delete when clicked', async () => {
|
||||||
const onConfirm = jest.fn();
|
const onConfirm = jest.fn();
|
||||||
render(
|
render(
|
||||||
<ConfirmButton confirmText="Confirm delete" onConfirm={onConfirm}>
|
<ConfirmButton confirmText="Confirm delete" onConfirm={onConfirm}>
|
||||||
@@ -17,18 +17,18 @@ describe('ConfirmButton', () => {
|
|||||||
// Confirm button should not be visible before clicking the Delete button
|
// Confirm button should not be visible before clicking the Delete button
|
||||||
expect(screen.queryByRole('button', { name: 'Confirm delete' })).not.toBeInTheDocument();
|
expect(screen.queryByRole('button', { name: 'Confirm delete' })).not.toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: 'Delete' }));
|
await userEvent.click(screen.getByRole('button', { name: 'Delete' }));
|
||||||
|
|
||||||
// Confirm button should now be visible
|
// Confirm button should now be visible
|
||||||
expect(screen.getByRole('button', { name: 'Confirm delete' })).toBeInTheDocument();
|
expect(screen.getByRole('button', { name: 'Confirm delete' })).toBeInTheDocument();
|
||||||
userEvent.click(screen.getByRole('button', { name: 'Confirm delete' }));
|
await userEvent.click(screen.getByRole('button', { name: 'Confirm delete' }));
|
||||||
expect(onConfirm).toHaveBeenCalled();
|
expect(onConfirm).toHaveBeenCalled();
|
||||||
|
|
||||||
// Confirm button should be visible if closeOnConfirm is false
|
// Confirm button should be visible if closeOnConfirm is false
|
||||||
expect(screen.queryByRole('button', { name: 'Confirm delete' })).toBeInTheDocument();
|
expect(screen.queryByRole('button', { name: 'Confirm delete' })).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should hide confirm delete when closeOnConfirm is true', () => {
|
it('should hide confirm delete when closeOnConfirm is true', async () => {
|
||||||
render(
|
render(
|
||||||
<ConfirmButton confirmText="Confirm delete" onConfirm={() => {}} closeOnConfirm={true}>
|
<ConfirmButton confirmText="Confirm delete" onConfirm={() => {}} closeOnConfirm={true}>
|
||||||
Delete
|
Delete
|
||||||
@@ -38,17 +38,17 @@ describe('ConfirmButton', () => {
|
|||||||
// Confirm button should not be visible before clicking the Delete button
|
// Confirm button should not be visible before clicking the Delete button
|
||||||
expect(screen.queryByRole('button', { name: 'Confirm delete' })).not.toBeInTheDocument();
|
expect(screen.queryByRole('button', { name: 'Confirm delete' })).not.toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: 'Delete' }));
|
await userEvent.click(screen.getByRole('button', { name: 'Delete' }));
|
||||||
|
|
||||||
// Confirm button should now be visible
|
// Confirm button should now be visible
|
||||||
expect(screen.getByRole('button', { name: 'Confirm delete' })).toBeInTheDocument();
|
expect(screen.getByRole('button', { name: 'Confirm delete' })).toBeInTheDocument();
|
||||||
userEvent.click(screen.getByRole('button', { name: 'Confirm delete' }));
|
await userEvent.click(screen.getByRole('button', { name: 'Confirm delete' }));
|
||||||
|
|
||||||
// Confirm button should not be visible if closeOnConfirm is true
|
// Confirm button should not be visible if closeOnConfirm is true
|
||||||
expect(screen.queryByRole('button', { name: 'Confirm delete' })).not.toBeInTheDocument();
|
expect(screen.queryByRole('button', { name: 'Confirm delete' })).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show cancel when clicked', () => {
|
it('should show cancel when clicked', async () => {
|
||||||
const onCancel = jest.fn();
|
const onCancel = jest.fn();
|
||||||
render(
|
render(
|
||||||
<ConfirmButton confirmText="Confirm delete" onCancel={onCancel} onConfirm={() => {}}>
|
<ConfirmButton confirmText="Confirm delete" onCancel={onCancel} onConfirm={() => {}}>
|
||||||
@@ -59,11 +59,11 @@ describe('ConfirmButton', () => {
|
|||||||
// Cancel button should not be visible before clicking the Delete button
|
// Cancel button should not be visible before clicking the Delete button
|
||||||
expect(screen.queryByRole('button', { name: 'Cancel' })).not.toBeInTheDocument();
|
expect(screen.queryByRole('button', { name: 'Cancel' })).not.toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: 'Delete' }));
|
await userEvent.click(screen.getByRole('button', { name: 'Delete' }));
|
||||||
|
|
||||||
// Cancel button should now be visible
|
// Cancel button should now be visible
|
||||||
expect(screen.getByRole('button', { name: 'Cancel' })).toBeInTheDocument();
|
expect(screen.getByRole('button', { name: 'Cancel' })).toBeInTheDocument();
|
||||||
userEvent.click(screen.getByRole('button', { name: 'Cancel' }));
|
await userEvent.click(screen.getByRole('button', { name: 'Cancel' }));
|
||||||
expect(onCancel).toHaveBeenCalled();
|
expect(onCancel).toHaveBeenCalled();
|
||||||
|
|
||||||
// Cancel button should not be visible after click
|
// Cancel button should not be visible after click
|
||||||
|
@@ -54,13 +54,13 @@ function assertRowCount(configuredInputCount: number, passwordInputCount: number
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('Render', () => {
|
describe('Render', () => {
|
||||||
it('should add a new header', () => {
|
it('should add a new header', async () => {
|
||||||
setup();
|
setup();
|
||||||
const b = screen.getByRole('button', { name: 'Add header' });
|
const b = screen.getByRole('button', { name: 'Add header' });
|
||||||
expect(b).toBeInTheDocument();
|
expect(b).toBeInTheDocument();
|
||||||
assertRowCount(0, 0);
|
assertRowCount(0, 0);
|
||||||
|
|
||||||
userEvent.click(b);
|
await userEvent.click(b);
|
||||||
assertRowCount(0, 1);
|
assertRowCount(0, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ describe('Render', () => {
|
|||||||
expect(b.getAttribute('type')).toBe('button');
|
expect(b.getAttribute('type')).toBe('button');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove a header', () => {
|
it('should remove a header', async () => {
|
||||||
const { onChange } = setup({
|
const { onChange } = setup({
|
||||||
dataSourceConfig: {
|
dataSourceConfig: {
|
||||||
jsonData: {
|
jsonData: {
|
||||||
@@ -87,14 +87,14 @@ describe('Render', () => {
|
|||||||
|
|
||||||
assertRowCount(1, 0);
|
assertRowCount(1, 0);
|
||||||
|
|
||||||
userEvent.click(b);
|
await userEvent.click(b);
|
||||||
assertRowCount(0, 0);
|
assertRowCount(0, 0);
|
||||||
|
|
||||||
expect(onChange).toHaveBeenCalledTimes(1);
|
expect(onChange).toHaveBeenCalledTimes(1);
|
||||||
expect(onChange.mock.calls[0][0].jsonData).toStrictEqual({});
|
expect(onChange.mock.calls[0][0].jsonData).toStrictEqual({});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('when removing a just-created header, it should clean up secureJsonData', () => {
|
it('when removing a just-created header, it should clean up secureJsonData', async () => {
|
||||||
const { onChange } = setup({
|
const { onChange } = setup({
|
||||||
dataSourceConfig: {
|
dataSourceConfig: {
|
||||||
jsonData: {
|
jsonData: {
|
||||||
@@ -109,7 +109,7 @@ describe('Render', () => {
|
|||||||
// we remove the row
|
// we remove the row
|
||||||
const removeButton = screen.getByRole('button', { name: 'Remove header' });
|
const removeButton = screen.getByRole('button', { name: 'Remove header' });
|
||||||
expect(removeButton).toBeInTheDocument();
|
expect(removeButton).toBeInTheDocument();
|
||||||
userEvent.click(removeButton);
|
await userEvent.click(removeButton);
|
||||||
assertRowCount(0, 0);
|
assertRowCount(0, 0);
|
||||||
expect(onChange).toHaveBeenCalled();
|
expect(onChange).toHaveBeenCalled();
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ describe('Render', () => {
|
|||||||
expect(lastCall[0].secureJsonData).not.toHaveProperty('httpHeaderValue1');
|
expect(lastCall[0].secureJsonData).not.toHaveProperty('httpHeaderValue1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reset a header', () => {
|
it('should reset a header', async () => {
|
||||||
setup({
|
setup({
|
||||||
dataSourceConfig: {
|
dataSourceConfig: {
|
||||||
jsonData: {
|
jsonData: {
|
||||||
@@ -135,7 +135,7 @@ describe('Render', () => {
|
|||||||
expect(b).toBeInTheDocument();
|
expect(b).toBeInTheDocument();
|
||||||
|
|
||||||
assertRowCount(1, 0);
|
assertRowCount(1, 0);
|
||||||
userEvent.click(b);
|
await userEvent.click(b);
|
||||||
assertRowCount(0, 1);
|
assertRowCount(0, 1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -33,7 +33,7 @@ describe('<SecretInput />', () => {
|
|||||||
expect(screen.queryByRole('button', { name: RESET_BUTTON_TEXT })).toBeInTheDocument();
|
expect(screen.queryByRole('button', { name: RESET_BUTTON_TEXT })).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be possible to reset a configured secret', () => {
|
it('should be possible to reset a configured secret', async () => {
|
||||||
const onReset = jest.fn();
|
const onReset = jest.fn();
|
||||||
|
|
||||||
render(<SecretInput isConfigured={true} onChange={() => {}} onReset={onReset} placeholder={PLACEHOLDER_TEXT} />);
|
render(<SecretInput isConfigured={true} onChange={() => {}} onReset={onReset} placeholder={PLACEHOLDER_TEXT} />);
|
||||||
@@ -43,12 +43,12 @@ describe('<SecretInput />', () => {
|
|||||||
expect(screen.queryByRole('button', { name: RESET_BUTTON_TEXT })).toBeInTheDocument();
|
expect(screen.queryByRole('button', { name: RESET_BUTTON_TEXT })).toBeInTheDocument();
|
||||||
|
|
||||||
// Click on "Reset"
|
// Click on "Reset"
|
||||||
userEvent.click(screen.getByRole('button', { name: RESET_BUTTON_TEXT }));
|
await userEvent.click(screen.getByRole('button', { name: RESET_BUTTON_TEXT }));
|
||||||
|
|
||||||
expect(onReset).toHaveBeenCalledTimes(1);
|
expect(onReset).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be possible to change the value of the secret', () => {
|
it('should be possible to change the value of the secret', async () => {
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
|
|
||||||
render(<SecretInput isConfigured={false} onChange={onChange} onReset={() => {}} placeholder={PLACEHOLDER_TEXT} />);
|
render(<SecretInput isConfigured={false} onChange={onChange} onReset={() => {}} placeholder={PLACEHOLDER_TEXT} />);
|
||||||
@@ -57,7 +57,7 @@ describe('<SecretInput />', () => {
|
|||||||
|
|
||||||
expect(input).toHaveValue('');
|
expect(input).toHaveValue('');
|
||||||
|
|
||||||
userEvent.type(input, 'Foo');
|
await userEvent.type(input, 'Foo');
|
||||||
|
|
||||||
expect(onChange).toHaveBeenCalled();
|
expect(onChange).toHaveBeenCalled();
|
||||||
expect(input).toHaveValue('Foo');
|
expect(input).toHaveValue('Foo');
|
||||||
|
@@ -22,9 +22,9 @@ describe('SelectBase', () => {
|
|||||||
render(<SelectBase menuShouldPortal onChange={onChangeHandler} />);
|
render(<SelectBase menuShouldPortal onChange={onChangeHandler} />);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders empty options information', () => {
|
it('renders empty options information', async () => {
|
||||||
render(<SelectBase menuShouldPortal onChange={onChangeHandler} />);
|
render(<SelectBase menuShouldPortal onChange={onChangeHandler} />);
|
||||||
userEvent.click(screen.getByText(/choose/i));
|
await userEvent.click(screen.getByText(/choose/i));
|
||||||
expect(screen.queryByText(/no options found/i)).toBeVisible();
|
expect(screen.queryByText(/no options found/i)).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ describe('SelectBase', () => {
|
|||||||
|
|
||||||
render(<Test />);
|
render(<Test />);
|
||||||
expect(screen.queryByText('Test label')).toBeInTheDocument();
|
expect(screen.queryByText('Test label')).toBeInTheDocument();
|
||||||
userEvent.click(screen.getByText('clear value'));
|
await userEvent.click(screen.getByText('clear value'));
|
||||||
expect(screen.queryByText('Test label')).not.toBeInTheDocument();
|
expect(screen.queryByText('Test label')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -186,9 +186,9 @@ describe('SelectBase', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('options', () => {
|
describe('options', () => {
|
||||||
it('renders menu with provided options', () => {
|
it('renders menu with provided options', async () => {
|
||||||
render(<SelectBase menuShouldPortal options={options} onChange={onChangeHandler} />);
|
render(<SelectBase menuShouldPortal options={options} onChange={onChangeHandler} />);
|
||||||
userEvent.click(screen.getByText(/choose/i));
|
await userEvent.click(screen.getByText(/choose/i));
|
||||||
const menuOptions = screen.getAllByLabelText('Select option');
|
const menuOptions = screen.getAllByLabelText('Select option');
|
||||||
expect(menuOptions).toHaveLength(2);
|
expect(menuOptions).toHaveLength(2);
|
||||||
});
|
});
|
||||||
|
@@ -159,11 +159,11 @@ describe('Table', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('when sorting with column header', () => {
|
describe('when sorting with column header', () => {
|
||||||
it('then correct rows should be rendered', () => {
|
it('then correct rows should be rendered', async () => {
|
||||||
getTestContext();
|
getTestContext();
|
||||||
|
|
||||||
userEvent.click(within(getColumnHeader(/temperature/)).getByText(/temperature/i));
|
await userEvent.click(within(getColumnHeader(/temperature/)).getByText(/temperature/i));
|
||||||
userEvent.click(within(getColumnHeader(/temperature/)).getByText(/temperature/i));
|
await userEvent.click(within(getColumnHeader(/temperature/)).getByText(/temperature/i));
|
||||||
|
|
||||||
const rows = within(getTable()).getAllByRole('row');
|
const rows = within(getTable()).getAllByRole('row');
|
||||||
expect(rows).toHaveLength(5);
|
expect(rows).toHaveLength(5);
|
||||||
|
@@ -48,11 +48,11 @@ describe('ChangePassword Page', () => {
|
|||||||
expect(await screen.findByText('New Password is required')).toBeInTheDocument();
|
expect(await screen.findByText('New Password is required')).toBeInTheDocument();
|
||||||
expect(screen.getByText('Confirmed Password is required')).toBeInTheDocument();
|
expect(screen.getByText('Confirmed Password is required')).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.type(screen.getByLabelText('New password'), 'admin');
|
await userEvent.type(screen.getByLabelText('New password'), 'admin');
|
||||||
userEvent.type(screen.getByLabelText('Confirm new password'), 'a');
|
await userEvent.type(screen.getByLabelText('Confirm new password'), 'a');
|
||||||
await waitFor(() => expect(screen.getByText('Passwords must match!')).toBeInTheDocument());
|
await waitFor(() => expect(screen.getByText('Passwords must match!')).toBeInTheDocument());
|
||||||
|
|
||||||
userEvent.type(screen.getByLabelText('Confirm new password'), 'dmin');
|
await userEvent.type(screen.getByLabelText('Confirm new password'), 'dmin');
|
||||||
await waitFor(() => expect(screen.queryByText('Passwords must match!')).not.toBeInTheDocument());
|
await waitFor(() => expect(screen.queryByText('Passwords must match!')).not.toBeInTheDocument());
|
||||||
});
|
});
|
||||||
it('should navigate to default url if change password is successful', async () => {
|
it('should navigate to default url if change password is successful', async () => {
|
||||||
@@ -64,8 +64,8 @@ describe('ChangePassword Page', () => {
|
|||||||
postMock.mockResolvedValueOnce({ message: 'Logged in' });
|
postMock.mockResolvedValueOnce({ message: 'Logged in' });
|
||||||
render(<ChangePasswordPage {...props} />);
|
render(<ChangePasswordPage {...props} />);
|
||||||
|
|
||||||
userEvent.type(screen.getByLabelText('New password'), 'test');
|
await userEvent.type(screen.getByLabelText('New password'), 'test');
|
||||||
userEvent.type(screen.getByLabelText('Confirm new password'), 'test');
|
await userEvent.type(screen.getByLabelText('Confirm new password'), 'test');
|
||||||
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
|
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
|
||||||
await waitFor(() =>
|
await waitFor(() =>
|
||||||
expect(postMock).toHaveBeenCalledWith('/api/user/password/reset', {
|
expect(postMock).toHaveBeenCalledWith('/api/user/password/reset', {
|
||||||
|
@@ -41,14 +41,14 @@ describe('VerifyEmail Page', () => {
|
|||||||
fireEvent.click(screen.getByRole('button', { name: 'Send reset email' }));
|
fireEvent.click(screen.getByRole('button', { name: 'Send reset email' }));
|
||||||
expect(await screen.findByText('Email or username is required')).toBeInTheDocument();
|
expect(await screen.findByText('Email or username is required')).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.type(screen.getByRole('textbox', { name: /User Enter your information/i }), 'test@gmail.com');
|
await userEvent.type(screen.getByRole('textbox', { name: /User Enter your information/i }), 'test@gmail.com');
|
||||||
await waitFor(() => expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument());
|
await waitFor(() => expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument());
|
||||||
});
|
});
|
||||||
it('should show success meessage if reset-password is successful', async () => {
|
it('should show success meessage if reset-password is successful', async () => {
|
||||||
postMock.mockResolvedValueOnce({ message: 'Email sent' });
|
postMock.mockResolvedValueOnce({ message: 'Email sent' });
|
||||||
render(<SendResetMailPage />);
|
render(<SendResetMailPage />);
|
||||||
|
|
||||||
userEvent.type(screen.getByRole('textbox', { name: /User Enter your information/i }), 'test@gmail.com');
|
await userEvent.type(screen.getByRole('textbox', { name: /User Enter your information/i }), 'test@gmail.com');
|
||||||
fireEvent.click(screen.getByRole('button', { name: 'Send reset email' }));
|
fireEvent.click(screen.getByRole('button', { name: 'Send reset email' }));
|
||||||
await waitFor(() =>
|
await waitFor(() =>
|
||||||
expect(postMock).toHaveBeenCalledWith('/api/user/password/send-reset-email', {
|
expect(postMock).toHaveBeenCalledWith('/api/user/password/send-reset-email', {
|
||||||
|
@@ -56,7 +56,7 @@ describe('Login Page', () => {
|
|||||||
fireEvent.click(screen.getByRole('button', { name: 'Login button' }));
|
fireEvent.click(screen.getByRole('button', { name: 'Login button' }));
|
||||||
expect(await screen.findByText('Email or username is required')).toBeInTheDocument();
|
expect(await screen.findByText('Email or username is required')).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.type(screen.getByRole('textbox', { name: 'Username input field' }), 'admin');
|
await userEvent.type(screen.getByRole('textbox', { name: 'Username input field' }), 'admin');
|
||||||
await waitFor(() => expect(screen.queryByText('Email or username is required')).not.toBeInTheDocument());
|
await waitFor(() => expect(screen.queryByText('Email or username is required')).not.toBeInTheDocument());
|
||||||
});
|
});
|
||||||
it('should pass validation checks for password field', async () => {
|
it('should pass validation checks for password field', async () => {
|
||||||
@@ -65,7 +65,7 @@ describe('Login Page', () => {
|
|||||||
fireEvent.click(screen.getByRole('button', { name: 'Login button' }));
|
fireEvent.click(screen.getByRole('button', { name: 'Login button' }));
|
||||||
expect(await screen.findByText('Password is required')).toBeInTheDocument();
|
expect(await screen.findByText('Password is required')).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.type(screen.getByLabelText('Password input field'), 'admin');
|
await userEvent.type(screen.getByLabelText('Password input field'), 'admin');
|
||||||
await waitFor(() => expect(screen.queryByText('Password is required')).not.toBeInTheDocument());
|
await waitFor(() => expect(screen.queryByText('Password is required')).not.toBeInTheDocument());
|
||||||
});
|
});
|
||||||
it('should navigate to default url if credentials is valid', async () => {
|
it('should navigate to default url if credentials is valid', async () => {
|
||||||
@@ -77,8 +77,8 @@ describe('Login Page', () => {
|
|||||||
postMock.mockResolvedValueOnce({ message: 'Logged in' });
|
postMock.mockResolvedValueOnce({ message: 'Logged in' });
|
||||||
render(<LoginPage />);
|
render(<LoginPage />);
|
||||||
|
|
||||||
userEvent.type(screen.getByLabelText('Username input field'), 'admin');
|
await userEvent.type(screen.getByLabelText('Username input field'), 'admin');
|
||||||
userEvent.type(screen.getByLabelText('Password input field'), 'test');
|
await userEvent.type(screen.getByLabelText('Password input field'), 'test');
|
||||||
fireEvent.click(screen.getByLabelText('Login button'));
|
fireEvent.click(screen.getByLabelText('Login button'));
|
||||||
|
|
||||||
await waitFor(() => expect(postMock).toHaveBeenCalledWith('/login', { password: 'test', user: 'admin' }));
|
await waitFor(() => expect(postMock).toHaveBeenCalledWith('/login', { password: 'test', user: 'admin' }));
|
||||||
|
@@ -1,11 +1,21 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act, render, screen, waitFor } from '@testing-library/react';
|
import { render, screen, waitFor } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { BrowserRouter } from 'react-router-dom';
|
import { BrowserRouter } from 'react-router-dom';
|
||||||
import { locationUtil } from '@grafana/data';
|
import { locationUtil } from '@grafana/data';
|
||||||
import { config, setLocationService } from '@grafana/runtime';
|
import { config, setLocationService } from '@grafana/runtime';
|
||||||
import TestProvider from '../../../../test/helpers/TestProvider';
|
import TestProvider from '../../../../test/helpers/TestProvider';
|
||||||
|
|
||||||
|
// Need to mock createBrowserHistory here to avoid errors
|
||||||
|
jest.mock('history', () => ({
|
||||||
|
...jest.requireActual('history'),
|
||||||
|
createBrowserHistory: () => ({
|
||||||
|
listen: jest.fn(),
|
||||||
|
location: {},
|
||||||
|
createHref: jest.fn(),
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
import NavBarItem, { Props } from './NavBarItem';
|
import NavBarItem, { Props } from './NavBarItem';
|
||||||
|
|
||||||
const onClickMock = jest.fn();
|
const onClickMock = jest.fn();
|
||||||
@@ -21,7 +31,7 @@ const defaults: Props = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function getTestContext(overrides: Partial<Props> = {}, subUrl = '') {
|
async function getTestContext(overrides: Partial<Props> = {}, subUrl = '') {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
config.appSubUrl = subUrl;
|
config.appSubUrl = subUrl;
|
||||||
locationUtil.initialize({ config, getTimeRangeForUrl: jest.fn(), getVariablesUrlParams: jest.fn() });
|
locationUtil.initialize({ config, getTimeRangeForUrl: jest.fn(), getVariablesUrlParams: jest.fn() });
|
||||||
@@ -38,33 +48,34 @@ function getTestContext(overrides: Partial<Props> = {}, subUrl = '') {
|
|||||||
</TestProvider>
|
</TestProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Need to click this first to set the correct selection range
|
||||||
|
// see https://github.com/testing-library/user-event/issues/901#issuecomment-1087192424
|
||||||
|
await userEvent.click(document.body);
|
||||||
return { rerender, pushMock };
|
return { rerender, pushMock };
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('NavBarItem', () => {
|
describe('NavBarItem', () => {
|
||||||
describe('when url property is not set', () => {
|
describe('when url property is not set', () => {
|
||||||
it('then it renders the menu trigger as a button', () => {
|
it('then it renders the menu trigger as a button', async () => {
|
||||||
getTestContext();
|
await getTestContext();
|
||||||
|
|
||||||
expect(screen.getAllByRole('button')).toHaveLength(1);
|
expect(screen.getAllByRole('button')).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('and clicking on the menu trigger button', () => {
|
describe('and clicking on the menu trigger button', () => {
|
||||||
it('then the onClick handler should be called', () => {
|
it('then the onClick handler should be called', async () => {
|
||||||
getTestContext();
|
await getTestContext();
|
||||||
|
|
||||||
act(() => {
|
await userEvent.click(screen.getByRole('button'));
|
||||||
userEvent.click(screen.getByRole('button'));
|
|
||||||
});
|
|
||||||
expect(onClickMock).toHaveBeenCalledTimes(1);
|
expect(onClickMock).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('and hovering over the menu trigger button', () => {
|
describe('and hovering over the menu trigger button', () => {
|
||||||
it('then the menu items should be visible', () => {
|
it('then the menu items should be visible', async () => {
|
||||||
getTestContext();
|
await getTestContext();
|
||||||
|
|
||||||
userEvent.hover(screen.getByRole('button'));
|
await userEvent.hover(screen.getByRole('button'));
|
||||||
|
|
||||||
expect(screen.getByRole('menuitem', { name: 'Parent Node' })).toBeInTheDocument();
|
expect(screen.getByRole('menuitem', { name: 'Parent Node' })).toBeInTheDocument();
|
||||||
expect(screen.getByText('Child Node 1')).toBeInTheDocument();
|
expect(screen.getByText('Child Node 1')).toBeInTheDocument();
|
||||||
@@ -73,10 +84,10 @@ describe('NavBarItem', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('and tabbing to the menu trigger button', () => {
|
describe('and tabbing to the menu trigger button', () => {
|
||||||
it('then the menu items should be visible', () => {
|
it('then the menu items should be visible', async () => {
|
||||||
getTestContext();
|
await getTestContext();
|
||||||
|
|
||||||
userEvent.tab();
|
await userEvent.tab();
|
||||||
|
|
||||||
expect(screen.getByText('Parent Node')).toBeInTheDocument();
|
expect(screen.getByText('Parent Node')).toBeInTheDocument();
|
||||||
expect(screen.getByText('Child Node 1')).toBeInTheDocument();
|
expect(screen.getByText('Child Node 1')).toBeInTheDocument();
|
||||||
@@ -85,16 +96,16 @@ describe('NavBarItem', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('and pressing arrow right on the menu trigger button', () => {
|
describe('and pressing arrow right on the menu trigger button', () => {
|
||||||
it('then the correct menu item should receive focus', () => {
|
it('then the correct menu item should receive focus', async () => {
|
||||||
getTestContext();
|
await getTestContext();
|
||||||
|
|
||||||
userEvent.tab();
|
await userEvent.tab();
|
||||||
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
|
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
|
||||||
expect(screen.getByRole('menuitem', { name: 'Parent Node' })).toHaveAttribute('tabIndex', '-1');
|
expect(screen.getByRole('menuitem', { name: 'Parent Node' })).toHaveAttribute('tabIndex', '-1');
|
||||||
expect(screen.getAllByRole('menuitem')[1]).toHaveAttribute('tabIndex', '-1');
|
expect(screen.getAllByRole('menuitem')[1]).toHaveAttribute('tabIndex', '-1');
|
||||||
expect(screen.getAllByRole('menuitem')[2]).toHaveAttribute('tabIndex', '-1');
|
expect(screen.getAllByRole('menuitem')[2]).toHaveAttribute('tabIndex', '-1');
|
||||||
|
|
||||||
userEvent.keyboard('{arrowright}');
|
await userEvent.keyboard('{ArrowRight}');
|
||||||
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
|
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
|
||||||
expect(screen.getAllByRole('menuitem')[0]).toHaveAttribute('tabIndex', '0');
|
expect(screen.getAllByRole('menuitem')[0]).toHaveAttribute('tabIndex', '0');
|
||||||
expect(screen.getAllByRole('menuitem')[1]).toHaveAttribute('tabIndex', '-1');
|
expect(screen.getAllByRole('menuitem')[1]).toHaveAttribute('tabIndex', '-1');
|
||||||
@@ -104,18 +115,18 @@ describe('NavBarItem', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('when url property is set', () => {
|
describe('when url property is set', () => {
|
||||||
it('then it renders the menu trigger as a link', () => {
|
it('then it renders the menu trigger as a link', async () => {
|
||||||
getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
|
await getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
|
||||||
|
|
||||||
expect(screen.getAllByRole('link')).toHaveLength(1);
|
expect(screen.getAllByRole('link')).toHaveLength(1);
|
||||||
expect(screen.getByRole('link')).toHaveAttribute('href', 'https://www.grafana.com');
|
expect(screen.getByRole('link')).toHaveAttribute('href', 'https://www.grafana.com');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('and hovering over the menu trigger link', () => {
|
describe('and hovering over the menu trigger link', () => {
|
||||||
it('then the menu items should be visible', () => {
|
it('then the menu items should be visible', async () => {
|
||||||
getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
|
await getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
|
||||||
|
|
||||||
userEvent.hover(screen.getByRole('link'));
|
await userEvent.hover(screen.getByRole('link'));
|
||||||
|
|
||||||
expect(screen.getByText('Parent Node')).toBeInTheDocument();
|
expect(screen.getByText('Parent Node')).toBeInTheDocument();
|
||||||
expect(screen.getByText('Child Node 1')).toBeInTheDocument();
|
expect(screen.getByText('Child Node 1')).toBeInTheDocument();
|
||||||
@@ -124,10 +135,10 @@ describe('NavBarItem', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('and tabbing to the menu trigger link', () => {
|
describe('and tabbing to the menu trigger link', () => {
|
||||||
it('then the menu items should be visible', () => {
|
it('then the menu items should be visible', async () => {
|
||||||
getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
|
await getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
|
||||||
|
|
||||||
userEvent.tab();
|
await userEvent.tab();
|
||||||
|
|
||||||
expect(screen.getByText('Parent Node')).toBeInTheDocument();
|
expect(screen.getByText('Parent Node')).toBeInTheDocument();
|
||||||
expect(screen.getByText('Child Node 1')).toBeInTheDocument();
|
expect(screen.getByText('Child Node 1')).toBeInTheDocument();
|
||||||
@@ -136,17 +147,17 @@ describe('NavBarItem', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('and pressing arrow right on the menu trigger link', () => {
|
describe('and pressing arrow right on the menu trigger link', () => {
|
||||||
it('then the correct menu item should receive focus', () => {
|
it('then the correct menu item should receive focus', async () => {
|
||||||
getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
|
await getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
|
||||||
|
|
||||||
userEvent.tab();
|
await userEvent.tab();
|
||||||
expect(screen.getAllByRole('link')[0]).toHaveFocus();
|
expect(screen.getAllByRole('link')[0]).toHaveFocus();
|
||||||
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
|
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
|
||||||
expect(screen.getAllByRole('menuitem')[0]).toHaveAttribute('tabIndex', '-1');
|
expect(screen.getAllByRole('menuitem')[0]).toHaveAttribute('tabIndex', '-1');
|
||||||
expect(screen.getAllByRole('menuitem')[1]).toHaveAttribute('tabIndex', '-1');
|
expect(screen.getAllByRole('menuitem')[1]).toHaveAttribute('tabIndex', '-1');
|
||||||
expect(screen.getAllByRole('menuitem')[2]).toHaveAttribute('tabIndex', '-1');
|
expect(screen.getAllByRole('menuitem')[2]).toHaveAttribute('tabIndex', '-1');
|
||||||
|
|
||||||
userEvent.keyboard('{arrowright}');
|
await userEvent.keyboard('{ArrowRight}');
|
||||||
expect(screen.getAllByRole('link')[0]).not.toHaveFocus();
|
expect(screen.getAllByRole('link')[0]).not.toHaveFocus();
|
||||||
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
|
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
|
||||||
expect(screen.getAllByRole('menuitem')[0]).toHaveAttribute('tabIndex', '0');
|
expect(screen.getAllByRole('menuitem')[0]).toHaveAttribute('tabIndex', '0');
|
||||||
@@ -156,18 +167,18 @@ describe('NavBarItem', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('and pressing arrow left on a menu item', () => {
|
describe('and pressing arrow left on a menu item', () => {
|
||||||
it('then the nav bar item should receive focus', () => {
|
it('then the nav bar item should receive focus', async () => {
|
||||||
getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
|
await getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
|
||||||
|
|
||||||
userEvent.tab();
|
await userEvent.tab();
|
||||||
userEvent.keyboard('{arrowright}');
|
await userEvent.keyboard('{ArrowRight}');
|
||||||
expect(screen.getAllByRole('link')[0]).not.toHaveFocus();
|
expect(screen.getAllByRole('link')[0]).not.toHaveFocus();
|
||||||
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
|
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
|
||||||
expect(screen.getAllByRole('menuitem')[0]).toHaveAttribute('tabIndex', '0');
|
expect(screen.getAllByRole('menuitem')[0]).toHaveAttribute('tabIndex', '0');
|
||||||
expect(screen.getAllByRole('menuitem')[1]).toHaveAttribute('tabIndex', '-1');
|
expect(screen.getAllByRole('menuitem')[1]).toHaveAttribute('tabIndex', '-1');
|
||||||
expect(screen.getAllByRole('menuitem')[2]).toHaveAttribute('tabIndex', '-1');
|
expect(screen.getAllByRole('menuitem')[2]).toHaveAttribute('tabIndex', '-1');
|
||||||
|
|
||||||
userEvent.keyboard('{arrowleft}');
|
await userEvent.keyboard('{ArrowLeft}');
|
||||||
expect(screen.getAllByRole('link')[0]).toHaveFocus();
|
expect(screen.getAllByRole('link')[0]).toHaveFocus();
|
||||||
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
|
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
|
||||||
expect(screen.getAllByRole('menuitem')[0]).toHaveAttribute('tabIndex', '-1');
|
expect(screen.getAllByRole('menuitem')[0]).toHaveAttribute('tabIndex', '-1');
|
||||||
@@ -178,7 +189,7 @@ describe('NavBarItem', () => {
|
|||||||
|
|
||||||
describe('when appSubUrl is configured and user clicks on menuitem link', () => {
|
describe('when appSubUrl is configured and user clicks on menuitem link', () => {
|
||||||
it('then location service should be called with correct url', async () => {
|
it('then location service should be called with correct url', async () => {
|
||||||
const { pushMock } = getTestContext(
|
const { pushMock } = await getTestContext(
|
||||||
{
|
{
|
||||||
link: {
|
link: {
|
||||||
...defaults.link,
|
...defaults.link,
|
||||||
@@ -189,15 +200,13 @@ describe('NavBarItem', () => {
|
|||||||
'/grafana'
|
'/grafana'
|
||||||
);
|
);
|
||||||
|
|
||||||
userEvent.hover(screen.getByRole('link'));
|
await userEvent.hover(screen.getByRole('link'));
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(screen.getByText('Parent Node')).toBeInTheDocument();
|
expect(screen.getByText('Parent Node')).toBeInTheDocument();
|
||||||
expect(screen.getByText('New')).toBeInTheDocument();
|
expect(screen.getByText('New')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
act(() => {
|
await userEvent.click(screen.getByText('New'));
|
||||||
userEvent.click(screen.getByText('New'));
|
|
||||||
});
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(pushMock).toHaveBeenCalledTimes(1);
|
expect(pushMock).toHaveBeenCalledTimes(1);
|
||||||
expect(pushMock).toHaveBeenCalledWith('/dashboard/new');
|
expect(pushMock).toHaveBeenCalledWith('/dashboard/new');
|
||||||
@@ -207,7 +216,7 @@ describe('NavBarItem', () => {
|
|||||||
|
|
||||||
describe('when appSubUrl is not configured and user clicks on menuitem link', () => {
|
describe('when appSubUrl is not configured and user clicks on menuitem link', () => {
|
||||||
it('then location service should be called with correct url', async () => {
|
it('then location service should be called with correct url', async () => {
|
||||||
const { pushMock } = getTestContext({
|
const { pushMock } = await getTestContext({
|
||||||
link: {
|
link: {
|
||||||
...defaults.link,
|
...defaults.link,
|
||||||
url: 'https://www.grafana.com',
|
url: 'https://www.grafana.com',
|
||||||
@@ -215,15 +224,13 @@ describe('NavBarItem', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
userEvent.hover(screen.getByRole('link'));
|
await userEvent.hover(screen.getByRole('link'));
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(screen.getByText('Parent Node')).toBeInTheDocument();
|
expect(screen.getByText('Parent Node')).toBeInTheDocument();
|
||||||
expect(screen.getByText('New')).toBeInTheDocument();
|
expect(screen.getByText('New')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
act(() => {
|
await userEvent.click(screen.getByText('New'));
|
||||||
userEvent.click(screen.getByText('New'));
|
|
||||||
});
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(pushMock).toHaveBeenCalledTimes(1);
|
expect(pushMock).toHaveBeenCalledTimes(1);
|
||||||
expect(pushMock).toHaveBeenCalledWith('/grafana/dashboard/new');
|
expect(pushMock).toHaveBeenCalledWith('/grafana/dashboard/new');
|
||||||
|
@@ -23,10 +23,10 @@ describe('NavBarMenu', () => {
|
|||||||
expect(closeButton).toBeInTheDocument();
|
expect(closeButton).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('clicking the close button calls the onClose callback', () => {
|
it('clicking the close button calls the onClose callback', async () => {
|
||||||
const closeButton = screen.getByRole('button', { name: 'Close navigation menu' });
|
const closeButton = screen.getByRole('button', { name: 'Close navigation menu' });
|
||||||
expect(closeButton).toBeInTheDocument();
|
expect(closeButton).toBeInTheDocument();
|
||||||
userEvent.click(closeButton);
|
await userEvent.click(closeButton);
|
||||||
expect(mockOnClose).toHaveBeenCalled();
|
expect(mockOnClose).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -76,7 +76,7 @@ describe('ReadonlyFolderPicker', () => {
|
|||||||
|
|
||||||
expect(within(selectors.container.get()).getByRole('combobox')).toBeInTheDocument();
|
expect(within(selectors.container.get()).getByRole('combobox')).toBeInTheDocument();
|
||||||
getFoldersAsOptionsSpy.mockClear();
|
getFoldersAsOptionsSpy.mockClear();
|
||||||
userEvent.type(within(selectors.container.get()).getByRole('combobox'), 'A');
|
await userEvent.type(within(selectors.container.get()).getByRole('combobox'), 'A');
|
||||||
await waitFor(() => expect(getFoldersAsOptionsSpy).toHaveBeenCalledTimes(1));
|
await waitFor(() => expect(getFoldersAsOptionsSpy).toHaveBeenCalledTimes(1));
|
||||||
|
|
||||||
expect(getFoldersAsOptionsSpy).toHaveBeenCalledWith({
|
expect(getFoldersAsOptionsSpy).toHaveBeenCalledWith({
|
||||||
|
@@ -60,10 +60,10 @@ describe('Signup Page', () => {
|
|||||||
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
|
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
|
||||||
expect(await screen.findByText('Email is required')).toBeInTheDocument();
|
expect(await screen.findByText('Email is required')).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test');
|
await userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test');
|
||||||
await waitFor(() => expect(screen.queryByText('Email is invalid')).toBeInTheDocument());
|
await waitFor(() => expect(screen.queryByText('Email is invalid')).toBeInTheDocument());
|
||||||
|
|
||||||
userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test@gmail.com');
|
await userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test@gmail.com');
|
||||||
await waitFor(() => expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument());
|
await waitFor(() => expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument());
|
||||||
});
|
});
|
||||||
it('should pass validation checks for password and confirm password field', async () => {
|
it('should pass validation checks for password and confirm password field', async () => {
|
||||||
@@ -73,11 +73,11 @@ describe('Signup Page', () => {
|
|||||||
expect(await screen.findByText('Password is required')).toBeInTheDocument();
|
expect(await screen.findByText('Password is required')).toBeInTheDocument();
|
||||||
expect(await screen.findByText('Confirmed password is required')).toBeInTheDocument();
|
expect(await screen.findByText('Confirmed password is required')).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.type(screen.getByLabelText('Password'), 'admin');
|
await userEvent.type(screen.getByLabelText('Password'), 'admin');
|
||||||
userEvent.type(screen.getByLabelText('Confirm password'), 'a');
|
await userEvent.type(screen.getByLabelText('Confirm password'), 'a');
|
||||||
await waitFor(() => expect(screen.queryByText('Passwords must match!')).toBeInTheDocument());
|
await waitFor(() => expect(screen.queryByText('Passwords must match!')).toBeInTheDocument());
|
||||||
|
|
||||||
userEvent.type(screen.getByLabelText('Confirm password'), 'dmin');
|
await userEvent.type(screen.getByLabelText('Confirm password'), 'dmin');
|
||||||
await waitFor(() => expect(screen.queryByText('Passwords must match!')).not.toBeInTheDocument());
|
await waitFor(() => expect(screen.queryByText('Passwords must match!')).not.toBeInTheDocument());
|
||||||
});
|
});
|
||||||
it('should navigate to default url if signup is successful', async () => {
|
it('should navigate to default url if signup is successful', async () => {
|
||||||
@@ -89,10 +89,10 @@ describe('Signup Page', () => {
|
|||||||
postMock.mockResolvedValueOnce({ message: 'Logged in' });
|
postMock.mockResolvedValueOnce({ message: 'Logged in' });
|
||||||
render(<SignupPage {...props} />);
|
render(<SignupPage {...props} />);
|
||||||
|
|
||||||
userEvent.type(screen.getByRole('textbox', { name: 'Your name' }), 'test-user');
|
await userEvent.type(screen.getByRole('textbox', { name: 'Your name' }), 'test-user');
|
||||||
userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test@gmail.com');
|
await userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test@gmail.com');
|
||||||
userEvent.type(screen.getByLabelText('Password'), 'admin');
|
await userEvent.type(screen.getByLabelText('Password'), 'admin');
|
||||||
userEvent.type(screen.getByLabelText('Confirm password'), 'admin');
|
await userEvent.type(screen.getByLabelText('Confirm password'), 'admin');
|
||||||
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
|
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
|
||||||
|
|
||||||
await waitFor(() =>
|
await waitFor(() =>
|
||||||
|
@@ -44,17 +44,17 @@ describe('VerifyEmail Page', () => {
|
|||||||
fireEvent.click(screen.getByRole('button', { name: 'Send verification email' }));
|
fireEvent.click(screen.getByRole('button', { name: 'Send verification email' }));
|
||||||
expect(await screen.findByText('Email is required')).toBeInTheDocument();
|
expect(await screen.findByText('Email is required')).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test');
|
await userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test');
|
||||||
await waitFor(() => expect(screen.queryByText('Email is invalid')).toBeInTheDocument());
|
await waitFor(() => expect(screen.queryByText('Email is invalid')).toBeInTheDocument());
|
||||||
|
|
||||||
userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test@gmail.com');
|
await userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test@gmail.com');
|
||||||
await waitFor(() => expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument());
|
await waitFor(() => expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument());
|
||||||
});
|
});
|
||||||
it('should show complete signup if email-verification is successful', async () => {
|
it('should show complete signup if email-verification is successful', async () => {
|
||||||
postMock.mockResolvedValueOnce({ message: 'SignUpCreated' });
|
postMock.mockResolvedValueOnce({ message: 'SignUpCreated' });
|
||||||
render(<VerifyEmailPage />);
|
render(<VerifyEmailPage />);
|
||||||
|
|
||||||
userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test@gmail.com');
|
await userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test@gmail.com');
|
||||||
fireEvent.click(screen.getByRole('button', { name: 'Send verification email' }));
|
fireEvent.click(screen.getByRole('button', { name: 'Send verification email' }));
|
||||||
|
|
||||||
await waitFor(() =>
|
await waitFor(() =>
|
||||||
|
@@ -53,7 +53,7 @@ describe('OrgSwitcher', () => {
|
|||||||
it('should switch orgId in call to backend', async () => {
|
it('should switch orgId in call to backend', async () => {
|
||||||
const row = screen.getByRole('row', { name: /org 2 admin switch to/i });
|
const row = screen.getByRole('row', { name: /org 2 admin switch to/i });
|
||||||
const switchToButton = within(row).getByText(/switch to/i);
|
const switchToButton = within(row).getByText(/switch to/i);
|
||||||
userEvent.click(switchToButton);
|
await userEvent.click(switchToButton);
|
||||||
|
|
||||||
await waitFor(() => expect(setUserOrgSpy).toBeCalledWith({ orgId: 2, name: 'Org 2', role: 'Admin' }));
|
await waitFor(() => expect(setUserOrgSpy).toBeCalledWith({ orgId: 2, name: 'Org 2', role: 'Admin' }));
|
||||||
});
|
});
|
||||||
@@ -63,7 +63,7 @@ describe('OrgSwitcher', () => {
|
|||||||
|
|
||||||
const row = screen.getByRole('row', { name: /org 2 admin switch to/i });
|
const row = screen.getByRole('row', { name: /org 2 admin switch to/i });
|
||||||
const switchToButton = within(row).getByText(/switch to/i);
|
const switchToButton = within(row).getByText(/switch to/i);
|
||||||
userEvent.click(switchToButton);
|
await userEvent.click(switchToButton);
|
||||||
|
|
||||||
await waitFor(() => expect(window.location.href).toEqual('/subUrl/?orgId=2'));
|
await waitFor(() => expect(window.location.href).toEqual('/subUrl/?orgId=2'));
|
||||||
});
|
});
|
||||||
|
@@ -14,12 +14,12 @@ describe('Unified Alerting promotion', () => {
|
|||||||
expect(screen.queryByText('Try out the Grafana 8 alerting!')).toBeInTheDocument();
|
expect(screen.queryByText('Try out the Grafana 8 alerting!')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be hidden if dismissed', () => {
|
it('should be hidden if dismissed', async () => {
|
||||||
const promotion = render(<UnifiedAlertingPromotion />);
|
const promotion = render(<UnifiedAlertingPromotion />);
|
||||||
expect(window.localStorage.getItem(LOCAL_STORAGE_KEY)).toBe('true');
|
expect(window.localStorage.getItem(LOCAL_STORAGE_KEY)).toBe('true');
|
||||||
|
|
||||||
const dismissButton = promotion.getByRole('button');
|
const dismissButton = promotion.getByRole('button');
|
||||||
userEvent.click(dismissButton);
|
await userEvent.click(dismissButton);
|
||||||
|
|
||||||
expect(screen.queryByText('Try out the Grafana 8 alerting!')).not.toBeInTheDocument();
|
expect(screen.queryByText('Try out the Grafana 8 alerting!')).not.toBeInTheDocument();
|
||||||
expect(window.localStorage.getItem(LOCAL_STORAGE_KEY)).toBe('false');
|
expect(window.localStorage.getItem(LOCAL_STORAGE_KEY)).toBe('false');
|
||||||
|
@@ -83,10 +83,10 @@ describe('AlertGroups', () => {
|
|||||||
expect(groups[0]).toHaveTextContent('No grouping');
|
expect(groups[0]).toHaveTextContent('No grouping');
|
||||||
expect(groups[1]).toHaveTextContent('severity=warningregion=US-Central');
|
expect(groups[1]).toHaveTextContent('severity=warningregion=US-Central');
|
||||||
|
|
||||||
userEvent.click(ui.groupCollapseToggle.get(groups[0]));
|
await userEvent.click(ui.groupCollapseToggle.get(groups[0]));
|
||||||
expect(ui.groupTable.get()).toBeDefined();
|
expect(ui.groupTable.get()).toBeDefined();
|
||||||
|
|
||||||
userEvent.click(ui.collapseToggle.get(ui.groupTable.get()));
|
await userEvent.click(ui.collapseToggle.get(ui.groupTable.get()));
|
||||||
expect(ui.silenceButton.get(ui.groupTable.get())).toBeDefined();
|
expect(ui.silenceButton.get(ui.groupTable.get())).toBeDefined();
|
||||||
expect(ui.sourceButton.get(ui.groupTable.get())).toBeDefined();
|
expect(ui.sourceButton.get(ui.groupTable.get())).toBeDefined();
|
||||||
});
|
});
|
||||||
@@ -118,7 +118,7 @@ describe('AlertGroups', () => {
|
|||||||
expect(groups[1]).toHaveTextContent('region=EMEA');
|
expect(groups[1]).toHaveTextContent('region=EMEA');
|
||||||
expect(groups[2]).toHaveTextContent('region=APAC');
|
expect(groups[2]).toHaveTextContent('region=APAC');
|
||||||
|
|
||||||
userEvent.type(groupByInput, 'appName{enter}');
|
await userEvent.type(groupByInput, 'appName{enter}');
|
||||||
|
|
||||||
await waitFor(() => expect(groupByWrapper).toHaveTextContent('appName'));
|
await waitFor(() => expect(groupByWrapper).toHaveTextContent('appName'));
|
||||||
|
|
||||||
@@ -130,10 +130,10 @@ describe('AlertGroups', () => {
|
|||||||
expect(groups[1]).toHaveTextContent('appName=auth');
|
expect(groups[1]).toHaveTextContent('appName=auth');
|
||||||
expect(groups[2]).toHaveTextContent('appName=frontend');
|
expect(groups[2]).toHaveTextContent('appName=frontend');
|
||||||
|
|
||||||
userEvent.click(ui.clearButton.get());
|
await userEvent.click(ui.clearButton.get());
|
||||||
await waitFor(() => expect(groupByWrapper).not.toHaveTextContent('appName'));
|
await waitFor(() => expect(groupByWrapper).not.toHaveTextContent('appName'));
|
||||||
|
|
||||||
userEvent.type(groupByInput, 'env{enter}');
|
await userEvent.type(groupByInput, 'env{enter}');
|
||||||
await waitFor(() => expect(groupByWrapper).toHaveTextContent('env'));
|
await waitFor(() => expect(groupByWrapper).toHaveTextContent('env'));
|
||||||
|
|
||||||
groups = ui.group.getAll();
|
groups = ui.group.getAll();
|
||||||
@@ -142,10 +142,10 @@ describe('AlertGroups', () => {
|
|||||||
expect(groups[0]).toHaveTextContent('env=production');
|
expect(groups[0]).toHaveTextContent('env=production');
|
||||||
expect(groups[1]).toHaveTextContent('env=staging');
|
expect(groups[1]).toHaveTextContent('env=staging');
|
||||||
|
|
||||||
userEvent.click(ui.clearButton.get());
|
await userEvent.click(ui.clearButton.get());
|
||||||
await waitFor(() => expect(groupByWrapper).not.toHaveTextContent('env'));
|
await waitFor(() => expect(groupByWrapper).not.toHaveTextContent('env'));
|
||||||
|
|
||||||
userEvent.type(groupByInput, 'uniqueLabel{enter}');
|
await userEvent.type(groupByInput, 'uniqueLabel{enter}');
|
||||||
await waitFor(() => expect(groupByWrapper).toHaveTextContent('uniqueLabel'));
|
await waitFor(() => expect(groupByWrapper).toHaveTextContent('uniqueLabel'));
|
||||||
|
|
||||||
groups = ui.group.getAll();
|
groups = ui.group.getAll();
|
||||||
|
@@ -116,7 +116,7 @@ describe('AlertsFolderView tests', () => {
|
|||||||
expect(ui.ruleList.row.queryAll()).toHaveLength(0);
|
expect(ui.ruleList.row.queryAll()).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should filter alert rules by the name, case insensitive', () => {
|
it('Should filter alert rules by the name, case insensitive', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const store = configureStore();
|
const store = configureStore();
|
||||||
const folder = mockFolder();
|
const folder = mockFolder();
|
||||||
@@ -143,14 +143,14 @@ describe('AlertsFolderView tests', () => {
|
|||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
|
|
||||||
userEvent.type(ui.filter.name.get(), 'cpu');
|
await userEvent.type(ui.filter.name.get(), 'cpu');
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(ui.ruleList.row.queryAll()).toHaveLength(1);
|
expect(ui.ruleList.row.queryAll()).toHaveLength(1);
|
||||||
expect(ui.ruleList.row.get()).toHaveTextContent('CPU Alert');
|
expect(ui.ruleList.row.get()).toHaveTextContent('CPU Alert');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should filter alert rule by labels', () => {
|
it('Should filter alert rule by labels', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const store = configureStore();
|
const store = configureStore();
|
||||||
const folder = mockFolder();
|
const folder = mockFolder();
|
||||||
@@ -180,7 +180,7 @@ describe('AlertsFolderView tests', () => {
|
|||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
|
|
||||||
userEvent.type(ui.filter.label.get(), 'severity=critical');
|
await userEvent.type(ui.filter.label.get(), 'severity=critical');
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(ui.ruleList.row.queryAll()).toHaveLength(1);
|
expect(ui.ruleList.row.queryAll()).toHaveLength(1);
|
||||||
|
@@ -273,24 +273,24 @@ describe('AmRoutes', () => {
|
|||||||
|
|
||||||
// open root route for editing
|
// open root route for editing
|
||||||
const rootRouteContainer = await ui.rootRouteContainer.find();
|
const rootRouteContainer = await ui.rootRouteContainer.find();
|
||||||
userEvent.click(ui.editButton.get(rootRouteContainer));
|
await userEvent.click(ui.editButton.get(rootRouteContainer));
|
||||||
|
|
||||||
// configure receiver & group by
|
// configure receiver & group by
|
||||||
const receiverSelect = await ui.receiverSelect.find();
|
const receiverSelect = await ui.receiverSelect.find();
|
||||||
await clickSelectOption(receiverSelect, 'critical');
|
await clickSelectOption(receiverSelect, 'critical');
|
||||||
|
|
||||||
const groupSelect = ui.groupSelect.get();
|
const groupSelect = ui.groupSelect.get();
|
||||||
userEvent.type(byRole('combobox').get(groupSelect), 'namespace{enter}');
|
await userEvent.type(byRole('combobox').get(groupSelect), 'namespace{enter}');
|
||||||
|
|
||||||
// configure timing intervals
|
// configure timing intervals
|
||||||
userEvent.click(byText('Timing options').get(rootRouteContainer));
|
await userEvent.click(byText('Timing options').get(rootRouteContainer));
|
||||||
|
|
||||||
await updateTiming(ui.groupWaitContainer.get(), '1', 'Minutes');
|
await updateTiming(ui.groupWaitContainer.get(), '1', 'Minutes');
|
||||||
await updateTiming(ui.groupIntervalContainer.get(), '4', 'Minutes');
|
await updateTiming(ui.groupIntervalContainer.get(), '4', 'Minutes');
|
||||||
await updateTiming(ui.groupRepeatContainer.get(), '5', 'Hours');
|
await updateTiming(ui.groupRepeatContainer.get(), '5', 'Hours');
|
||||||
|
|
||||||
//save
|
//save
|
||||||
userEvent.click(ui.saveButton.get(rootRouteContainer));
|
await userEvent.click(ui.saveButton.get(rootRouteContainer));
|
||||||
|
|
||||||
// wait for it to go out of edit mode
|
// wait for it to go out of edit mode
|
||||||
await waitFor(() => expect(ui.editButton.query(rootRouteContainer)).not.toBeInTheDocument());
|
await waitFor(() => expect(ui.editButton.query(rootRouteContainer)).not.toBeInTheDocument());
|
||||||
@@ -333,17 +333,17 @@ describe('AmRoutes', () => {
|
|||||||
|
|
||||||
// open root route for editing
|
// open root route for editing
|
||||||
const rootRouteContainer = await ui.rootRouteContainer.find();
|
const rootRouteContainer = await ui.rootRouteContainer.find();
|
||||||
userEvent.click(ui.editButton.get(rootRouteContainer));
|
await userEvent.click(ui.editButton.get(rootRouteContainer));
|
||||||
|
|
||||||
// configure receiver & group by
|
// configure receiver & group by
|
||||||
const receiverSelect = await ui.receiverSelect.find();
|
const receiverSelect = await ui.receiverSelect.find();
|
||||||
await clickSelectOption(receiverSelect, 'default');
|
await clickSelectOption(receiverSelect, 'default');
|
||||||
|
|
||||||
const groupSelect = ui.groupSelect.get();
|
const groupSelect = ui.groupSelect.get();
|
||||||
userEvent.type(byRole('combobox').get(groupSelect), 'severity{enter}');
|
await userEvent.type(byRole('combobox').get(groupSelect), 'severity{enter}');
|
||||||
userEvent.type(byRole('combobox').get(groupSelect), 'namespace{enter}');
|
await userEvent.type(byRole('combobox').get(groupSelect), 'namespace{enter}');
|
||||||
//save
|
//save
|
||||||
userEvent.click(ui.saveButton.get(rootRouteContainer));
|
await userEvent.click(ui.saveButton.get(rootRouteContainer));
|
||||||
|
|
||||||
// wait for it to go out of edit mode
|
// wait for it to go out of edit mode
|
||||||
await waitFor(() => expect(ui.editButton.query(rootRouteContainer)).not.toBeInTheDocument());
|
await waitFor(() => expect(ui.editButton.query(rootRouteContainer)).not.toBeInTheDocument());
|
||||||
@@ -426,8 +426,8 @@ describe('AmRoutes', () => {
|
|||||||
|
|
||||||
// Toggle a save to test new object_matchers
|
// Toggle a save to test new object_matchers
|
||||||
const rootRouteContainer = await ui.rootRouteContainer.find();
|
const rootRouteContainer = await ui.rootRouteContainer.find();
|
||||||
userEvent.click(ui.editButton.get(rootRouteContainer));
|
await userEvent.click(ui.editButton.get(rootRouteContainer));
|
||||||
userEvent.click(ui.saveButton.get(rootRouteContainer));
|
await userEvent.click(ui.saveButton.get(rootRouteContainer));
|
||||||
|
|
||||||
await waitFor(() => expect(ui.editButton.query(rootRouteContainer)).not.toBeInTheDocument());
|
await waitFor(() => expect(ui.editButton.query(rootRouteContainer)).not.toBeInTheDocument());
|
||||||
|
|
||||||
@@ -497,8 +497,8 @@ describe('AmRoutes', () => {
|
|||||||
|
|
||||||
// Toggle a save to test new object_matchers
|
// Toggle a save to test new object_matchers
|
||||||
const rootRouteContainer = await ui.rootRouteContainer.find();
|
const rootRouteContainer = await ui.rootRouteContainer.find();
|
||||||
userEvent.click(ui.editButton.get(rootRouteContainer));
|
await userEvent.click(ui.editButton.get(rootRouteContainer));
|
||||||
userEvent.click(ui.saveButton.get(rootRouteContainer));
|
await userEvent.click(ui.saveButton.get(rootRouteContainer));
|
||||||
|
|
||||||
await waitFor(() => expect(ui.editButton.query(rootRouteContainer)).not.toBeInTheDocument());
|
await waitFor(() => expect(ui.editButton.query(rootRouteContainer)).not.toBeInTheDocument());
|
||||||
|
|
||||||
@@ -599,7 +599,7 @@ describe('AmRoutes', () => {
|
|||||||
await renderAmRoutes(dataSources.am.name);
|
await renderAmRoutes(dataSources.am.name);
|
||||||
const rows = await ui.row.findAll();
|
const rows = await ui.row.findAll();
|
||||||
expect(rows).toHaveLength(1);
|
expect(rows).toHaveLength(1);
|
||||||
userEvent.click(ui.editRouteButton.get(rows[0]));
|
await userEvent.click(ui.editRouteButton.get(rows[0]));
|
||||||
|
|
||||||
const muteTimingSelect = ui.muteTimingSelect.get();
|
const muteTimingSelect = ui.muteTimingSelect.get();
|
||||||
await clickSelectOption(muteTimingSelect, 'default-mute');
|
await clickSelectOption(muteTimingSelect, 'default-mute');
|
||||||
@@ -608,7 +608,7 @@ describe('AmRoutes', () => {
|
|||||||
const savePolicyButton = ui.savePolicyButton.get();
|
const savePolicyButton = ui.savePolicyButton.get();
|
||||||
expect(savePolicyButton).toBeInTheDocument();
|
expect(savePolicyButton).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(savePolicyButton);
|
await userEvent.click(savePolicyButton);
|
||||||
|
|
||||||
await waitFor(() => expect(savePolicyButton).not.toBeInTheDocument());
|
await waitFor(() => expect(savePolicyButton).not.toBeInTheDocument());
|
||||||
|
|
||||||
@@ -637,14 +637,14 @@ describe('AmRoutes', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const clickSelectOption = async (selectElement: HTMLElement, optionText: string): Promise<void> => {
|
const clickSelectOption = async (selectElement: HTMLElement, optionText: string): Promise<void> => {
|
||||||
userEvent.click(byRole('combobox').get(selectElement));
|
await userEvent.click(byRole('combobox').get(selectElement));
|
||||||
await selectOptionInTest(selectElement, optionText);
|
await selectOptionInTest(selectElement, optionText);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateTiming = async (selectElement: HTMLElement, value: string, timeUnit: string): Promise<void> => {
|
const updateTiming = async (selectElement: HTMLElement, value: string, timeUnit: string): Promise<void> => {
|
||||||
const input = byRole('textbox').get(selectElement);
|
const input = byRole('textbox').get(selectElement);
|
||||||
const select = byRole('combobox').get(selectElement);
|
const select = byRole('combobox').get(selectElement);
|
||||||
userEvent.type(input, value);
|
await userEvent.type(input, value);
|
||||||
userEvent.click(select);
|
await userEvent.click(select);
|
||||||
await selectOptionInTest(selectElement, timeUnit);
|
await selectOptionInTest(selectElement, timeUnit);
|
||||||
};
|
};
|
||||||
|
@@ -118,11 +118,11 @@ describe('Mute timings', () => {
|
|||||||
await waitFor(() => expect(mocks.api.fetchAlertManagerConfig).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.api.fetchAlertManagerConfig).toHaveBeenCalled());
|
||||||
expect(ui.nameField.get()).toBeInTheDocument();
|
expect(ui.nameField.get()).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.type(ui.nameField.get(), 'maintenance period');
|
await userEvent.type(ui.nameField.get(), 'maintenance period');
|
||||||
userEvent.type(ui.startsAt.get(), '22:00');
|
await userEvent.type(ui.startsAt.get(), '22:00');
|
||||||
userEvent.type(ui.endsAt.get(), '24:00');
|
await userEvent.type(ui.endsAt.get(), '24:00');
|
||||||
userEvent.type(ui.days.get(), '-1');
|
await userEvent.type(ui.days.get(), '-1');
|
||||||
userEvent.type(ui.months.get(), 'january, july');
|
await userEvent.type(ui.months.get(), 'january, july');
|
||||||
|
|
||||||
fireEvent.submit(ui.form.get());
|
fireEvent.submit(ui.form.get());
|
||||||
|
|
||||||
@@ -163,17 +163,17 @@ describe('Mute timings', () => {
|
|||||||
expect(ui.nameField.get()).toHaveValue(muteTimeInterval.name);
|
expect(ui.nameField.get()).toHaveValue(muteTimeInterval.name);
|
||||||
expect(ui.months.get()).toHaveValue(muteTimeInterval.time_intervals[0].months?.join(', '));
|
expect(ui.months.get()).toHaveValue(muteTimeInterval.time_intervals[0].months?.join(', '));
|
||||||
|
|
||||||
userEvent.clear(ui.startsAt.getAll()?.[0]);
|
await userEvent.clear(ui.startsAt.getAll()?.[0]);
|
||||||
userEvent.clear(ui.endsAt.getAll()?.[0]);
|
await userEvent.clear(ui.endsAt.getAll()?.[0]);
|
||||||
userEvent.clear(ui.weekdays.get());
|
await userEvent.clear(ui.weekdays.get());
|
||||||
userEvent.clear(ui.days.get());
|
await userEvent.clear(ui.days.get());
|
||||||
userEvent.clear(ui.months.get());
|
await userEvent.clear(ui.months.get());
|
||||||
userEvent.clear(ui.years.get());
|
await userEvent.clear(ui.years.get());
|
||||||
|
|
||||||
userEvent.type(ui.weekdays.get(), 'monday');
|
await userEvent.type(ui.weekdays.get(), 'monday');
|
||||||
userEvent.type(ui.days.get(), '-7:-1');
|
await userEvent.type(ui.days.get(), '-7:-1');
|
||||||
userEvent.type(ui.months.get(), '3, 6, 9, 12');
|
await userEvent.type(ui.months.get(), '3, 6, 9, 12');
|
||||||
userEvent.type(ui.years.get(), '2021:2024');
|
await userEvent.type(ui.years.get(), '2021:2024');
|
||||||
|
|
||||||
fireEvent.submit(ui.form.get());
|
fireEvent.submit(ui.form.get());
|
||||||
|
|
||||||
@@ -243,8 +243,8 @@ describe('Mute timings', () => {
|
|||||||
expect(ui.nameField.get()).toBeInTheDocument();
|
expect(ui.nameField.get()).toBeInTheDocument();
|
||||||
expect(ui.nameField.get()).toHaveValue(muteTimeInterval.name);
|
expect(ui.nameField.get()).toHaveValue(muteTimeInterval.name);
|
||||||
|
|
||||||
userEvent.clear(ui.nameField.get());
|
await userEvent.clear(ui.nameField.get());
|
||||||
userEvent.type(ui.nameField.get(), 'Lunch breaks');
|
await userEvent.type(ui.nameField.get(), 'Lunch breaks');
|
||||||
|
|
||||||
fireEvent.submit(ui.form.get());
|
fireEvent.submit(ui.form.get());
|
||||||
|
|
||||||
|
@@ -4,7 +4,7 @@ import { Router } from 'react-router-dom';
|
|||||||
import Receivers from './Receivers';
|
import Receivers from './Receivers';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { locationService, setDataSourceSrv } from '@grafana/runtime';
|
import { locationService, setDataSourceSrv } from '@grafana/runtime';
|
||||||
import { act, render, waitFor } from '@testing-library/react';
|
import { render, waitFor } from '@testing-library/react';
|
||||||
import { getAllDataSources } from './utils/config';
|
import { getAllDataSources } from './utils/config';
|
||||||
import { updateAlertManagerConfig, fetchAlertManagerConfig, fetchStatus, testReceivers } from './api/alertmanager';
|
import { updateAlertManagerConfig, fetchAlertManagerConfig, fetchStatus, testReceivers } from './api/alertmanager';
|
||||||
import {
|
import {
|
||||||
@@ -116,7 +116,7 @@ const ui = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const clickSelectOption = async (selectElement: HTMLElement, optionText: string): Promise<void> => {
|
const clickSelectOption = async (selectElement: HTMLElement, optionText: string): Promise<void> => {
|
||||||
userEvent.click(byRole('combobox').get(selectElement));
|
await userEvent.click(byRole('combobox').get(selectElement));
|
||||||
await selectOptionInTest(selectElement, optionText);
|
await selectOptionInTest(selectElement, optionText);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -194,29 +194,25 @@ describe('Receivers', () => {
|
|||||||
await renderReceivers();
|
await renderReceivers();
|
||||||
|
|
||||||
// go to new contact point page
|
// go to new contact point page
|
||||||
await act(async () => {
|
await userEvent.click(await ui.newContactPointButton.find());
|
||||||
userEvent.click(await ui.newContactPointButton.find());
|
|
||||||
});
|
|
||||||
|
|
||||||
await byRole('heading', { name: /create contact point/i }).find();
|
await byRole('heading', { name: /create contact point/i }).find();
|
||||||
|
|
||||||
expect(locationService.getLocation().pathname).toEqual('/alerting/notifications/receivers/new');
|
expect(locationService.getLocation().pathname).toEqual('/alerting/notifications/receivers/new');
|
||||||
|
|
||||||
await act(async () => {
|
// type in a name for the new receiver
|
||||||
// type in a name for the new receiver
|
await userEvent.type(ui.inputs.name.get(), 'my new receiver');
|
||||||
userEvent.type(ui.inputs.name.get(), 'my new receiver');
|
|
||||||
|
|
||||||
// enter some email
|
// enter some email
|
||||||
const email = ui.inputs.email.addresses.get();
|
const email = ui.inputs.email.addresses.get();
|
||||||
userEvent.clear(email);
|
await userEvent.clear(email);
|
||||||
userEvent.type(email, 'tester@grafana.com');
|
await userEvent.type(email, 'tester@grafana.com');
|
||||||
|
|
||||||
// try to test the contact point
|
// try to test the contact point
|
||||||
userEvent.click(await ui.testContactPointButton.find());
|
await userEvent.click(await ui.testContactPointButton.find());
|
||||||
});
|
|
||||||
|
|
||||||
await waitFor(() => expect(ui.testContactPointModal.get()).toBeInTheDocument(), { timeout: 1000 });
|
await waitFor(() => expect(ui.testContactPointModal.get()).toBeInTheDocument(), { timeout: 1000 });
|
||||||
userEvent.click(ui.customContactPointOption.get());
|
await userEvent.click(ui.customContactPointOption.get());
|
||||||
await waitFor(() => expect(ui.contactPointAnnotationSelect(0).get()).toBeInTheDocument());
|
await waitFor(() => expect(ui.contactPointAnnotationSelect(0).get()).toBeInTheDocument());
|
||||||
|
|
||||||
// enter custom annotations and labels
|
// enter custom annotations and labels
|
||||||
@@ -224,7 +220,7 @@ describe('Receivers', () => {
|
|||||||
await userEvent.type(ui.contactPointAnnotationValue(0).get(), 'Test contact point');
|
await userEvent.type(ui.contactPointAnnotationValue(0).get(), 'Test contact point');
|
||||||
await userEvent.type(ui.contactPointLabelKey(0).get(), 'foo');
|
await userEvent.type(ui.contactPointLabelKey(0).get(), 'foo');
|
||||||
await userEvent.type(ui.contactPointLabelValue(0).get(), 'bar');
|
await userEvent.type(ui.contactPointLabelValue(0).get(), 'bar');
|
||||||
userEvent.click(ui.testContactPoint.get());
|
await userEvent.click(ui.testContactPoint.get());
|
||||||
|
|
||||||
await waitFor(() => expect(mocks.api.testReceivers).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.api.testReceivers).toHaveBeenCalled());
|
||||||
|
|
||||||
@@ -260,7 +256,7 @@ describe('Receivers', () => {
|
|||||||
expect(locationService.getLocation().pathname).toEqual('/alerting/notifications/receivers/new');
|
expect(locationService.getLocation().pathname).toEqual('/alerting/notifications/receivers/new');
|
||||||
|
|
||||||
// type in a name for the new receiver
|
// type in a name for the new receiver
|
||||||
userEvent.type(byPlaceholderText('Name').get(), 'my new receiver');
|
await userEvent.type(byPlaceholderText('Name').get(), 'my new receiver');
|
||||||
|
|
||||||
// check that default email form is rendered
|
// check that default email form is rendered
|
||||||
await ui.inputs.email.addresses.find();
|
await ui.inputs.email.addresses.find();
|
||||||
@@ -274,13 +270,10 @@ describe('Receivers', () => {
|
|||||||
const urlInput = ui.inputs.hipchat.url.get();
|
const urlInput = ui.inputs.hipchat.url.get();
|
||||||
const apiKeyInput = ui.inputs.hipchat.apiKey.get();
|
const apiKeyInput = ui.inputs.hipchat.apiKey.get();
|
||||||
|
|
||||||
userEvent.type(urlInput, 'http://hipchat');
|
await userEvent.type(urlInput, 'http://hipchat');
|
||||||
userEvent.type(apiKeyInput, 'foobarbaz');
|
await userEvent.type(apiKeyInput, 'foobarbaz');
|
||||||
|
|
||||||
// it seems react-hook-form does some async state updates after submit
|
await userEvent.click(await ui.saveContactButton.find());
|
||||||
await act(async () => {
|
|
||||||
userEvent.click(await ui.saveContactButton.find());
|
|
||||||
});
|
|
||||||
|
|
||||||
// see that we're back to main page and proper api calls have been made
|
// see that we're back to main page and proper api calls have been made
|
||||||
await ui.receiversTable.find();
|
await ui.receiversTable.find();
|
||||||
@@ -350,13 +343,13 @@ describe('Receivers', () => {
|
|||||||
// modify webhook url
|
// modify webhook url
|
||||||
const slackContainer = ui.channelFormContainer.get();
|
const slackContainer = ui.channelFormContainer.get();
|
||||||
await userEvent.click(byText('Optional Slack settings').get(slackContainer));
|
await userEvent.click(byText('Optional Slack settings').get(slackContainer));
|
||||||
userEvent.type(ui.inputs.slack.webhookURL.get(slackContainer), 'http://newgreaturl');
|
await userEvent.type(ui.inputs.slack.webhookURL.get(slackContainer), 'http://newgreaturl');
|
||||||
|
|
||||||
// add confirm button to action
|
// add confirm button to action
|
||||||
await userEvent.click(byText(/Actions \(1\)/i).get(slackContainer));
|
await userEvent.click(byText(/Actions \(1\)/i).get(slackContainer));
|
||||||
await userEvent.click(await byTestId('items.1.settings.actions.0.confirm.add-button').find());
|
await userEvent.click(await byTestId('items.1.settings.actions.0.confirm.add-button').find());
|
||||||
const confirmSubform = byTestId('items.1.settings.actions.0.confirm.container').get();
|
const confirmSubform = byTestId('items.1.settings.actions.0.confirm.container').get();
|
||||||
userEvent.type(byLabelText('Text').get(confirmSubform), 'confirm this');
|
await userEvent.type(byLabelText('Text').get(confirmSubform), 'confirm this');
|
||||||
|
|
||||||
// delete a field
|
// delete a field
|
||||||
await userEvent.click(byText(/Fields \(2\)/i).get(slackContainer));
|
await userEvent.click(byText(/Fields \(2\)/i).get(slackContainer));
|
||||||
@@ -366,12 +359,9 @@ describe('Receivers', () => {
|
|||||||
// add another channel
|
// add another channel
|
||||||
await userEvent.click(ui.newContactPointTypeButton.get());
|
await userEvent.click(ui.newContactPointTypeButton.get());
|
||||||
await clickSelectOption(await byTestId('items.2.type').find(), 'Webhook');
|
await clickSelectOption(await byTestId('items.2.type').find(), 'Webhook');
|
||||||
userEvent.type(await ui.inputs.webhook.URL.find(), 'http://webhookurl');
|
await userEvent.type(await ui.inputs.webhook.URL.find(), 'http://webhookurl');
|
||||||
|
|
||||||
// it seems react-hook-form does some async state updates after submit
|
await userEvent.click(ui.saveContactButton.get());
|
||||||
await act(async () => {
|
|
||||||
await userEvent.click(ui.saveContactButton.get());
|
|
||||||
});
|
|
||||||
|
|
||||||
// see that we're back to main page and proper api calls have been made
|
// see that we're back to main page and proper api calls have been made
|
||||||
await ui.receiversTable.find();
|
await ui.receiversTable.find();
|
||||||
@@ -438,7 +428,7 @@ describe('Receivers', () => {
|
|||||||
const receiverRows = receiversTable.querySelectorAll<HTMLTableRowElement>('tbody tr');
|
const receiverRows = receiversTable.querySelectorAll<HTMLTableRowElement>('tbody tr');
|
||||||
expect(receiverRows[0]).toHaveTextContent('cloud-receiver');
|
expect(receiverRows[0]).toHaveTextContent('cloud-receiver');
|
||||||
expect(byTestId('edit').query(receiverRows[0])).not.toBeInTheDocument();
|
expect(byTestId('edit').query(receiverRows[0])).not.toBeInTheDocument();
|
||||||
userEvent.click(byTestId('view').get(receiverRows[0]));
|
await userEvent.click(byTestId('view').get(receiverRows[0]));
|
||||||
|
|
||||||
// check that form is open
|
// check that form is open
|
||||||
await byRole('heading', { name: /contact point/i }).find();
|
await byRole('heading', { name: /contact point/i }).find();
|
||||||
|
@@ -9,7 +9,7 @@ import { byLabelText, byRole, byTestId, byText } from 'testing-library-selector'
|
|||||||
import { selectOptionInTest } from '@grafana/ui';
|
import { selectOptionInTest } from '@grafana/ui';
|
||||||
import { contextSrv } from 'app/core/services/context_srv';
|
import { contextSrv } from 'app/core/services/context_srv';
|
||||||
import { mockDataSource, MockDataSourceSrv } from './mocks';
|
import { mockDataSource, MockDataSourceSrv } from './mocks';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event';
|
||||||
import { DataSourceInstanceSettings } from '@grafana/data';
|
import { DataSourceInstanceSettings } from '@grafana/data';
|
||||||
import { getAllDataSources } from './utils/config';
|
import { getAllDataSources } from './utils/config';
|
||||||
import { fetchRulerRules, fetchRulerRulesGroup, fetchRulerRulesNamespace, setRulerRuleGroup } from './api/ruler';
|
import { fetchRulerRules, fetchRulerRulesGroup, fetchRulerRulesNamespace, setRulerRuleGroup } from './api/ruler';
|
||||||
@@ -144,30 +144,30 @@ describe('RuleEditor', () => {
|
|||||||
await waitFor(() => expect(mocks.searchFolders).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.searchFolders).toHaveBeenCalled());
|
||||||
|
|
||||||
await waitFor(() => expect(mocks.api.fetchBuildInfo).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.api.fetchBuildInfo).toHaveBeenCalled());
|
||||||
userEvent.type(await ui.inputs.name.find(), 'my great new rule');
|
await userEvent.type(await ui.inputs.name.find(), 'my great new rule');
|
||||||
userEvent.click(await ui.buttons.lotexAlert.get());
|
await userEvent.click(await ui.buttons.lotexAlert.get());
|
||||||
const dataSourceSelect = ui.inputs.dataSource.get();
|
const dataSourceSelect = ui.inputs.dataSource.get();
|
||||||
userEvent.click(byRole('combobox').get(dataSourceSelect));
|
await userEvent.click(byRole('combobox').get(dataSourceSelect));
|
||||||
await clickSelectOption(dataSourceSelect, 'Prom (default)');
|
await clickSelectOption(dataSourceSelect, 'Prom (default)');
|
||||||
await waitFor(() => expect(mocks.api.fetchRulerRules).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.api.fetchRulerRules).toHaveBeenCalled());
|
||||||
await clickSelectOption(ui.inputs.namespace.get(), 'namespace2');
|
await clickSelectOption(ui.inputs.namespace.get(), 'namespace2');
|
||||||
await clickSelectOption(ui.inputs.group.get(), 'group2');
|
await clickSelectOption(ui.inputs.group.get(), 'group2');
|
||||||
|
|
||||||
userEvent.type(ui.inputs.expr.get(), 'up == 1');
|
await userEvent.type(ui.inputs.expr.get(), 'up == 1');
|
||||||
|
|
||||||
userEvent.type(ui.inputs.annotationValue(0).get(), 'some summary');
|
await userEvent.type(ui.inputs.annotationValue(0).get(), 'some summary');
|
||||||
userEvent.type(ui.inputs.annotationValue(1).get(), 'some description');
|
await userEvent.type(ui.inputs.annotationValue(1).get(), 'some description');
|
||||||
|
|
||||||
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
||||||
userEvent.click(ui.buttons.addLabel.get(), undefined, { skipPointerEventsCheck: true });
|
await userEvent.click(ui.buttons.addLabel.get(), { pointerEventsCheck: PointerEventsCheckLevel.Never });
|
||||||
|
|
||||||
userEvent.type(ui.inputs.labelKey(0).get(), 'severity');
|
await userEvent.type(ui.inputs.labelKey(0).get(), 'severity');
|
||||||
userEvent.type(ui.inputs.labelValue(0).get(), 'warn');
|
await userEvent.type(ui.inputs.labelValue(0).get(), 'warn');
|
||||||
userEvent.type(ui.inputs.labelKey(1).get(), 'team');
|
await userEvent.type(ui.inputs.labelKey(1).get(), 'team');
|
||||||
userEvent.type(ui.inputs.labelValue(1).get(), 'the a-team');
|
await userEvent.type(ui.inputs.labelValue(1).get(), 'the a-team');
|
||||||
|
|
||||||
// save and check what was sent to backend
|
// save and check what was sent to backend
|
||||||
userEvent.click(ui.buttons.save.get());
|
await userEvent.click(ui.buttons.save.get());
|
||||||
await waitFor(() => expect(mocks.api.setRulerRuleGroup).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.api.setRulerRuleGroup).toHaveBeenCalled());
|
||||||
expect(mocks.api.setRulerRuleGroup).toHaveBeenCalledWith(
|
expect(mocks.api.setRulerRuleGroup).toHaveBeenCalledWith(
|
||||||
{ dataSourceName: 'Prom', apiVersion: 'legacy' },
|
{ dataSourceName: 'Prom', apiVersion: 'legacy' },
|
||||||
@@ -244,27 +244,27 @@ describe('RuleEditor', () => {
|
|||||||
await waitFor(() => expect(mocks.searchFolders).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.searchFolders).toHaveBeenCalled());
|
||||||
await waitFor(() => expect(mocks.api.fetchBuildInfo).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.api.fetchBuildInfo).toHaveBeenCalled());
|
||||||
|
|
||||||
userEvent.type(await ui.inputs.name.find(), 'my great new rule');
|
await userEvent.type(await ui.inputs.name.find(), 'my great new rule');
|
||||||
|
|
||||||
const folderInput = await ui.inputs.folder.find();
|
const folderInput = await ui.inputs.folder.find();
|
||||||
await clickSelectOption(folderInput, 'Folder A');
|
await clickSelectOption(folderInput, 'Folder A');
|
||||||
|
|
||||||
const groupInput = screen.getByRole('textbox', { name: /^Group/ });
|
const groupInput = screen.getByRole('textbox', { name: /^Group/ });
|
||||||
userEvent.type(groupInput, 'my group');
|
await userEvent.type(groupInput, 'my group');
|
||||||
|
|
||||||
userEvent.type(ui.inputs.annotationValue(0).get(), 'some summary');
|
await userEvent.type(ui.inputs.annotationValue(0).get(), 'some summary');
|
||||||
userEvent.type(ui.inputs.annotationValue(1).get(), 'some description');
|
await userEvent.type(ui.inputs.annotationValue(1).get(), 'some description');
|
||||||
|
|
||||||
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
||||||
userEvent.click(ui.buttons.addLabel.get(), undefined, { skipPointerEventsCheck: true });
|
await userEvent.click(ui.buttons.addLabel.get(), { pointerEventsCheck: PointerEventsCheckLevel.Never });
|
||||||
|
|
||||||
userEvent.type(ui.inputs.labelKey(0).get(), 'severity');
|
await userEvent.type(ui.inputs.labelKey(0).get(), 'severity');
|
||||||
userEvent.type(ui.inputs.labelValue(0).get(), 'warn');
|
await userEvent.type(ui.inputs.labelValue(0).get(), 'warn');
|
||||||
userEvent.type(ui.inputs.labelKey(1).get(), 'team');
|
await userEvent.type(ui.inputs.labelKey(1).get(), 'team');
|
||||||
userEvent.type(ui.inputs.labelValue(1).get(), 'the a-team');
|
await userEvent.type(ui.inputs.labelValue(1).get(), 'the a-team');
|
||||||
|
|
||||||
// save and check what was sent to backend
|
// save and check what was sent to backend
|
||||||
userEvent.click(ui.buttons.save.get());
|
await userEvent.click(ui.buttons.save.get());
|
||||||
await waitFor(() => expect(mocks.api.setRulerRuleGroup).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.api.setRulerRuleGroup).toHaveBeenCalled());
|
||||||
expect(mocks.api.setRulerRuleGroup).toHaveBeenCalledWith(
|
expect(mocks.api.setRulerRuleGroup).toHaveBeenCalledWith(
|
||||||
{ dataSourceName: GRAFANA_RULES_SOURCE_NAME, apiVersion: 'legacy' },
|
{ dataSourceName: GRAFANA_RULES_SOURCE_NAME, apiVersion: 'legacy' },
|
||||||
@@ -336,27 +336,27 @@ describe('RuleEditor', () => {
|
|||||||
await renderRuleEditor();
|
await renderRuleEditor();
|
||||||
await waitFor(() => expect(mocks.searchFolders).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.searchFolders).toHaveBeenCalled());
|
||||||
await waitFor(() => expect(mocks.api.fetchBuildInfo).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.api.fetchBuildInfo).toHaveBeenCalled());
|
||||||
userEvent.type(await ui.inputs.name.find(), 'my great new recording rule');
|
await userEvent.type(await ui.inputs.name.find(), 'my great new recording rule');
|
||||||
userEvent.click(await ui.buttons.lotexRecordingRule.get());
|
await userEvent.click(await ui.buttons.lotexRecordingRule.get());
|
||||||
|
|
||||||
const dataSourceSelect = ui.inputs.dataSource.get();
|
const dataSourceSelect = ui.inputs.dataSource.get();
|
||||||
userEvent.click(byRole('combobox').get(dataSourceSelect));
|
await userEvent.click(byRole('combobox').get(dataSourceSelect));
|
||||||
|
|
||||||
await clickSelectOption(dataSourceSelect, 'Prom (default)');
|
await clickSelectOption(dataSourceSelect, 'Prom (default)');
|
||||||
await waitFor(() => expect(mocks.api.fetchRulerRules).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.api.fetchRulerRules).toHaveBeenCalled());
|
||||||
await clickSelectOption(ui.inputs.namespace.get(), 'namespace2');
|
await clickSelectOption(ui.inputs.namespace.get(), 'namespace2');
|
||||||
await clickSelectOption(ui.inputs.group.get(), 'group2');
|
await clickSelectOption(ui.inputs.group.get(), 'group2');
|
||||||
|
|
||||||
userEvent.type(ui.inputs.expr.get(), 'up == 1');
|
await userEvent.type(ui.inputs.expr.get(), 'up == 1');
|
||||||
|
|
||||||
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
||||||
userEvent.click(ui.buttons.addLabel.get(), undefined, { skipPointerEventsCheck: true });
|
await userEvent.click(ui.buttons.addLabel.get(), { pointerEventsCheck: PointerEventsCheckLevel.Never });
|
||||||
|
|
||||||
userEvent.type(ui.inputs.labelKey(1).get(), 'team');
|
await userEvent.type(ui.inputs.labelKey(1).get(), 'team');
|
||||||
userEvent.type(ui.inputs.labelValue(1).get(), 'the a-team');
|
await userEvent.type(ui.inputs.labelValue(1).get(), 'the a-team');
|
||||||
|
|
||||||
// try to save, find out that recording rule name is invalid
|
// try to save, find out that recording rule name is invalid
|
||||||
userEvent.click(ui.buttons.save.get());
|
await userEvent.click(ui.buttons.save.get());
|
||||||
await waitFor(() =>
|
await waitFor(() =>
|
||||||
expect(
|
expect(
|
||||||
byText(
|
byText(
|
||||||
@@ -367,11 +367,11 @@ describe('RuleEditor', () => {
|
|||||||
expect(mocks.api.setRulerRuleGroup).not.toBeCalled();
|
expect(mocks.api.setRulerRuleGroup).not.toBeCalled();
|
||||||
|
|
||||||
// fix name and re-submit
|
// fix name and re-submit
|
||||||
userEvent.type(await ui.inputs.name.find(), '{selectall}{del}my:great:new:recording:rule');
|
await userEvent.clear(await ui.inputs.name.find());
|
||||||
userEvent.click(ui.buttons.save.get());
|
await userEvent.type(await ui.inputs.name.find(), 'my:great:new:recording:rule');
|
||||||
|
|
||||||
// save and check what was sent to backend
|
// save and check what was sent to backend
|
||||||
userEvent.click(ui.buttons.save.get());
|
await userEvent.click(ui.buttons.save.get());
|
||||||
await waitFor(() => expect(mocks.api.setRulerRuleGroup).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.api.setRulerRuleGroup).toHaveBeenCalled());
|
||||||
expect(mocks.api.setRulerRuleGroup).toHaveBeenCalledWith(
|
expect(mocks.api.setRulerRuleGroup).toHaveBeenCalledWith(
|
||||||
{ dataSourceName: 'Prom', apiVersion: 'legacy' },
|
{ dataSourceName: 'Prom', apiVersion: 'legacy' },
|
||||||
@@ -458,15 +458,15 @@ describe('RuleEditor', () => {
|
|||||||
|
|
||||||
// add an annotation
|
// add an annotation
|
||||||
await clickSelectOption(ui.inputs.annotationKey(2).get(), /Add new/);
|
await clickSelectOption(ui.inputs.annotationKey(2).get(), /Add new/);
|
||||||
userEvent.type(byRole('textbox').get(ui.inputs.annotationKey(2).get()), 'custom');
|
await userEvent.type(byRole('textbox').get(ui.inputs.annotationKey(2).get()), 'custom');
|
||||||
userEvent.type(ui.inputs.annotationValue(2).get(), 'value');
|
await userEvent.type(ui.inputs.annotationValue(2).get(), 'value');
|
||||||
|
|
||||||
//add a label
|
//add a label
|
||||||
userEvent.type(ui.inputs.labelKey(2).get(), 'custom');
|
await userEvent.type(ui.inputs.labelKey(2).get(), 'custom');
|
||||||
userEvent.type(ui.inputs.labelValue(2).get(), 'value');
|
await userEvent.type(ui.inputs.labelValue(2).get(), 'value');
|
||||||
|
|
||||||
// save and check what was sent to backend
|
// save and check what was sent to backend
|
||||||
userEvent.click(ui.buttons.save.get());
|
await userEvent.click(ui.buttons.save.get());
|
||||||
await waitFor(() => expect(mocks.api.setRulerRuleGroup).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.api.setRulerRuleGroup).toHaveBeenCalled());
|
||||||
|
|
||||||
expect(mocks.api.setRulerRuleGroup).toHaveBeenCalledWith(
|
expect(mocks.api.setRulerRuleGroup).toHaveBeenCalledWith(
|
||||||
@@ -614,11 +614,11 @@ describe('RuleEditor', () => {
|
|||||||
await waitFor(() => expect(mocks.searchFolders).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.searchFolders).toHaveBeenCalled());
|
||||||
|
|
||||||
await ui.inputs.name.find();
|
await ui.inputs.name.find();
|
||||||
userEvent.click(await ui.buttons.lotexAlert.get());
|
await userEvent.click(await ui.buttons.lotexAlert.get());
|
||||||
|
|
||||||
// check that only rules sources that have ruler available are there
|
// check that only rules sources that have ruler available are there
|
||||||
const dataSourceSelect = ui.inputs.dataSource.get();
|
const dataSourceSelect = ui.inputs.dataSource.get();
|
||||||
userEvent.click(byRole('combobox').get(dataSourceSelect));
|
await userEvent.click(byRole('combobox').get(dataSourceSelect));
|
||||||
expect(await byText('loki with ruler').query()).toBeInTheDocument();
|
expect(await byText('loki with ruler').query()).toBeInTheDocument();
|
||||||
expect(byText('cortex with ruler').query()).toBeInTheDocument();
|
expect(byText('cortex with ruler').query()).toBeInTheDocument();
|
||||||
expect(byText('loki with local rule store').query()).not.toBeInTheDocument();
|
expect(byText('loki with local rule store').query()).not.toBeInTheDocument();
|
||||||
@@ -629,6 +629,6 @@ describe('RuleEditor', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const clickSelectOption = async (selectElement: HTMLElement, optionText: Matcher): Promise<void> => {
|
const clickSelectOption = async (selectElement: HTMLElement, optionText: Matcher): Promise<void> => {
|
||||||
userEvent.click(byRole('combobox').get(selectElement));
|
await userEvent.click(byRole('combobox').get(selectElement));
|
||||||
await selectOptionInTest(selectElement, optionText as string);
|
await selectOptionInTest(selectElement, optionText as string);
|
||||||
};
|
};
|
||||||
|
@@ -202,7 +202,7 @@ describe('RuleList', () => {
|
|||||||
expect(errors).not.toHaveTextContent(
|
expect(errors).not.toHaveTextContent(
|
||||||
'Failed to load rules state from Prometheus-broken: this datasource is broken'
|
'Failed to load rules state from Prometheus-broken: this datasource is broken'
|
||||||
);
|
);
|
||||||
userEvent.click(ui.moreErrorsButton.get());
|
await userEvent.click(ui.moreErrorsButton.get());
|
||||||
expect(errors).toHaveTextContent('Failed to load rules state from Prometheus-broken: this datasource is broken');
|
expect(errors).toHaveTextContent('Failed to load rules state from Prometheus-broken: this datasource is broken');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -293,7 +293,7 @@ describe('RuleList', () => {
|
|||||||
|
|
||||||
// expand second group to see rules table
|
// expand second group to see rules table
|
||||||
expect(ui.rulesTable.query()).not.toBeInTheDocument();
|
expect(ui.rulesTable.query()).not.toBeInTheDocument();
|
||||||
userEvent.click(ui.groupCollapseToggle.get(groups[1]));
|
await userEvent.click(ui.groupCollapseToggle.get(groups[1]));
|
||||||
const table = await ui.rulesTable.find(groups[1]);
|
const table = await ui.rulesTable.find(groups[1]);
|
||||||
|
|
||||||
// check that rule rows are rendered properly
|
// check that rule rows are rendered properly
|
||||||
@@ -315,7 +315,7 @@ describe('RuleList', () => {
|
|||||||
expect(byText('Labels').query()).not.toBeInTheDocument();
|
expect(byText('Labels').query()).not.toBeInTheDocument();
|
||||||
|
|
||||||
// expand alert details
|
// expand alert details
|
||||||
userEvent.click(ui.ruleCollapseToggle.get(ruleRows[1]));
|
await userEvent.click(ui.ruleCollapseToggle.get(ruleRows[1]));
|
||||||
|
|
||||||
const ruleDetails = ui.expandedContent.get(ruleRows[1]);
|
const ruleDetails = ui.expandedContent.get(ruleRows[1]);
|
||||||
|
|
||||||
@@ -334,17 +334,17 @@ describe('RuleList', () => {
|
|||||||
expect(instanceRows![1]).toHaveTextContent('Firingfoo=bazseverity=error2021-03-18 13:47:05');
|
expect(instanceRows![1]).toHaveTextContent('Firingfoo=bazseverity=error2021-03-18 13:47:05');
|
||||||
|
|
||||||
// expand details of an instance
|
// expand details of an instance
|
||||||
userEvent.click(ui.ruleCollapseToggle.get(instanceRows![0]));
|
await userEvent.click(ui.ruleCollapseToggle.get(instanceRows![0]));
|
||||||
|
|
||||||
const alertDetails = byTestId('expanded-content').get(instanceRows[0]);
|
const alertDetails = byTestId('expanded-content').get(instanceRows[0]);
|
||||||
expect(alertDetails).toHaveTextContent('Value2e+10');
|
expect(alertDetails).toHaveTextContent('Value2e+10');
|
||||||
expect(alertDetails).toHaveTextContent('messagefirst alert message');
|
expect(alertDetails).toHaveTextContent('messagefirst alert message');
|
||||||
|
|
||||||
// collapse everything again
|
// collapse everything again
|
||||||
userEvent.click(ui.ruleCollapseToggle.get(instanceRows![0]));
|
await userEvent.click(ui.ruleCollapseToggle.get(instanceRows![0]));
|
||||||
expect(byTestId('expanded-content').query(instanceRows[0])).not.toBeInTheDocument();
|
expect(byTestId('expanded-content').query(instanceRows[0])).not.toBeInTheDocument();
|
||||||
userEvent.click(ui.ruleCollapseToggle.getAll(ruleRows[1])[0]);
|
await userEvent.click(ui.ruleCollapseToggle.getAll(ruleRows[1])[0]);
|
||||||
userEvent.click(ui.groupCollapseToggle.get(groups[1]));
|
await userEvent.click(ui.groupCollapseToggle.get(groups[1]));
|
||||||
expect(ui.rulesTable.query()).not.toBeInTheDocument();
|
expect(ui.rulesTable.query()).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -456,33 +456,36 @@ describe('RuleList', () => {
|
|||||||
expect(groups).toHaveLength(2);
|
expect(groups).toHaveLength(2);
|
||||||
|
|
||||||
const filterInput = ui.rulesFilterInput.get();
|
const filterInput = ui.rulesFilterInput.get();
|
||||||
userEvent.type(filterInput, '{{foo="bar"}');
|
await userEvent.type(filterInput, '{{foo="bar"}');
|
||||||
|
|
||||||
// Input is debounced so wait for it to be visible
|
// Input is debounced so wait for it to be visible
|
||||||
await waitFor(() => expect(filterInput).toHaveValue('{foo="bar"}'));
|
await waitFor(() => expect(filterInput).toHaveValue('{foo="bar"}'));
|
||||||
// Group doesn't contain matching labels
|
// Group doesn't contain matching labels
|
||||||
await waitFor(() => expect(ui.ruleGroup.queryAll()).toHaveLength(1));
|
await waitFor(() => expect(ui.ruleGroup.queryAll()).toHaveLength(1));
|
||||||
|
|
||||||
userEvent.click(ui.groupCollapseToggle.get(groups[0]));
|
await userEvent.click(ui.groupCollapseToggle.get(groups[0]));
|
||||||
|
|
||||||
const ruleRows = ui.ruleRow.getAll(groups[0]);
|
const ruleRows = ui.ruleRow.getAll(groups[0]);
|
||||||
expect(ruleRows).toHaveLength(1);
|
expect(ruleRows).toHaveLength(1);
|
||||||
|
|
||||||
userEvent.click(ui.ruleCollapseToggle.get(ruleRows[0]));
|
await userEvent.click(ui.ruleCollapseToggle.get(ruleRows[0]));
|
||||||
const ruleDetails = ui.expandedContent.get(ruleRows[0]);
|
const ruleDetails = ui.expandedContent.get(ruleRows[0]);
|
||||||
|
|
||||||
expect(ruleDetails).toHaveTextContent('Labelsseverity=warningfoo=bar');
|
expect(ruleDetails).toHaveTextContent('Labelsseverity=warningfoo=bar');
|
||||||
|
|
||||||
// Check for different label matchers
|
// Check for different label matchers
|
||||||
userEvent.type(filterInput, '{selectall}{del}{{foo!="bar",foo!="baz"}');
|
await userEvent.clear(filterInput);
|
||||||
|
await userEvent.type(filterInput, '{{foo!="bar",foo!="baz"}');
|
||||||
// Group doesn't contain matching labels
|
// Group doesn't contain matching labels
|
||||||
await waitFor(() => expect(ui.ruleGroup.queryAll()).toHaveLength(1));
|
await waitFor(() => expect(ui.ruleGroup.queryAll()).toHaveLength(1));
|
||||||
await waitFor(() => expect(ui.ruleGroup.get()).toHaveTextContent('group-2'));
|
await waitFor(() => expect(ui.ruleGroup.get()).toHaveTextContent('group-2'));
|
||||||
|
|
||||||
userEvent.type(filterInput, '{selectall}{del}{{foo=~"b.+"}');
|
await userEvent.clear(filterInput);
|
||||||
|
await userEvent.type(filterInput, '{{foo=~"b.+"}');
|
||||||
await waitFor(() => expect(ui.ruleGroup.queryAll()).toHaveLength(2));
|
await waitFor(() => expect(ui.ruleGroup.queryAll()).toHaveLength(2));
|
||||||
|
|
||||||
userEvent.type(filterInput, '{selectall}{del}{{region="US"}');
|
await userEvent.clear(filterInput);
|
||||||
|
await userEvent.type(filterInput, '{{region="US"}');
|
||||||
await waitFor(() => expect(ui.ruleGroup.queryAll()).toHaveLength(1));
|
await waitFor(() => expect(ui.ruleGroup.queryAll()).toHaveLength(1));
|
||||||
await waitFor(() => expect(ui.ruleGroup.get()).toHaveTextContent('group-2'));
|
await waitFor(() => expect(ui.ruleGroup.get()).toHaveTextContent('group-2'));
|
||||||
});
|
});
|
||||||
@@ -521,7 +524,7 @@ describe('RuleList', () => {
|
|||||||
expect(groups).toHaveLength(3);
|
expect(groups).toHaveLength(3);
|
||||||
|
|
||||||
// open edit dialog
|
// open edit dialog
|
||||||
userEvent.click(ui.editCloudGroupIcon.get(groups[0]));
|
await userEvent.click(ui.editCloudGroupIcon.get(groups[0]));
|
||||||
|
|
||||||
expect(ui.editGroupModal.namespaceInput.get()).toHaveValue('namespace1');
|
expect(ui.editGroupModal.namespaceInput.get()).toHaveValue('namespace1');
|
||||||
expect(ui.editGroupModal.ruleGroupInput.get()).toHaveValue('group1');
|
expect(ui.editGroupModal.ruleGroupInput.get()).toHaveValue('group1');
|
||||||
@@ -531,16 +534,16 @@ describe('RuleList', () => {
|
|||||||
|
|
||||||
testCase('rename both lotex namespace and group', async () => {
|
testCase('rename both lotex namespace and group', async () => {
|
||||||
// make changes to form
|
// make changes to form
|
||||||
userEvent.clear(ui.editGroupModal.namespaceInput.get());
|
await userEvent.clear(ui.editGroupModal.namespaceInput.get());
|
||||||
userEvent.type(ui.editGroupModal.namespaceInput.get(), 'super namespace');
|
await userEvent.type(ui.editGroupModal.namespaceInput.get(), 'super namespace');
|
||||||
|
|
||||||
userEvent.clear(ui.editGroupModal.ruleGroupInput.get());
|
await userEvent.clear(ui.editGroupModal.ruleGroupInput.get());
|
||||||
userEvent.type(ui.editGroupModal.ruleGroupInput.get(), 'super group');
|
await userEvent.type(ui.editGroupModal.ruleGroupInput.get(), 'super group');
|
||||||
|
|
||||||
userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
|
await userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
|
||||||
|
|
||||||
// submit, check that appropriate calls were made
|
// submit, check that appropriate calls were made
|
||||||
userEvent.click(ui.editGroupModal.saveButton.get());
|
await userEvent.click(ui.editGroupModal.saveButton.get());
|
||||||
|
|
||||||
await waitFor(() => expect(ui.editGroupModal.namespaceInput.query()).not.toBeInTheDocument());
|
await waitFor(() => expect(ui.editGroupModal.namespaceInput.query()).not.toBeInTheDocument());
|
||||||
|
|
||||||
@@ -572,12 +575,12 @@ describe('RuleList', () => {
|
|||||||
|
|
||||||
testCase('rename just the lotex group', async () => {
|
testCase('rename just the lotex group', async () => {
|
||||||
// make changes to form
|
// make changes to form
|
||||||
userEvent.clear(ui.editGroupModal.ruleGroupInput.get());
|
await userEvent.clear(ui.editGroupModal.ruleGroupInput.get());
|
||||||
userEvent.type(ui.editGroupModal.ruleGroupInput.get(), 'super group');
|
await userEvent.type(ui.editGroupModal.ruleGroupInput.get(), 'super group');
|
||||||
userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
|
await userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
|
||||||
|
|
||||||
// submit, check that appropriate calls were made
|
// submit, check that appropriate calls were made
|
||||||
userEvent.click(ui.editGroupModal.saveButton.get());
|
await userEvent.click(ui.editGroupModal.saveButton.get());
|
||||||
|
|
||||||
await waitFor(() => expect(ui.editGroupModal.namespaceInput.query()).not.toBeInTheDocument());
|
await waitFor(() => expect(ui.editGroupModal.namespaceInput.query()).not.toBeInTheDocument());
|
||||||
|
|
||||||
@@ -604,10 +607,10 @@ describe('RuleList', () => {
|
|||||||
|
|
||||||
testCase('edit lotex group eval interval, no renaming', async () => {
|
testCase('edit lotex group eval interval, no renaming', async () => {
|
||||||
// make changes to form
|
// make changes to form
|
||||||
userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
|
await userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
|
||||||
|
|
||||||
// submit, check that appropriate calls were made
|
// submit, check that appropriate calls were made
|
||||||
userEvent.click(ui.editGroupModal.saveButton.get());
|
await userEvent.click(ui.editGroupModal.saveButton.get());
|
||||||
|
|
||||||
await waitFor(() => expect(ui.editGroupModal.namespaceInput.query()).not.toBeInTheDocument());
|
await waitFor(() => expect(ui.editGroupModal.namespaceInput.query()).not.toBeInTheDocument());
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@ import { DataSourceType } from './utils/datasource';
|
|||||||
import { parseMatchers } from './utils/alertmanager';
|
import { parseMatchers } from './utils/alertmanager';
|
||||||
import { AlertState, MatcherOperator } from 'app/plugins/datasource/alertmanager/types';
|
import { AlertState, MatcherOperator } from 'app/plugins/datasource/alertmanager/types';
|
||||||
import { byLabelText, byPlaceholderText, byRole, byTestId, byText } from 'testing-library-selector';
|
import { byLabelText, byPlaceholderText, byRole, byTestId, byText } from 'testing-library-selector';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event';
|
||||||
import { contextSrv } from 'app/core/services/context_srv';
|
import { contextSrv } from 'app/core/services/context_srv';
|
||||||
import { AccessControlAction } from 'app/types';
|
import { AccessControlAction } from 'app/types';
|
||||||
|
|
||||||
@@ -171,7 +171,8 @@ describe('Silences', () => {
|
|||||||
await waitFor(() => expect(mocks.api.fetchAlerts).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.api.fetchAlerts).toHaveBeenCalled());
|
||||||
|
|
||||||
const queryBar = ui.queryBar.get();
|
const queryBar = ui.queryBar.get();
|
||||||
userEvent.paste(queryBar, 'foo=bar');
|
await userEvent.click(queryBar);
|
||||||
|
await userEvent.paste('foo=bar');
|
||||||
|
|
||||||
await waitFor(() => expect(ui.silenceRow.getAll()).toHaveLength(1));
|
await waitFor(() => expect(ui.silenceRow.getAll()).toHaveLength(1));
|
||||||
},
|
},
|
||||||
@@ -254,40 +255,40 @@ describe('Silence edit', () => {
|
|||||||
const startDateString = dateTime(start).format('YYYY-MM-DD');
|
const startDateString = dateTime(start).format('YYYY-MM-DD');
|
||||||
const endDateString = dateTime(end).format('YYYY-MM-DD');
|
const endDateString = dateTime(end).format('YYYY-MM-DD');
|
||||||
|
|
||||||
userEvent.clear(ui.editor.durationInput.get());
|
await userEvent.clear(ui.editor.durationInput.get());
|
||||||
userEvent.type(ui.editor.durationInput.get(), '1d');
|
await userEvent.type(ui.editor.durationInput.get(), '1d');
|
||||||
|
|
||||||
await waitFor(() => expect(ui.editor.durationInput.query()).toHaveValue('1d'));
|
await waitFor(() => expect(ui.editor.durationInput.query()).toHaveValue('1d'));
|
||||||
await waitFor(() => expect(ui.editor.timeRange.get()).toHaveTextContent(startDateString));
|
await waitFor(() => expect(ui.editor.timeRange.get()).toHaveTextContent(startDateString));
|
||||||
await waitFor(() => expect(ui.editor.timeRange.get()).toHaveTextContent(endDateString));
|
await waitFor(() => expect(ui.editor.timeRange.get()).toHaveTextContent(endDateString));
|
||||||
|
|
||||||
userEvent.type(ui.editor.matcherName.get(), 'foo');
|
await userEvent.type(ui.editor.matcherName.get(), 'foo');
|
||||||
userEvent.type(ui.editor.matcherOperatorSelect.get(), '=');
|
await userEvent.type(ui.editor.matcherOperatorSelect.get(), '=');
|
||||||
userEvent.tab();
|
await userEvent.tab();
|
||||||
userEvent.type(ui.editor.matcherValue.get(), 'bar');
|
await userEvent.type(ui.editor.matcherValue.get(), 'bar');
|
||||||
|
|
||||||
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
||||||
userEvent.click(ui.editor.addMatcherButton.get(), undefined, { skipPointerEventsCheck: true });
|
await userEvent.click(ui.editor.addMatcherButton.get(), { pointerEventsCheck: PointerEventsCheckLevel.Never });
|
||||||
userEvent.type(ui.editor.matcherName.getAll()[1], 'bar');
|
await userEvent.type(ui.editor.matcherName.getAll()[1], 'bar');
|
||||||
userEvent.type(ui.editor.matcherOperatorSelect.getAll()[1], '!=');
|
await userEvent.type(ui.editor.matcherOperatorSelect.getAll()[1], '!=');
|
||||||
userEvent.tab();
|
await userEvent.tab();
|
||||||
userEvent.type(ui.editor.matcherValue.getAll()[1], 'buzz');
|
await userEvent.type(ui.editor.matcherValue.getAll()[1], 'buzz');
|
||||||
|
|
||||||
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
||||||
userEvent.click(ui.editor.addMatcherButton.get(), undefined, { skipPointerEventsCheck: true });
|
await userEvent.click(ui.editor.addMatcherButton.get(), { pointerEventsCheck: PointerEventsCheckLevel.Never });
|
||||||
userEvent.type(ui.editor.matcherName.getAll()[2], 'region');
|
await userEvent.type(ui.editor.matcherName.getAll()[2], 'region');
|
||||||
userEvent.type(ui.editor.matcherOperatorSelect.getAll()[2], '=~');
|
await userEvent.type(ui.editor.matcherOperatorSelect.getAll()[2], '=~');
|
||||||
userEvent.tab();
|
await userEvent.tab();
|
||||||
userEvent.type(ui.editor.matcherValue.getAll()[2], 'us-west-.*');
|
await userEvent.type(ui.editor.matcherValue.getAll()[2], 'us-west-.*');
|
||||||
|
|
||||||
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
||||||
userEvent.click(ui.editor.addMatcherButton.get(), undefined, { skipPointerEventsCheck: true });
|
await userEvent.click(ui.editor.addMatcherButton.get(), { pointerEventsCheck: PointerEventsCheckLevel.Never });
|
||||||
userEvent.type(ui.editor.matcherName.getAll()[3], 'env');
|
await userEvent.type(ui.editor.matcherName.getAll()[3], 'env');
|
||||||
userEvent.type(ui.editor.matcherOperatorSelect.getAll()[3], '!~');
|
await userEvent.type(ui.editor.matcherOperatorSelect.getAll()[3], '!~');
|
||||||
userEvent.tab();
|
await userEvent.tab();
|
||||||
userEvent.type(ui.editor.matcherValue.getAll()[3], 'dev|staging');
|
await userEvent.type(ui.editor.matcherValue.getAll()[3], 'dev|staging');
|
||||||
|
|
||||||
userEvent.click(ui.editor.submit.get());
|
await userEvent.click(ui.editor.submit.get());
|
||||||
|
|
||||||
await waitFor(() =>
|
await waitFor(() =>
|
||||||
expect(mocks.api.createOrUpdateSilence).toHaveBeenCalledWith(
|
expect(mocks.api.createOrUpdateSilence).toHaveBeenCalledWith(
|
||||||
|
@@ -104,8 +104,8 @@ describe('Admin config', () => {
|
|||||||
|
|
||||||
await renderAdminPage(dataSources.alertManager.name);
|
await renderAdminPage(dataSources.alertManager.name);
|
||||||
|
|
||||||
userEvent.click(await ui.resetButton.find());
|
await userEvent.click(await ui.resetButton.find());
|
||||||
userEvent.click(ui.confirmButton.get());
|
await userEvent.click(ui.confirmButton.get());
|
||||||
await waitFor(() => expect(mocks.api.deleteAlertManagerConfig).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.api.deleteAlertManagerConfig).toHaveBeenCalled());
|
||||||
expect(ui.confirmButton.query()).not.toBeInTheDocument();
|
expect(ui.confirmButton.query()).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
@@ -132,12 +132,12 @@ describe('Admin config', () => {
|
|||||||
await renderAdminPage(dataSources.alertManager.name);
|
await renderAdminPage(dataSources.alertManager.name);
|
||||||
const input = await ui.configInput.find();
|
const input = await ui.configInput.find();
|
||||||
expect(input.value).toEqual(JSON.stringify(defaultConfig, null, 2));
|
expect(input.value).toEqual(JSON.stringify(defaultConfig, null, 2));
|
||||||
userEvent.clear(input);
|
await userEvent.clear(input);
|
||||||
// What is this regex replace doing? in userEvent v13, '{' and '[' are special characters.
|
// What is this regex replace doing? in userEvent v13, '{' and '[' are special characters.
|
||||||
// To get the literal character, you have to escape them by typing '{{' or '[['.
|
// To get the literal character, you have to escape them by typing '{{' or '[['.
|
||||||
// See https://github.com/testing-library/user-event/issues/584.
|
// See https://github.com/testing-library/user-event/issues/584.
|
||||||
userEvent.type(input, JSON.stringify(newConfig, null, 2).replace(/[{[]/g, '$&$&'));
|
await userEvent.type(input, JSON.stringify(newConfig, null, 2).replace(/[{[]/g, '$&$&'));
|
||||||
userEvent.click(ui.saveButton.get());
|
await userEvent.click(ui.saveButton.get());
|
||||||
await waitFor(() => expect(mocks.api.updateAlertManagerConfig).toHaveBeenCalled());
|
await waitFor(() => expect(mocks.api.updateAlertManagerConfig).toHaveBeenCalled());
|
||||||
await waitFor(() => expect(mocks.api.fetchConfig).toHaveBeenCalledTimes(3));
|
await waitFor(() => expect(mocks.api.fetchConfig).toHaveBeenCalledTimes(3));
|
||||||
expect(input.value).toEqual(JSON.stringify(newConfig, null, 2));
|
expect(input.value).toEqual(JSON.stringify(newConfig, null, 2));
|
||||||
|
@@ -95,13 +95,13 @@ describe('Rules group tests', () => {
|
|||||||
expect(ui.editGroupButton.query()).not.toBeInTheDocument();
|
expect(ui.editGroupButton.query()).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Delete button click should display confirmation modal', () => {
|
it('Delete button click should display confirmation modal', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
hasRulerMock.mockReturnValue(true);
|
hasRulerMock.mockReturnValue(true);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
renderRulesGroup(namespace, group);
|
renderRulesGroup(namespace, group);
|
||||||
userEvent.click(ui.deleteGroupButton.get());
|
await userEvent.click(ui.deleteGroupButton.get());
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(ui.confirmDeleteModal.header.get()).toBeInTheDocument();
|
expect(ui.confirmDeleteModal.header.get()).toBeInTheDocument();
|
||||||
|
@@ -7,7 +7,7 @@ import { setSearchQuery } from './state/reducers';
|
|||||||
import { mockToolkitActionCreator } from '../../../test/core/redux/mocks';
|
import { mockToolkitActionCreator } from '../../../test/core/redux/mocks';
|
||||||
import { getMultipleMockKeys } from './__mocks__/apiKeysMock';
|
import { getMultipleMockKeys } from './__mocks__/apiKeysMock';
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event';
|
||||||
import { silenceConsoleOutput } from '../../../test/core/utils/silenceConsoleOutput';
|
import { silenceConsoleOutput } from '../../../test/core/utils/silenceConsoleOutput';
|
||||||
|
|
||||||
const setup = (propOverrides: Partial<Props>) => {
|
const setup = (propOverrides: Partial<Props>) => {
|
||||||
@@ -100,7 +100,7 @@ describe('ApiKeysPage', () => {
|
|||||||
const apiKeys = getMultipleMockKeys(3);
|
const apiKeys = getMultipleMockKeys(3);
|
||||||
const { toggleIncludeExpiredMock } = setup({ apiKeys, apiKeysCount: apiKeys.length, hasFetched: true });
|
const { toggleIncludeExpiredMock } = setup({ apiKeys, apiKeysCount: apiKeys.length, hasFetched: true });
|
||||||
|
|
||||||
toggleShowExpired();
|
await toggleShowExpired();
|
||||||
expect(toggleIncludeExpiredMock).toHaveBeenCalledTimes(1);
|
expect(toggleIncludeExpiredMock).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -112,7 +112,7 @@ describe('ApiKeysPage', () => {
|
|||||||
|
|
||||||
setSearchQueryMock.mockClear();
|
setSearchQueryMock.mockClear();
|
||||||
expect(screen.getByPlaceholderText(/search keys/i)).toBeInTheDocument();
|
expect(screen.getByPlaceholderText(/search keys/i)).toBeInTheDocument();
|
||||||
userEvent.type(screen.getByPlaceholderText(/search keys/i), 'First');
|
await userEvent.type(screen.getByPlaceholderText(/search keys/i), 'First');
|
||||||
expect(setSearchQueryMock).toHaveBeenCalledTimes(5);
|
expect(setSearchQueryMock).toHaveBeenCalledTimes(5);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -130,21 +130,21 @@ describe('ApiKeysPage', () => {
|
|||||||
|
|
||||||
deleteApiKeyMock.mockClear();
|
deleteApiKeyMock.mockClear();
|
||||||
expect(within(firstRow).getByLabelText('Delete API key')).toBeInTheDocument();
|
expect(within(firstRow).getByLabelText('Delete API key')).toBeInTheDocument();
|
||||||
userEvent.click(within(firstRow).getByLabelText('Delete API key'));
|
await userEvent.click(within(firstRow).getByLabelText('Delete API key'));
|
||||||
|
|
||||||
expect(within(firstRow).getByRole('button', { name: /delete$/i })).toBeInTheDocument();
|
expect(within(firstRow).getByRole('button', { name: /delete$/i })).toBeInTheDocument();
|
||||||
userEvent.click(within(firstRow).getByRole('button', { name: /delete$/i }));
|
await userEvent.click(within(firstRow).getByRole('button', { name: /delete$/i }));
|
||||||
expect(deleteApiKeyMock).toHaveBeenCalledTimes(1);
|
expect(deleteApiKeyMock).toHaveBeenCalledTimes(1);
|
||||||
expect(deleteApiKeyMock).toHaveBeenCalledWith(1);
|
expect(deleteApiKeyMock).toHaveBeenCalledWith(1);
|
||||||
|
|
||||||
toggleShowExpired();
|
await toggleShowExpired();
|
||||||
|
|
||||||
deleteApiKeyMock.mockClear();
|
deleteApiKeyMock.mockClear();
|
||||||
expect(within(secondRow).getByLabelText('Delete API key')).toBeInTheDocument();
|
expect(within(secondRow).getByLabelText('Delete API key')).toBeInTheDocument();
|
||||||
userEvent.click(within(secondRow).getByLabelText('Delete API key'));
|
await userEvent.click(within(secondRow).getByLabelText('Delete API key'));
|
||||||
expect(within(secondRow).getByRole('button', { name: /delete$/i })).toBeInTheDocument();
|
expect(within(secondRow).getByRole('button', { name: /delete$/i })).toBeInTheDocument();
|
||||||
userEvent.click(within(secondRow).getByRole('button', { name: /delete$/i }), undefined, {
|
await userEvent.click(within(secondRow).getByRole('button', { name: /delete$/i }), {
|
||||||
skipPointerEventsCheck: true,
|
pointerEventsCheck: PointerEventsCheckLevel.Never,
|
||||||
});
|
});
|
||||||
expect(deleteApiKeyMock).toHaveBeenCalledTimes(1);
|
expect(deleteApiKeyMock).toHaveBeenCalledTimes(1);
|
||||||
expect(deleteApiKeyMock).toHaveBeenCalledWith(2);
|
expect(deleteApiKeyMock).toHaveBeenCalledWith(2);
|
||||||
@@ -157,7 +157,7 @@ describe('ApiKeysPage', () => {
|
|||||||
const { addApiKeyMock } = setup({ apiKeys, apiKeysCount: apiKeys.length, hasFetched: true });
|
const { addApiKeyMock } = setup({ apiKeys, apiKeysCount: apiKeys.length, hasFetched: true });
|
||||||
|
|
||||||
addApiKeyMock.mockClear();
|
addApiKeyMock.mockClear();
|
||||||
userEvent.click(screen.getByTestId(selectors.components.CallToActionCard.buttonV2('New API key')));
|
await userEvent.click(screen.getByTestId(selectors.components.CallToActionCard.buttonV2('New API key')));
|
||||||
await addAndVerifyApiKey(addApiKeyMock);
|
await addAndVerifyApiKey(addApiKeyMock);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -168,13 +168,13 @@ describe('ApiKeysPage', () => {
|
|||||||
const { addApiKeyMock } = setup({ apiKeys, apiKeysCount: apiKeys.length, hasFetched: true });
|
const { addApiKeyMock } = setup({ apiKeys, apiKeysCount: apiKeys.length, hasFetched: true });
|
||||||
|
|
||||||
addApiKeyMock.mockClear();
|
addApiKeyMock.mockClear();
|
||||||
userEvent.click(screen.getByRole('button', { name: /add api key/i }));
|
await userEvent.click(screen.getByRole('button', { name: /add api key/i }));
|
||||||
await addAndVerifyApiKey(addApiKeyMock);
|
await addAndVerifyApiKey(addApiKeyMock);
|
||||||
|
|
||||||
toggleShowExpired();
|
await toggleShowExpired();
|
||||||
|
|
||||||
addApiKeyMock.mockClear();
|
addApiKeyMock.mockClear();
|
||||||
userEvent.click(screen.getByRole('button', { name: /add api key/i }));
|
await userEvent.click(screen.getByRole('button', { name: /add api key/i }));
|
||||||
await addAndVerifyApiKey(addApiKeyMock);
|
await addAndVerifyApiKey(addApiKeyMock);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -185,20 +185,20 @@ describe('ApiKeysPage', () => {
|
|||||||
const { addApiKeyMock } = setup({ apiKeys, apiKeysCount: apiKeys.length, hasFetched: true });
|
const { addApiKeyMock } = setup({ apiKeys, apiKeysCount: apiKeys.length, hasFetched: true });
|
||||||
|
|
||||||
addApiKeyMock.mockClear();
|
addApiKeyMock.mockClear();
|
||||||
userEvent.click(screen.getByRole('button', { name: /add api key/i }));
|
await userEvent.click(screen.getByRole('button', { name: /add api key/i }));
|
||||||
userEvent.type(screen.getByPlaceholderText(/name/i), 'Test');
|
await userEvent.type(screen.getByPlaceholderText(/name/i), 'Test');
|
||||||
userEvent.type(screen.getByPlaceholderText(/1d/i), '60x');
|
await userEvent.type(screen.getByPlaceholderText(/1d/i), '60x');
|
||||||
expect(screen.queryByText(/not a valid duration/i)).not.toBeInTheDocument();
|
expect(screen.queryByText(/not a valid duration/i)).not.toBeInTheDocument();
|
||||||
userEvent.click(screen.getByRole('button', { name: /^add$/i }));
|
await userEvent.click(screen.getByRole('button', { name: /^add$/i }));
|
||||||
expect(screen.getByText(/not a valid duration/i)).toBeInTheDocument();
|
expect(screen.getByText(/not a valid duration/i)).toBeInTheDocument();
|
||||||
expect(addApiKeyMock).toHaveBeenCalledTimes(0);
|
expect(addApiKeyMock).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function toggleShowExpired() {
|
async function toggleShowExpired() {
|
||||||
expect(screen.queryByLabelText(/include expired keys/i)).toBeInTheDocument();
|
expect(screen.queryByLabelText(/include expired keys/i)).toBeInTheDocument();
|
||||||
userEvent.click(screen.getByLabelText(/include expired keys/i));
|
await userEvent.click(screen.getByLabelText(/include expired keys/i));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addAndVerifyApiKey(addApiKeyMock: jest.Mock) {
|
async function addAndVerifyApiKey(addApiKeyMock: jest.Mock) {
|
||||||
@@ -207,9 +207,9 @@ async function addAndVerifyApiKey(addApiKeyMock: jest.Mock) {
|
|||||||
expect(screen.getByPlaceholderText(/1d/i)).toBeInTheDocument();
|
expect(screen.getByPlaceholderText(/1d/i)).toBeInTheDocument();
|
||||||
expect(screen.getByRole('button', { name: /^add$/i })).toBeInTheDocument();
|
expect(screen.getByRole('button', { name: /^add$/i })).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.type(screen.getByPlaceholderText(/name/i), 'Test');
|
await userEvent.type(screen.getByPlaceholderText(/name/i), 'Test');
|
||||||
userEvent.type(screen.getByPlaceholderText(/1d/i), '60s');
|
await userEvent.type(screen.getByPlaceholderText(/1d/i), '60s');
|
||||||
userEvent.click(screen.getByRole('button', { name: /^add$/i }));
|
await userEvent.click(screen.getByRole('button', { name: /^add$/i }));
|
||||||
expect(addApiKeyMock).toHaveBeenCalledTimes(1);
|
expect(addApiKeyMock).toHaveBeenCalledTimes(1);
|
||||||
expect(addApiKeyMock).toHaveBeenCalledWith({ name: 'Test', role: 'Viewer', secondsToLive: 60 }, expect.anything());
|
expect(addApiKeyMock).toHaveBeenCalledWith({ name: 'Test', role: 'Viewer', secondsToLive: 60 }, expect.anything());
|
||||||
}
|
}
|
||||||
|
@@ -76,7 +76,7 @@ describe('AnnotationsSettings', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it renders a header and cta if no annotations or only builtIn annotation', () => {
|
test('it renders a header and cta if no annotations or only builtIn annotation', async () => {
|
||||||
render(<AnnotationsSettings dashboard={dashboard} />);
|
render(<AnnotationsSettings dashboard={dashboard} />);
|
||||||
|
|
||||||
expect(screen.getByRole('heading', { name: /annotations/i })).toBeInTheDocument();
|
expect(screen.getByRole('heading', { name: /annotations/i })).toBeInTheDocument();
|
||||||
@@ -87,7 +87,7 @@ describe('AnnotationsSettings', () => {
|
|||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
expect(screen.queryByRole('link', { name: /annotations documentation/i })).toBeInTheDocument();
|
expect(screen.queryByRole('link', { name: /annotations documentation/i })).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('cell', { name: /annotations & alerts \(built\-in\)/i }));
|
await userEvent.click(screen.getByRole('cell', { name: /annotations & alerts \(built\-in\)/i }));
|
||||||
|
|
||||||
const heading = screen.getByRole('heading', {
|
const heading = screen.getByRole('heading', {
|
||||||
name: /annotations edit/i,
|
name: /annotations edit/i,
|
||||||
@@ -96,13 +96,13 @@ describe('AnnotationsSettings', () => {
|
|||||||
|
|
||||||
expect(heading).toBeInTheDocument();
|
expect(heading).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.clear(nameInput);
|
await userEvent.clear(nameInput);
|
||||||
userEvent.type(nameInput, 'My Annotation');
|
await userEvent.type(nameInput, 'My Annotation');
|
||||||
|
|
||||||
expect(screen.queryByText(/grafana/i)).toBeInTheDocument();
|
expect(screen.queryByText(/grafana/i)).toBeInTheDocument();
|
||||||
expect(screen.getByRole('checkbox', { name: /hidden/i })).toBeChecked();
|
expect(screen.getByRole('checkbox', { name: /hidden/i })).toBeChecked();
|
||||||
|
|
||||||
userEvent.click(within(heading).getByText(/annotations/i));
|
await userEvent.click(within(heading).getByText(/annotations/i));
|
||||||
|
|
||||||
expect(screen.getByRole('table')).toBeInTheDocument();
|
expect(screen.getByRole('table')).toBeInTheDocument();
|
||||||
expect(screen.getByRole('row', { name: /my annotation \(built\-in\) grafana/i })).toBeInTheDocument();
|
expect(screen.getByRole('row', { name: /my annotation \(built\-in\) grafana/i })).toBeInTheDocument();
|
||||||
@@ -111,8 +111,8 @@ describe('AnnotationsSettings', () => {
|
|||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
expect(screen.queryByRole('button', { name: /new query/i })).not.toBeInTheDocument();
|
expect(screen.queryByRole('button', { name: /new query/i })).not.toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getAllByLabelText(/Delete query with title/)[0]);
|
await userEvent.click(screen.getAllByLabelText(/Delete query with title/)[0]);
|
||||||
userEvent.click(screen.getByRole('button', { name: 'Delete' }));
|
await userEvent.click(screen.getByRole('button', { name: 'Delete' }));
|
||||||
|
|
||||||
expect(screen.queryAllByRole('row').length).toBe(0);
|
expect(screen.queryAllByRole('row').length).toBe(0);
|
||||||
expect(
|
expect(
|
||||||
@@ -120,7 +120,7 @@ describe('AnnotationsSettings', () => {
|
|||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it renders a sortable table of annotations', () => {
|
test('it renders a sortable table of annotations', async () => {
|
||||||
const annotationsList = [
|
const annotationsList = [
|
||||||
...dashboard.annotations.list,
|
...dashboard.annotations.list,
|
||||||
{
|
{
|
||||||
@@ -164,9 +164,9 @@ describe('AnnotationsSettings', () => {
|
|||||||
expect(within(getTableBodyRows()[1]).queryByText(/annotation 2/i)).toBeInTheDocument();
|
expect(within(getTableBodyRows()[1]).queryByText(/annotation 2/i)).toBeInTheDocument();
|
||||||
expect(within(getTableBodyRows()[2]).queryByText(/annotation 3/i)).toBeInTheDocument();
|
expect(within(getTableBodyRows()[2]).queryByText(/annotation 3/i)).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[0]);
|
await userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[0]);
|
||||||
userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[1]);
|
await userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[1]);
|
||||||
userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-up' })[0]);
|
await userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-up' })[0]);
|
||||||
|
|
||||||
// Checking if it has changed the sorting accordingly
|
// Checking if it has changed the sorting accordingly
|
||||||
expect(within(getTableBodyRows()[0]).queryByText(/annotation 3/i)).toBeInTheDocument();
|
expect(within(getTableBodyRows()[0]).queryByText(/annotation 3/i)).toBeInTheDocument();
|
||||||
@@ -177,7 +177,7 @@ describe('AnnotationsSettings', () => {
|
|||||||
test('it renders a form for adding/editing annotations', async () => {
|
test('it renders a form for adding/editing annotations', async () => {
|
||||||
render(<AnnotationsSettings dashboard={dashboard} />);
|
render(<AnnotationsSettings dashboard={dashboard} />);
|
||||||
|
|
||||||
userEvent.click(screen.getByTestId(selectors.components.CallToActionCard.buttonV2('Add annotation query')));
|
await userEvent.click(screen.getByTestId(selectors.components.CallToActionCard.buttonV2('Add annotation query')));
|
||||||
|
|
||||||
const heading = screen.getByRole('heading', {
|
const heading = screen.getByRole('heading', {
|
||||||
name: /annotations edit/i,
|
name: /annotations edit/i,
|
||||||
@@ -186,19 +186,19 @@ describe('AnnotationsSettings', () => {
|
|||||||
|
|
||||||
expect(heading).toBeInTheDocument();
|
expect(heading).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.clear(nameInput);
|
await userEvent.clear(nameInput);
|
||||||
userEvent.type(nameInput, 'My Prometheus Annotation');
|
await userEvent.type(nameInput, 'My Prometheus Annotation');
|
||||||
|
|
||||||
userEvent.click(screen.getByText(/testdata/i));
|
await userEvent.click(screen.getByText(/testdata/i));
|
||||||
|
|
||||||
expect(await screen.findByText(/Prometheus/i)).toBeVisible();
|
expect(await screen.findByText(/Prometheus/i)).toBeVisible();
|
||||||
expect(screen.queryAllByText(/testdata/i)).toHaveLength(2);
|
expect(screen.queryAllByText(/testdata/i)).toHaveLength(2);
|
||||||
|
|
||||||
userEvent.click(screen.getByText(/prometheus/i));
|
await userEvent.click(screen.getByText(/prometheus/i));
|
||||||
|
|
||||||
expect(screen.getByRole('checkbox', { name: /hidden/i })).not.toBeChecked();
|
expect(screen.getByRole('checkbox', { name: /hidden/i })).not.toBeChecked();
|
||||||
|
|
||||||
userEvent.click(within(heading).getByText(/annotations/i));
|
await userEvent.click(within(heading).getByText(/annotations/i));
|
||||||
|
|
||||||
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(2);
|
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(2);
|
||||||
expect(screen.queryByRole('row', { name: /my prometheus annotation prometheus/i })).toBeInTheDocument();
|
expect(screen.queryByRole('row', { name: /my prometheus annotation prometheus/i })).toBeInTheDocument();
|
||||||
@@ -207,14 +207,14 @@ describe('AnnotationsSettings', () => {
|
|||||||
screen.queryByTestId(selectors.components.CallToActionCard.buttonV2('Add annotation query'))
|
screen.queryByTestId(selectors.components.CallToActionCard.buttonV2('Add annotation query'))
|
||||||
).not.toBeInTheDocument();
|
).not.toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: /new query/i }));
|
await userEvent.click(screen.getByRole('button', { name: /new query/i }));
|
||||||
|
|
||||||
userEvent.click(within(screen.getByRole('heading', { name: /annotations edit/i })).getByText(/annotations/i));
|
await userEvent.click(within(screen.getByRole('heading', { name: /annotations edit/i })).getByText(/annotations/i));
|
||||||
|
|
||||||
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(3);
|
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(3);
|
||||||
|
|
||||||
userEvent.click(screen.getAllByLabelText(/Delete query with title/)[0]);
|
await userEvent.click(screen.getAllByLabelText(/Delete query with title/)[0]);
|
||||||
userEvent.click(screen.getByRole('button', { name: 'Delete' }));
|
await userEvent.click(screen.getByRole('button', { name: 'Delete' }));
|
||||||
|
|
||||||
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(2);
|
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(2);
|
||||||
});
|
});
|
||||||
|
@@ -49,11 +49,11 @@ describe('AutoRefreshIntervals', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('when input loses focus and intervals are valid', () => {
|
describe('when input loses focus and intervals are valid', () => {
|
||||||
it('then onRefreshIntervalChange should be called', () => {
|
it('then onRefreshIntervalChange should be called', async () => {
|
||||||
const { props } = setupTestContext({ validateIntervalsFunc: () => null });
|
const { props } = setupTestContext({ validateIntervalsFunc: () => null });
|
||||||
|
|
||||||
userEvent.type(screen.getByRole('textbox'), ',30s');
|
await userEvent.type(screen.getByRole('textbox'), ',30s');
|
||||||
userEvent.tab();
|
await userEvent.tab();
|
||||||
|
|
||||||
expect(screen.getByRole('textbox')).toHaveValue('1s,5s,10s,30s');
|
expect(screen.getByRole('textbox')).toHaveValue('1s,5s,10s,30s');
|
||||||
expect(props.onRefreshIntervalChange).toHaveBeenCalledTimes(1);
|
expect(props.onRefreshIntervalChange).toHaveBeenCalledTimes(1);
|
||||||
@@ -62,11 +62,11 @@ describe('AutoRefreshIntervals', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('when input loses focus and intervals are invalid', () => {
|
describe('when input loses focus and intervals are invalid', () => {
|
||||||
it('then onRefreshIntervalChange should not be called', () => {
|
it('then onRefreshIntervalChange should not be called', async () => {
|
||||||
const { props } = setupTestContext({ validateIntervalsFunc: () => 'Not valid' });
|
const { props } = setupTestContext({ validateIntervalsFunc: () => 'Not valid' });
|
||||||
|
|
||||||
userEvent.type(screen.getByRole('textbox'), ',30q');
|
await userEvent.type(screen.getByRole('textbox'), ',30q');
|
||||||
userEvent.tab();
|
await userEvent.tab();
|
||||||
|
|
||||||
expect(screen.getByRole('textbox')).toHaveValue('1s,5s,10s,30q');
|
expect(screen.getByRole('textbox')).toHaveValue('1s,5s,10s,30q');
|
||||||
expect(props.onRefreshIntervalChange).toHaveBeenCalledTimes(0);
|
expect(props.onRefreshIntervalChange).toHaveBeenCalledTimes(0);
|
||||||
@@ -74,14 +74,14 @@ describe('AutoRefreshIntervals', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('when input loses focus and previous intervals were invalid', () => {
|
describe('when input loses focus and previous intervals were invalid', () => {
|
||||||
it('then onRefreshIntervalChange should be called', () => {
|
it('then onRefreshIntervalChange should be called', async () => {
|
||||||
const validateIntervalsFunc = jest.fn().mockReturnValueOnce('Not valid').mockReturnValue(null);
|
const validateIntervalsFunc = jest.fn().mockReturnValueOnce('Not valid').mockReturnValue(null);
|
||||||
const { props } = setupTestContext({ validateIntervalsFunc });
|
const { props } = setupTestContext({ validateIntervalsFunc });
|
||||||
|
|
||||||
userEvent.type(screen.getByRole('textbox'), ',30q');
|
await userEvent.type(screen.getByRole('textbox'), ',30q');
|
||||||
userEvent.tab();
|
await userEvent.tab();
|
||||||
userEvent.type(screen.getByRole('textbox'), '{backspace}s');
|
await userEvent.type(screen.getByRole('textbox'), '{backspace}s');
|
||||||
userEvent.tab();
|
await userEvent.tab();
|
||||||
|
|
||||||
expect(screen.getByRole('textbox')).toHaveValue('1s,5s,10s,30s');
|
expect(screen.getByRole('textbox')).toHaveValue('1s,5s,10s,30s');
|
||||||
expect(props.onRefreshIntervalChange).toHaveBeenCalledTimes(1);
|
expect(props.onRefreshIntervalChange).toHaveBeenCalledTimes(1);
|
||||||
|
@@ -48,9 +48,9 @@ describe('General Settings', () => {
|
|||||||
describe('when timezone is changed', () => {
|
describe('when timezone is changed', () => {
|
||||||
it('should call update function', async () => {
|
it('should call update function', async () => {
|
||||||
const { props } = setupTestContext({});
|
const { props } = setupTestContext({});
|
||||||
userEvent.click(screen.getByTestId(selectors.components.TimeZonePicker.containerV2));
|
await userEvent.click(screen.getByTestId(selectors.components.TimeZonePicker.containerV2));
|
||||||
const timeZonePicker = screen.getByTestId(selectors.components.TimeZonePicker.containerV2);
|
const timeZonePicker = screen.getByTestId(selectors.components.TimeZonePicker.containerV2);
|
||||||
userEvent.click(byRole('combobox').get(timeZonePicker));
|
await userEvent.click(byRole('combobox').get(timeZonePicker));
|
||||||
await selectOptionInTest(timeZonePicker, 'Browser Time');
|
await selectOptionInTest(timeZonePicker, 'Browser Time');
|
||||||
expect(props.updateTimeZone).toHaveBeenCalledWith('browser');
|
expect(props.updateTimeZone).toHaveBeenCalledWith('browser');
|
||||||
expect(props.dashboard.timezone).toBe('browser');
|
expect(props.dashboard.timezone).toBe('browser');
|
||||||
|
@@ -84,7 +84,7 @@ describe('LinksSettings', () => {
|
|||||||
).not.toBeInTheDocument();
|
).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it rearranges the order of dashboard links', () => {
|
test('it rearranges the order of dashboard links', async () => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
render(<LinksSettings dashboard={dashboard} />);
|
render(<LinksSettings dashboard={dashboard} />);
|
||||||
|
|
||||||
@@ -103,9 +103,9 @@ describe('LinksSettings', () => {
|
|||||||
assertRowHasText(1, links[1].title);
|
assertRowHasText(1, links[1].title);
|
||||||
assertRowHasText(2, links[2].url);
|
assertRowHasText(2, links[2].url);
|
||||||
|
|
||||||
userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[0]);
|
await userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[0]);
|
||||||
userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[1]);
|
await userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[1]);
|
||||||
userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-up' })[0]);
|
await userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-up' })[0]);
|
||||||
|
|
||||||
// Checking if it has changed the sorting accordingly
|
// Checking if it has changed the sorting accordingly
|
||||||
assertRowHasText(0, links[2].url);
|
assertRowHasText(0, links[2].url);
|
||||||
@@ -113,35 +113,35 @@ describe('LinksSettings', () => {
|
|||||||
assertRowHasText(2, links[0].title);
|
assertRowHasText(2, links[0].title);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it duplicates dashboard links', () => {
|
test('it duplicates dashboard links', async () => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
render(<LinksSettings dashboard={dashboard} />);
|
render(<LinksSettings dashboard={dashboard} />);
|
||||||
|
|
||||||
expect(getTableBodyRows().length).toBe(links.length);
|
expect(getTableBodyRows().length).toBe(links.length);
|
||||||
|
|
||||||
userEvent.click(within(getTableBody()).getAllByRole('button', { name: /copy/i })[0]);
|
await userEvent.click(within(getTableBody()).getAllByRole('button', { name: /copy/i })[0]);
|
||||||
|
|
||||||
expect(getTableBodyRows().length).toBe(links.length + 1);
|
expect(getTableBodyRows().length).toBe(links.length + 1);
|
||||||
expect(within(getTableBody()).getAllByText(links[0].title).length).toBe(2);
|
expect(within(getTableBody()).getAllByText(links[0].title).length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it deletes dashboard links', () => {
|
test('it deletes dashboard links', async () => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
render(<LinksSettings dashboard={dashboard} />);
|
render(<LinksSettings dashboard={dashboard} />);
|
||||||
|
|
||||||
expect(getTableBodyRows().length).toBe(links.length);
|
expect(getTableBodyRows().length).toBe(links.length);
|
||||||
|
|
||||||
userEvent.click(within(getTableBody()).getAllByLabelText(/Delete link with title/)[0]);
|
await userEvent.click(within(getTableBody()).getAllByLabelText(/Delete link with title/)[0]);
|
||||||
userEvent.click(within(getTableBody()).getByRole('button', { name: 'Delete' }));
|
await userEvent.click(within(getTableBody()).getByRole('button', { name: 'Delete' }));
|
||||||
|
|
||||||
expect(getTableBodyRows().length).toBe(links.length - 1);
|
expect(getTableBodyRows().length).toBe(links.length - 1);
|
||||||
expect(within(getTableBody()).queryByText(links[0].title)).not.toBeInTheDocument();
|
expect(within(getTableBody()).queryByText(links[0].title)).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it renders a form which modifies dashboard links', () => {
|
test('it renders a form which modifies dashboard links', async () => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
render(<LinksSettings dashboard={dashboard} />);
|
render(<LinksSettings dashboard={dashboard} />);
|
||||||
userEvent.click(screen.getByRole('button', { name: /new/i }));
|
await userEvent.click(screen.getByRole('button', { name: /new/i }));
|
||||||
|
|
||||||
expect(screen.queryByText('Type')).toBeInTheDocument();
|
expect(screen.queryByText('Type')).toBeInTheDocument();
|
||||||
expect(screen.queryByText('Title')).toBeInTheDocument();
|
expect(screen.queryByText('Title')).toBeInTheDocument();
|
||||||
@@ -151,29 +151,29 @@ describe('LinksSettings', () => {
|
|||||||
expect(screen.queryByText('Tooltip')).not.toBeInTheDocument();
|
expect(screen.queryByText('Tooltip')).not.toBeInTheDocument();
|
||||||
expect(screen.queryByText('Icon')).not.toBeInTheDocument();
|
expect(screen.queryByText('Icon')).not.toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getByText('Dashboards'));
|
await userEvent.click(screen.getByText('Dashboards'));
|
||||||
expect(screen.queryAllByText('Dashboards')).toHaveLength(2);
|
expect(screen.queryAllByText('Dashboards')).toHaveLength(2);
|
||||||
expect(screen.queryByText('Link')).toBeVisible();
|
expect(screen.queryByText('Link')).toBeVisible();
|
||||||
|
|
||||||
userEvent.click(screen.getByText('Link'));
|
await userEvent.click(screen.getByText('Link'));
|
||||||
|
|
||||||
expect(screen.queryByText('URL')).toBeInTheDocument();
|
expect(screen.queryByText('URL')).toBeInTheDocument();
|
||||||
expect(screen.queryByText('Tooltip')).toBeInTheDocument();
|
expect(screen.queryByText('Tooltip')).toBeInTheDocument();
|
||||||
expect(screen.queryByText('Icon')).toBeInTheDocument();
|
expect(screen.queryByText('Icon')).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.clear(screen.getByRole('textbox', { name: /title/i }));
|
await userEvent.clear(screen.getByRole('textbox', { name: /title/i }));
|
||||||
userEvent.type(screen.getByRole('textbox', { name: /title/i }), 'New Dashboard Link');
|
await userEvent.type(screen.getByRole('textbox', { name: /title/i }), 'New Dashboard Link');
|
||||||
userEvent.click(
|
await userEvent.click(
|
||||||
within(screen.getByRole('heading', { name: /dashboard links edit/i })).getByText(/dashboard links/i)
|
within(screen.getByRole('heading', { name: /dashboard links edit/i })).getByText(/dashboard links/i)
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(getTableBodyRows().length).toBe(links.length + 1);
|
expect(getTableBodyRows().length).toBe(links.length + 1);
|
||||||
expect(within(getTableBody()).queryByText('New Dashboard Link')).toBeInTheDocument();
|
expect(within(getTableBody()).queryByText('New Dashboard Link')).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getAllByText(links[0].type)[0]);
|
await userEvent.click(screen.getAllByText(links[0].type)[0]);
|
||||||
userEvent.clear(screen.getByRole('textbox', { name: /title/i }));
|
await userEvent.clear(screen.getByRole('textbox', { name: /title/i }));
|
||||||
userEvent.type(screen.getByRole('textbox', { name: /title/i }), 'The first dashboard link');
|
await userEvent.type(screen.getByRole('textbox', { name: /title/i }), 'The first dashboard link');
|
||||||
userEvent.click(
|
await userEvent.click(
|
||||||
within(screen.getByRole('heading', { name: /dashboard links edit/i })).getByText(/dashboard links/i)
|
within(screen.getByRole('heading', { name: /dashboard links edit/i })).getByText(/dashboard links/i)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -6,6 +6,7 @@ import userEvent from '@testing-library/user-event';
|
|||||||
import { historySrv } from '../VersionHistory/HistorySrv';
|
import { historySrv } from '../VersionHistory/HistorySrv';
|
||||||
import { VersionsSettings, VERSIONS_FETCH_LIMIT } from './VersionsSettings';
|
import { VersionsSettings, VERSIONS_FETCH_LIMIT } from './VersionsSettings';
|
||||||
import { versions, diffs } from './__mocks__/versions';
|
import { versions, diffs } from './__mocks__/versions';
|
||||||
|
import { UserEvent } from '@testing-library/user-event/dist/types/setup';
|
||||||
|
|
||||||
jest.mock('../VersionHistory/HistorySrv');
|
jest.mock('../VersionHistory/HistorySrv');
|
||||||
|
|
||||||
@@ -28,8 +29,18 @@ describe('VersionSettings', () => {
|
|||||||
getRelativeTime: jest.fn(() => 'time ago'),
|
getRelativeTime: jest.fn(() => 'time ago'),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let user: UserEvent;
|
||||||
|
|
||||||
beforeEach(() => {
|
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.resetAllMocks();
|
jest.resetAllMocks();
|
||||||
|
jest.useFakeTimers();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('renders a header and a loading indicator followed by results in a table', async () => {
|
test('renders a header and a loading indicator followed by results in a table', async () => {
|
||||||
@@ -102,7 +113,9 @@ describe('VersionSettings', () => {
|
|||||||
historySrv.getHistoryList
|
historySrv.getHistoryList
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
.mockImplementationOnce(() => Promise.resolve(versions.slice(0, VERSIONS_FETCH_LIMIT)))
|
.mockImplementationOnce(() => Promise.resolve(versions.slice(0, VERSIONS_FETCH_LIMIT)))
|
||||||
.mockImplementationOnce(() => Promise.resolve(versions.slice(VERSIONS_FETCH_LIMIT, versions.length)));
|
.mockImplementationOnce(
|
||||||
|
() => new Promise((resolve) => setTimeout(() => resolve(versions.slice(VERSIONS_FETCH_LIMIT)), 1000))
|
||||||
|
);
|
||||||
|
|
||||||
render(<VersionsSettings dashboard={dashboard} />);
|
render(<VersionsSettings dashboard={dashboard} />);
|
||||||
|
|
||||||
@@ -113,14 +126,16 @@ describe('VersionSettings', () => {
|
|||||||
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(VERSIONS_FETCH_LIMIT);
|
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(VERSIONS_FETCH_LIMIT);
|
||||||
|
|
||||||
const showMoreButton = screen.getByRole('button', { name: /show more versions/i });
|
const showMoreButton = screen.getByRole('button', { name: /show more versions/i });
|
||||||
userEvent.click(showMoreButton);
|
await user.click(showMoreButton);
|
||||||
|
|
||||||
expect(historySrv.getHistoryList).toBeCalledTimes(2);
|
expect(historySrv.getHistoryList).toBeCalledTimes(2);
|
||||||
expect(screen.queryByText(/Fetching more entries/i)).toBeInTheDocument();
|
expect(screen.getByText(/Fetching more entries/i)).toBeInTheDocument();
|
||||||
|
jest.advanceTimersByTime(1000);
|
||||||
|
|
||||||
await waitFor(() =>
|
await waitFor(() => {
|
||||||
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(versions.length)
|
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 () => {
|
test('selecting two versions and clicking compare button should render compare view', async () => {
|
||||||
@@ -139,17 +154,17 @@ describe('VersionSettings', () => {
|
|||||||
|
|
||||||
const compareButton = screen.getByRole('button', { name: /compare versions/i });
|
const compareButton = screen.getByRole('button', { name: /compare versions/i });
|
||||||
const tableBody = screen.getAllByRole('rowgroup')[1];
|
const tableBody = screen.getAllByRole('rowgroup')[1];
|
||||||
userEvent.click(within(tableBody).getAllByRole('checkbox')[0]);
|
await user.click(within(tableBody).getAllByRole('checkbox')[0]);
|
||||||
userEvent.click(within(tableBody).getAllByRole('checkbox')[VERSIONS_FETCH_LIMIT - 1]);
|
await user.click(within(tableBody).getAllByRole('checkbox')[VERSIONS_FETCH_LIMIT - 1]);
|
||||||
|
|
||||||
expect(compareButton).toBeEnabled();
|
expect(compareButton).toBeEnabled();
|
||||||
|
|
||||||
userEvent.click(within(tableBody).getAllByRole('checkbox')[1]);
|
await user.click(within(tableBody).getAllByRole('checkbox')[1]);
|
||||||
|
|
||||||
expect(compareButton).toBeDisabled();
|
expect(compareButton).toBeDisabled();
|
||||||
|
|
||||||
userEvent.click(within(tableBody).getAllByRole('checkbox')[1]);
|
await user.click(within(tableBody).getAllByRole('checkbox')[1]);
|
||||||
userEvent.click(compareButton);
|
await user.click(compareButton);
|
||||||
|
|
||||||
await waitFor(() => expect(screen.getByRole('heading', { name: /versions comparing 2 11/i })).toBeInTheDocument());
|
await waitFor(() => expect(screen.getByRole('heading', { name: /versions comparing 2 11/i })).toBeInTheDocument());
|
||||||
|
|
||||||
@@ -170,7 +185,7 @@ describe('VersionSettings', () => {
|
|||||||
expect(queryByFullText('version changed')).toBeInTheDocument();
|
expect(queryByFullText('version changed')).toBeInTheDocument();
|
||||||
expect(screen.queryByText(/view json diff/i)).toBeInTheDocument();
|
expect(screen.queryByText(/view json diff/i)).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getByText(/view json diff/i));
|
await user.click(screen.getByText(/view json diff/i));
|
||||||
|
|
||||||
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
|
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
|
||||||
});
|
});
|
||||||
|
@@ -28,9 +28,9 @@ describe('PanelNotSupported', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('when the back to queries button is clicked', () => {
|
describe('when the back to queries button is clicked', () => {
|
||||||
it('then correct action should be dispatched', () => {
|
it('then correct action should be dispatched', async () => {
|
||||||
setupTestContext({});
|
setupTestContext({});
|
||||||
userEvent.click(screen.getByRole('button', { name: /go back to queries/i }));
|
await userEvent.click(screen.getByRole('button', { name: /go back to queries/i }));
|
||||||
expect(locationService.getSearchObject().tab).toBe(PanelEditorTabId.Query);
|
expect(locationService.getSearchObject().tab).toBe(PanelEditorTabId.Query);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -33,13 +33,13 @@ describe('TransformationsEditor', () => {
|
|||||||
options: {},
|
options: {},
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
const editors = screen.getAllByLabelText(/^Transformation editor/g);
|
const editors = screen.getAllByLabelText(/^Transformation editor/);
|
||||||
expect(editors).toHaveLength(1);
|
expect(editors).toHaveLength(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when Add transformation clicked', () => {
|
describe('when Add transformation clicked', () => {
|
||||||
it('renders transformations picker', () => {
|
it('renders transformations picker', async () => {
|
||||||
const buttonLabel = 'Add transformation';
|
const buttonLabel = 'Add transformation';
|
||||||
setup([
|
setup([
|
||||||
{
|
{
|
||||||
@@ -49,7 +49,7 @@ describe('TransformationsEditor', () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
const addTransformationButton = screen.getByText(buttonLabel);
|
const addTransformationButton = screen.getByText(buttonLabel);
|
||||||
userEvent.click(addTransformationButton);
|
await userEvent.click(addTransformationButton);
|
||||||
|
|
||||||
const search = screen.getByLabelText(selectors.components.Transforms.searchInput);
|
const search = screen.getByLabelText(selectors.components.Transforms.searchInput);
|
||||||
expect(search).toBeDefined();
|
expect(search).toBeDefined();
|
||||||
@@ -58,7 +58,7 @@ describe('TransformationsEditor', () => {
|
|||||||
|
|
||||||
describe('actions', () => {
|
describe('actions', () => {
|
||||||
describe('debug', () => {
|
describe('debug', () => {
|
||||||
it('should show/hide debugger', () => {
|
it('should show/hide debugger', async () => {
|
||||||
setup([
|
setup([
|
||||||
{
|
{
|
||||||
id: 'reduce',
|
id: 'reduce',
|
||||||
@@ -70,7 +70,7 @@ describe('TransformationsEditor', () => {
|
|||||||
expect(screen.queryByLabelText(debuggerSelector)).toBeNull();
|
expect(screen.queryByLabelText(debuggerSelector)).toBeNull();
|
||||||
|
|
||||||
const debugButton = screen.getByLabelText(selectors.components.QueryEditorRow.actionButton('Debug'));
|
const debugButton = screen.getByLabelText(selectors.components.QueryEditorRow.actionButton('Debug'));
|
||||||
userEvent.click(debugButton);
|
await userEvent.click(debugButton);
|
||||||
|
|
||||||
expect(screen.getByLabelText(debuggerSelector)).toBeInTheDocument();
|
expect(screen.getByLabelText(debuggerSelector)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
@@ -28,7 +28,7 @@ const setup = (children: ReactNode, queries: DataQuery[] = [{ refId: 'A' }]) =>
|
|||||||
};
|
};
|
||||||
|
|
||||||
const openModal = async () => {
|
const openModal = async () => {
|
||||||
userEvent.click(screen.getByRole('button', { name: /add to dashboard/i }));
|
await userEvent.click(screen.getByRole('button', { name: /add to dashboard/i }));
|
||||||
|
|
||||||
expect(await screen.findByRole('dialog', { name: 'Add panel to dashboard' })).toBeInTheDocument();
|
expect(await screen.findByRole('dialog', { name: 'Add panel to dashboard' })).toBeInTheDocument();
|
||||||
};
|
};
|
||||||
@@ -44,7 +44,7 @@ describe('AddToDashboardButton', () => {
|
|||||||
const button = await screen.findByRole('button', { name: /add to dashboard/i });
|
const button = await screen.findByRole('button', { name: /add to dashboard/i });
|
||||||
expect(button).toBeDisabled();
|
expect(button).toBeDisabled();
|
||||||
|
|
||||||
userEvent.click(button);
|
await userEvent.click(button);
|
||||||
|
|
||||||
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
@@ -71,7 +71,7 @@ describe('AddToDashboardButton', () => {
|
|||||||
|
|
||||||
await openModal();
|
await openModal();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: /cancel/i }));
|
await userEvent.click(screen.getByRole('button', { name: /cancel/i }));
|
||||||
|
|
||||||
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
@@ -86,7 +86,7 @@ describe('AddToDashboardButton', () => {
|
|||||||
|
|
||||||
await openModal();
|
await openModal();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
|
await userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
|
||||||
|
|
||||||
await waitForAddToDashboardResponse();
|
await waitForAddToDashboardResponse();
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ describe('AddToDashboardButton', () => {
|
|||||||
|
|
||||||
await openModal();
|
await openModal();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
|
await userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
|
||||||
|
|
||||||
await waitForAddToDashboardResponse();
|
await waitForAddToDashboardResponse();
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ describe('AddToDashboardButton', () => {
|
|||||||
|
|
||||||
await openModal();
|
await openModal();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
|
await userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
|
||||||
|
|
||||||
await waitForAddToDashboardResponse();
|
await waitForAddToDashboardResponse();
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ describe('AddToDashboardButton', () => {
|
|||||||
|
|
||||||
await openModal();
|
await openModal();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
|
await userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
|
||||||
|
|
||||||
await waitForAddToDashboardResponse();
|
await waitForAddToDashboardResponse();
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ describe('AddToDashboardButton', () => {
|
|||||||
|
|
||||||
expect(screen.queryByRole('combobox', { name: /dashboard/ })).not.toBeInTheDocument();
|
expect(screen.queryByRole('combobox', { name: /dashboard/ })).not.toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole<HTMLInputElement>('radio', { name: /existing dashboard/i }));
|
await userEvent.click(screen.getByRole<HTMLInputElement>('radio', { name: /existing dashboard/i }));
|
||||||
expect(screen.getByRole('combobox', { name: /dashboard/ })).toBeInTheDocument();
|
expect(screen.getByRole('combobox', { name: /dashboard/ })).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -168,9 +168,9 @@ describe('AddToDashboardButton', () => {
|
|||||||
|
|
||||||
await openModal();
|
await openModal();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole<HTMLInputElement>('radio', { name: /existing dashboard/i }));
|
await userEvent.click(screen.getByRole<HTMLInputElement>('radio', { name: /existing dashboard/i }));
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
|
await userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
|
||||||
await waitForAddToDashboardResponse();
|
await waitForAddToDashboardResponse();
|
||||||
|
|
||||||
expect(locationService.push).not.toHaveBeenCalled();
|
expect(locationService.push).not.toHaveBeenCalled();
|
||||||
@@ -203,16 +203,16 @@ describe('AddToDashboardButton', () => {
|
|||||||
|
|
||||||
await openModal();
|
await openModal();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
|
await userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('combobox', { name: /dashboard/i }));
|
await userEvent.click(screen.getByRole('combobox', { name: /dashboard/i }));
|
||||||
|
|
||||||
await waitFor(async () => {
|
await waitFor(async () => {
|
||||||
await screen.findByLabelText('Select option');
|
await screen.findByLabelText('Select option');
|
||||||
});
|
});
|
||||||
userEvent.click(screen.getByLabelText('Select option'));
|
await userEvent.click(screen.getByLabelText('Select option'));
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
|
await userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
|
||||||
|
|
||||||
await waitFor(async () => {
|
await waitFor(async () => {
|
||||||
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
||||||
@@ -246,16 +246,16 @@ describe('AddToDashboardButton', () => {
|
|||||||
|
|
||||||
await openModal();
|
await openModal();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
|
await userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('combobox', { name: /dashboard/i }));
|
await userEvent.click(screen.getByRole('combobox', { name: /dashboard/i }));
|
||||||
|
|
||||||
await waitFor(async () => {
|
await waitFor(async () => {
|
||||||
await screen.findByLabelText('Select option');
|
await screen.findByLabelText('Select option');
|
||||||
});
|
});
|
||||||
userEvent.click(screen.getByLabelText('Select option'));
|
await userEvent.click(screen.getByLabelText('Select option'));
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
|
await userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
|
||||||
|
|
||||||
await waitFor(async () => {
|
await waitFor(async () => {
|
||||||
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
||||||
@@ -281,7 +281,7 @@ describe('AddToDashboardButton', () => {
|
|||||||
await openModal();
|
await openModal();
|
||||||
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
|
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
|
await userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
|
||||||
|
|
||||||
await waitFor(async () => {
|
await waitFor(async () => {
|
||||||
expect(await screen.findByRole('alert')).toBeInTheDocument();
|
expect(await screen.findByRole('alert')).toBeInTheDocument();
|
||||||
@@ -300,7 +300,7 @@ describe('AddToDashboardButton', () => {
|
|||||||
await openModal();
|
await openModal();
|
||||||
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
|
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
|
await userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
|
||||||
|
|
||||||
await waitFor(async () => {
|
await waitFor(async () => {
|
||||||
expect(await screen.findByRole('alert')).toBeInTheDocument();
|
expect(await screen.findByRole('alert')).toBeInTheDocument();
|
||||||
@@ -328,16 +328,16 @@ describe('AddToDashboardButton', () => {
|
|||||||
await openModal();
|
await openModal();
|
||||||
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
|
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
|
await userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('combobox', { name: /dashboard/i }));
|
await userEvent.click(screen.getByRole('combobox', { name: /dashboard/i }));
|
||||||
|
|
||||||
await waitFor(async () => {
|
await waitFor(async () => {
|
||||||
await screen.findByLabelText('Select option');
|
await screen.findByLabelText('Select option');
|
||||||
});
|
});
|
||||||
userEvent.click(screen.getByLabelText('Select option'));
|
await userEvent.click(screen.getByLabelText('Select option'));
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
|
await userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
|
||||||
|
|
||||||
await waitFor(async () => {
|
await waitFor(async () => {
|
||||||
expect(await screen.findByRole('alert')).toBeInTheDocument();
|
expect(await screen.findByRole('alert')).toBeInTheDocument();
|
||||||
@@ -352,7 +352,7 @@ describe('AddToDashboardButton', () => {
|
|||||||
await openModal();
|
await openModal();
|
||||||
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
|
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
|
await userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
|
||||||
|
|
||||||
await waitFor(async () => {
|
await waitFor(async () => {
|
||||||
expect(await screen.findByRole('alert')).toBeInTheDocument();
|
expect(await screen.findByRole('alert')).toBeInTheDocument();
|
||||||
|
@@ -92,10 +92,10 @@ describe('TraceView', () => {
|
|||||||
renderTraceViewNew();
|
renderTraceViewNew();
|
||||||
expect(screen.queryByText(/Tags/)).toBeFalsy();
|
expect(screen.queryByText(/Tags/)).toBeFalsy();
|
||||||
const spanView = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[0];
|
const spanView = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[0];
|
||||||
userEvent.click(spanView);
|
await userEvent.click(spanView);
|
||||||
expect(screen.queryByText(/Tags/)).toBeTruthy();
|
expect(screen.queryByText(/Tags/)).toBeTruthy();
|
||||||
|
|
||||||
userEvent.click(spanView);
|
await userEvent.click(spanView);
|
||||||
screen.debug(screen.queryAllByText(/Tags/));
|
screen.debug(screen.queryAllByText(/Tags/));
|
||||||
expect(screen.queryByText(/Tags/)).toBeFalsy();
|
expect(screen.queryByText(/Tags/)).toBeFalsy();
|
||||||
});
|
});
|
||||||
@@ -109,36 +109,36 @@ describe('TraceView', () => {
|
|||||||
expect(ticks()).toBe('0μs274.5μs549μs823.5μs1.1ms');
|
expect(ticks()).toBe('0μs274.5μs549μs823.5μs1.1ms');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('correctly shows processes for each span', () => {
|
it('correctly shows processes for each span', async () => {
|
||||||
renderTraceView();
|
renderTraceView();
|
||||||
let table: HTMLElement;
|
let table: HTMLElement;
|
||||||
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
|
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
|
||||||
|
|
||||||
const firstSpan = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[0];
|
const firstSpan = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[0];
|
||||||
userEvent.click(firstSpan);
|
await userEvent.click(firstSpan);
|
||||||
userEvent.click(screen.getByText(/Process/));
|
await userEvent.click(screen.getByText(/Process/));
|
||||||
table = screen.getByText('', { selector: 'div[data-test-id="KeyValueTable"]' });
|
table = screen.getByText('', { selector: 'div[data-test-id="KeyValueTable"]' });
|
||||||
expect(table.innerHTML).toContain('client-uuid-1');
|
expect(table.innerHTML).toContain('client-uuid-1');
|
||||||
userEvent.click(firstSpan);
|
await userEvent.click(firstSpan);
|
||||||
|
|
||||||
const secondSpan = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[1];
|
const secondSpan = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[1];
|
||||||
userEvent.click(secondSpan);
|
await userEvent.click(secondSpan);
|
||||||
userEvent.click(screen.getByText(/Process/));
|
await userEvent.click(screen.getByText(/Process/));
|
||||||
table = screen.getByText('', { selector: 'div[data-test-id="KeyValueTable"]' });
|
table = screen.getByText('', { selector: 'div[data-test-id="KeyValueTable"]' });
|
||||||
expect(table.innerHTML).toContain('client-uuid-2');
|
expect(table.innerHTML).toContain('client-uuid-2');
|
||||||
userEvent.click(secondSpan);
|
await userEvent.click(secondSpan);
|
||||||
|
|
||||||
const thirdSpan = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[2];
|
const thirdSpan = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[2];
|
||||||
userEvent.click(thirdSpan);
|
await userEvent.click(thirdSpan);
|
||||||
userEvent.click(screen.getByText(/Process/));
|
await userEvent.click(screen.getByText(/Process/));
|
||||||
table = screen.getByText('', { selector: 'div[data-test-id="KeyValueTable"]' });
|
table = screen.getByText('', { selector: 'div[data-test-id="KeyValueTable"]' });
|
||||||
expect(table.innerHTML).toContain('client-uuid-3');
|
expect(table.innerHTML).toContain('client-uuid-3');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('resets detail view for new trace with the identical spanID', () => {
|
it('resets detail view for new trace with the identical spanID', async () => {
|
||||||
const { rerender } = render(getTraceView([frameOld]));
|
const { rerender } = render(getTraceView([frameOld]));
|
||||||
const span = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[2];
|
const span = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[2];
|
||||||
userEvent.click(span);
|
await userEvent.click(span);
|
||||||
//Process is in detail view
|
//Process is in detail view
|
||||||
expect(screen.getByText(/Process/)).toBeInTheDocument();
|
expect(screen.getByText(/Process/)).toBeInTheDocument();
|
||||||
|
|
||||||
|
@@ -35,75 +35,75 @@ function renderTraceViewContainer(frames = [frameOld]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('TraceViewContainer', () => {
|
describe('TraceViewContainer', () => {
|
||||||
it('toggles children visibility', () => {
|
it('toggles children visibility', async () => {
|
||||||
renderTraceViewContainer();
|
renderTraceViewContainer();
|
||||||
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
|
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
|
||||||
userEvent.click(screen.getAllByText('', { selector: 'span[data-test-id="SpanTreeOffset--indentGuide"]' })[0]);
|
await userEvent.click(screen.getAllByText('', { selector: 'span[data-test-id="SpanTreeOffset--indentGuide"]' })[0]);
|
||||||
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(1);
|
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(1);
|
||||||
|
|
||||||
userEvent.click(screen.getAllByText('', { selector: 'span[data-test-id="SpanTreeOffset--indentGuide"]' })[0]);
|
await userEvent.click(screen.getAllByText('', { selector: 'span[data-test-id="SpanTreeOffset--indentGuide"]' })[0]);
|
||||||
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
|
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('toggles collapses and expands one level of spans', () => {
|
it('toggles collapses and expands one level of spans', async () => {
|
||||||
renderTraceViewContainer();
|
renderTraceViewContainer();
|
||||||
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
|
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
|
||||||
userEvent.click(screen.getByLabelText('Collapse +1'));
|
await userEvent.click(screen.getByLabelText('Collapse +1'));
|
||||||
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(2);
|
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(2);
|
||||||
userEvent.click(screen.getByLabelText('Expand +1'));
|
await userEvent.click(screen.getByLabelText('Expand +1'));
|
||||||
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
|
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('toggles collapses and expands all levels', () => {
|
it('toggles collapses and expands all levels', async () => {
|
||||||
renderTraceViewContainer();
|
renderTraceViewContainer();
|
||||||
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
|
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
|
||||||
userEvent.click(screen.getByLabelText('Collapse All'));
|
await userEvent.click(screen.getByLabelText('Collapse All'));
|
||||||
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(1);
|
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(1);
|
||||||
userEvent.click(screen.getByLabelText('Expand All'));
|
await userEvent.click(screen.getByLabelText('Expand All'));
|
||||||
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
|
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('searches for spans', () => {
|
it('searches for spans', async () => {
|
||||||
renderTraceViewContainer();
|
renderTraceViewContainer();
|
||||||
userEvent.type(screen.getByPlaceholderText('Find...'), '1ed38015486087ca');
|
await userEvent.type(screen.getByPlaceholderText('Find...'), '1ed38015486087ca');
|
||||||
expect(
|
expect(
|
||||||
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[0].parentNode! as HTMLElement).className
|
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[0].parentNode! as HTMLElement).className
|
||||||
).toContain('rowMatchingFilter');
|
).toContain('rowMatchingFilter');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can select next/prev results', () => {
|
it('can select next/prev results', async () => {
|
||||||
renderTraceViewContainer();
|
renderTraceViewContainer();
|
||||||
userEvent.type(screen.getByPlaceholderText('Find...'), 'logproto');
|
await userEvent.type(screen.getByPlaceholderText('Find...'), 'logproto');
|
||||||
const nextResultButton = screen.getByTestId('trace-page-search-bar-next-result-button');
|
const nextResultButton = screen.getByTestId('trace-page-search-bar-next-result-button');
|
||||||
const prevResultButton = screen.getByTestId('trace-page-search-bar-prev-result-button');
|
const prevResultButton = screen.getByTestId('trace-page-search-bar-prev-result-button');
|
||||||
const suffix = screen.getByTestId('trace-page-search-bar-suffix');
|
const suffix = screen.getByTestId('trace-page-search-bar-suffix');
|
||||||
|
|
||||||
userEvent.click(nextResultButton);
|
await userEvent.click(nextResultButton);
|
||||||
expect(suffix.textContent).toBe('1 of 2');
|
expect(suffix.textContent).toBe('1 of 2');
|
||||||
expect(
|
expect(
|
||||||
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[1].parentNode! as HTMLElement).className
|
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[1].parentNode! as HTMLElement).className
|
||||||
).toContain('rowFocused');
|
).toContain('rowFocused');
|
||||||
userEvent.click(nextResultButton);
|
await userEvent.click(nextResultButton);
|
||||||
expect(suffix.textContent).toBe('2 of 2');
|
expect(suffix.textContent).toBe('2 of 2');
|
||||||
expect(
|
expect(
|
||||||
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[2].parentNode! as HTMLElement).className
|
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[2].parentNode! as HTMLElement).className
|
||||||
).toContain('rowFocused');
|
).toContain('rowFocused');
|
||||||
userEvent.click(nextResultButton);
|
await userEvent.click(nextResultButton);
|
||||||
expect(suffix.textContent).toBe('1 of 2');
|
expect(suffix.textContent).toBe('1 of 2');
|
||||||
expect(
|
expect(
|
||||||
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[1].parentNode! as HTMLElement).className
|
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[1].parentNode! as HTMLElement).className
|
||||||
).toContain('rowFocused');
|
).toContain('rowFocused');
|
||||||
userEvent.click(prevResultButton);
|
await userEvent.click(prevResultButton);
|
||||||
expect(suffix.textContent).toBe('2 of 2');
|
expect(suffix.textContent).toBe('2 of 2');
|
||||||
expect(
|
expect(
|
||||||
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[2].parentNode! as HTMLElement).className
|
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[2].parentNode! as HTMLElement).className
|
||||||
).toContain('rowFocused');
|
).toContain('rowFocused');
|
||||||
userEvent.click(prevResultButton);
|
await userEvent.click(prevResultButton);
|
||||||
expect(suffix.textContent).toBe('1 of 2');
|
expect(suffix.textContent).toBe('1 of 2');
|
||||||
expect(
|
expect(
|
||||||
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[1].parentNode! as HTMLElement).className
|
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[1].parentNode! as HTMLElement).className
|
||||||
).toContain('rowFocused');
|
).toContain('rowFocused');
|
||||||
userEvent.click(prevResultButton);
|
await userEvent.click(prevResultButton);
|
||||||
expect(suffix.textContent).toBe('2 of 2');
|
expect(suffix.textContent).toBe('2 of 2');
|
||||||
expect(
|
expect(
|
||||||
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[2].parentNode! as HTMLElement).className
|
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[2].parentNode! as HTMLElement).className
|
||||||
|
@@ -217,7 +217,7 @@ describe('Wrapper', () => {
|
|||||||
};
|
};
|
||||||
setupExplore({ urlParams });
|
setupExplore({ urlParams });
|
||||||
const closeButtons = await screen.findAllByTitle(/Close split pane/i);
|
const closeButtons = await screen.findAllByTitle(/Close split pane/i);
|
||||||
userEvent.click(closeButtons[1]);
|
await userEvent.click(closeButtons[1]);
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
const logsPanels = screen.queryAllByTitle(/Close split pane/i);
|
const logsPanels = screen.queryAllByTitle(/Close split pane/i);
|
||||||
|
@@ -11,23 +11,23 @@ export const changeDatasource = async (name: string) => {
|
|||||||
fireEvent.click(option);
|
fireEvent.click(option);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const inputQuery = (query: string, exploreId: ExploreId = ExploreId.left) => {
|
export const inputQuery = async (query: string, exploreId: ExploreId = ExploreId.left) => {
|
||||||
const input = withinExplore(exploreId).getByRole('textbox', { name: 'query' });
|
const input = withinExplore(exploreId).getByRole('textbox', { name: 'query' });
|
||||||
userEvent.clear(input);
|
await userEvent.clear(input);
|
||||||
userEvent.type(input, query);
|
await userEvent.type(input, query);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const runQuery = (exploreId: ExploreId = ExploreId.left) => {
|
export const runQuery = async (exploreId: ExploreId = ExploreId.left) => {
|
||||||
const explore = withinExplore(exploreId);
|
const explore = withinExplore(exploreId);
|
||||||
const toolbar = within(explore.getByLabelText('Explore toolbar'));
|
const toolbar = within(explore.getByLabelText('Explore toolbar'));
|
||||||
const button = toolbar.getByRole('button', { name: /run query/i });
|
const button = toolbar.getByRole('button', { name: /run query/i });
|
||||||
userEvent.click(button);
|
await userEvent.click(button);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const openQueryHistory = async (exploreId: ExploreId = ExploreId.left) => {
|
export const openQueryHistory = async (exploreId: ExploreId = ExploreId.left) => {
|
||||||
const selector = withinExplore(exploreId);
|
const selector = withinExplore(exploreId);
|
||||||
const button = selector.getByRole('button', { name: 'Rich history button' });
|
const button = selector.getByRole('button', { name: 'Rich history button' });
|
||||||
userEvent.click(button);
|
await userEvent.click(button);
|
||||||
expect(
|
expect(
|
||||||
await selector.findByText('The history is local to your browser and is not shared with others.')
|
await selector.findByText('The history is local to your browser and is not shared with others.')
|
||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
@@ -35,26 +35,26 @@ export const openQueryHistory = async (exploreId: ExploreId = ExploreId.left) =>
|
|||||||
|
|
||||||
export const closeQueryHistory = async (exploreId: ExploreId = ExploreId.left) => {
|
export const closeQueryHistory = async (exploreId: ExploreId = ExploreId.left) => {
|
||||||
const closeButton = withinExplore(exploreId).getByRole('button', { name: 'Close query history' });
|
const closeButton = withinExplore(exploreId).getByRole('button', { name: 'Close query history' });
|
||||||
userEvent.click(closeButton);
|
await userEvent.click(closeButton);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const switchToQueryHistoryTab = async (
|
export const switchToQueryHistoryTab = async (
|
||||||
name: 'Settings' | 'Query History',
|
name: 'Settings' | 'Query History',
|
||||||
exploreId: ExploreId = ExploreId.left
|
exploreId: ExploreId = ExploreId.left
|
||||||
) => {
|
) => {
|
||||||
userEvent.click(withinExplore(exploreId).getByRole('tab', { name: `Tab ${name}` }));
|
await userEvent.click(withinExplore(exploreId).getByRole('tab', { name: `Tab ${name}` }));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const selectStarredTabFirst = (exploreId: ExploreId = ExploreId.left) => {
|
export const selectStarredTabFirst = async (exploreId: ExploreId = ExploreId.left) => {
|
||||||
const checkbox = withinExplore(exploreId).getByRole('checkbox', {
|
const checkbox = withinExplore(exploreId).getByRole('checkbox', {
|
||||||
name: 'Change the default active tab from “Query history” to “Starred”',
|
name: 'Change the default active tab from “Query history” to “Starred”',
|
||||||
});
|
});
|
||||||
userEvent.click(checkbox);
|
await userEvent.click(checkbox);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const selectOnlyActiveDataSource = (exploreId: ExploreId = ExploreId.left) => {
|
export const selectOnlyActiveDataSource = async (exploreId: ExploreId = ExploreId.left) => {
|
||||||
const checkbox = withinExplore(exploreId).getByLabelText(/Only show queries for data source currently active.*/);
|
const checkbox = withinExplore(exploreId).getByLabelText(/Only show queries for data source currently active.*/);
|
||||||
userEvent.click(checkbox);
|
await userEvent.click(checkbox);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const starQueryHistory = (queryIndex: number, exploreId: ExploreId = ExploreId.left) => {
|
export const starQueryHistory = (queryIndex: number, exploreId: ExploreId = ExploreId.left) => {
|
||||||
@@ -65,8 +65,8 @@ export const deleteQueryHistory = (queryIndex: number, exploreId: ExploreId = Ex
|
|||||||
invokeAction(queryIndex, 'Delete query', exploreId);
|
invokeAction(queryIndex, 'Delete query', exploreId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const invokeAction = (queryIndex: number, actionAccessibleName: string, exploreId: ExploreId) => {
|
const invokeAction = async (queryIndex: number, actionAccessibleName: string, exploreId: ExploreId) => {
|
||||||
const selector = withinExplore(exploreId);
|
const selector = withinExplore(exploreId);
|
||||||
const buttons = selector.getAllByRole('button', { name: actionAccessibleName });
|
const buttons = selector.getAllByRole('button', { name: actionAccessibleName });
|
||||||
userEvent.click(buttons[queryIndex]);
|
await userEvent.click(buttons[queryIndex]);
|
||||||
};
|
};
|
||||||
|
@@ -49,8 +49,8 @@ describe('Explore: Query History', () => {
|
|||||||
await waitForExplore();
|
await waitForExplore();
|
||||||
|
|
||||||
// and a user runs a query and opens query history
|
// and a user runs a query and opens query history
|
||||||
inputQuery(USER_INPUT);
|
await inputQuery(USER_INPUT);
|
||||||
runQuery();
|
await runQuery();
|
||||||
await openQueryHistory();
|
await openQueryHistory();
|
||||||
|
|
||||||
// the query that was run is in query history
|
// the query that was run is in query history
|
||||||
@@ -80,8 +80,8 @@ describe('Explore: Query History', () => {
|
|||||||
await waitForExplore();
|
await waitForExplore();
|
||||||
await openQueryHistory();
|
await openQueryHistory();
|
||||||
|
|
||||||
inputQuery('query #2');
|
await inputQuery('query #2');
|
||||||
runQuery();
|
await runQuery();
|
||||||
await assertQueryHistory(['{"expr":"query #2"}', '{"expr":"query #1"}']);
|
await assertQueryHistory(['{"expr":"query #2"}', '{"expr":"query #1"}']);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -135,8 +135,8 @@ describe('Explore: Query History', () => {
|
|||||||
await switchToQueryHistoryTab('Settings');
|
await switchToQueryHistoryTab('Settings');
|
||||||
|
|
||||||
// change settings
|
// change settings
|
||||||
selectStarredTabFirst();
|
await selectStarredTabFirst();
|
||||||
selectOnlyActiveDataSource();
|
await selectOnlyActiveDataSource();
|
||||||
await closeQueryHistory();
|
await closeQueryHistory();
|
||||||
await openQueryHistory();
|
await openQueryHistory();
|
||||||
|
|
||||||
|
@@ -50,19 +50,19 @@ describe('InspectDataTab', () => {
|
|||||||
render(<InspectDataTab {...createProps()} />);
|
render(<InspectDataTab {...createProps()} />);
|
||||||
expect(screen.getByText(/Data options/i)).toBeInTheDocument();
|
expect(screen.getByText(/Data options/i)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
it('should show available options', () => {
|
it('should show available options', async () => {
|
||||||
render(<InspectDataTab {...createProps()} />);
|
render(<InspectDataTab {...createProps()} />);
|
||||||
const dataOptions = screen.getByText(/Data options/i);
|
const dataOptions = screen.getByText(/Data options/i);
|
||||||
userEvent.click(dataOptions);
|
await userEvent.click(dataOptions);
|
||||||
expect(screen.getByText(/Show data frame/i)).toBeInTheDocument();
|
expect(screen.getByText(/Show data frame/i)).toBeInTheDocument();
|
||||||
expect(screen.getByText(/Download for Excel/i)).toBeInTheDocument();
|
expect(screen.getByText(/Download for Excel/i)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
it('should show available dataFrame options', () => {
|
it('should show available dataFrame options', async () => {
|
||||||
render(<InspectDataTab {...createProps()} />);
|
render(<InspectDataTab {...createProps()} />);
|
||||||
const dataOptions = screen.getByText(/Data options/i);
|
const dataOptions = screen.getByText(/Data options/i);
|
||||||
userEvent.click(dataOptions);
|
await userEvent.click(dataOptions);
|
||||||
const dataFrameInput = screen.getByRole('combobox', { name: /Select dataframe/i });
|
const dataFrameInput = screen.getByRole('combobox', { name: /Select dataframe/i });
|
||||||
userEvent.click(dataFrameInput);
|
await userEvent.click(dataFrameInput);
|
||||||
expect(screen.getByText(/Second data frame/i)).toBeInTheDocument();
|
expect(screen.getByText(/Second data frame/i)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
it('should show download logs button if logs data', () => {
|
it('should show download logs button if logs data', () => {
|
||||||
|
@@ -103,7 +103,7 @@ describe('SignupInvitedPage', () => {
|
|||||||
it('then required fields should show error messages and nothing should be posted', async () => {
|
it('then required fields should show error messages and nothing should be posted', async () => {
|
||||||
const { postSpy } = await setupTestContext({ get: { email: '', invitedBy: '', name: '', username: '' } });
|
const { postSpy } = await setupTestContext({ get: { email: '', invitedBy: '', name: '', username: '' } });
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: /sign up/i }));
|
await userEvent.click(screen.getByRole('button', { name: /sign up/i }));
|
||||||
|
|
||||||
await waitFor(() => expect(screen.getByText(/email is required/i)).toBeInTheDocument());
|
await waitFor(() => expect(screen.getByText(/email is required/i)).toBeInTheDocument());
|
||||||
expect(screen.getByText(/username is required/i)).toBeInTheDocument();
|
expect(screen.getByText(/username is required/i)).toBeInTheDocument();
|
||||||
@@ -116,8 +116,8 @@ describe('SignupInvitedPage', () => {
|
|||||||
it('then correct form data should be posted', async () => {
|
it('then correct form data should be posted', async () => {
|
||||||
const { postSpy } = await setupTestContext();
|
const { postSpy } = await setupTestContext();
|
||||||
|
|
||||||
userEvent.type(screen.getByPlaceholderText(/password/i), 'pass@word1');
|
await userEvent.type(screen.getByPlaceholderText(/password/i), 'pass@word1');
|
||||||
userEvent.click(screen.getByRole('button', { name: /sign up/i }));
|
await userEvent.click(screen.getByRole('button', { name: /sign up/i }));
|
||||||
|
|
||||||
await waitFor(() => expect(postSpy).toHaveBeenCalledTimes(1));
|
await waitFor(() => expect(postSpy).toHaveBeenCalledTimes(1));
|
||||||
expect(postSpy).toHaveBeenCalledWith('/api/user/invite/complete', {
|
expect(postSpy).toHaveBeenCalledWith('/api/user/invite/complete', {
|
||||||
|
@@ -75,6 +75,7 @@ async function getTestContext(
|
|||||||
|
|
||||||
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalled());
|
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalled());
|
||||||
expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1);
|
expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1);
|
||||||
|
jest.clearAllMocks();
|
||||||
|
|
||||||
return { rerender, getLibraryPanelsSpy, getSpy, getAllPanelPluginMetaSpy };
|
return { rerender, getLibraryPanelsSpy, getSpy, getAllPanelPluginMetaSpy };
|
||||||
}
|
}
|
||||||
@@ -91,9 +92,8 @@ describe('LibraryPanelsSearch', () => {
|
|||||||
describe('and user searches for library panel by name or description', () => {
|
describe('and user searches for library panel by name or description', () => {
|
||||||
it('should call api with correct params', async () => {
|
it('should call api with correct params', async () => {
|
||||||
const { getLibraryPanelsSpy } = await getTestContext();
|
const { getLibraryPanelsSpy } = await getTestContext();
|
||||||
getLibraryPanelsSpy.mockClear();
|
|
||||||
|
|
||||||
userEvent.type(screen.getByPlaceholderText(/search by name/i), 'a');
|
await userEvent.type(screen.getByPlaceholderText(/search by name/i), 'a');
|
||||||
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalled());
|
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalled());
|
||||||
expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1);
|
expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1);
|
||||||
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
|
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
|
||||||
@@ -119,18 +119,18 @@ describe('LibraryPanelsSearch', () => {
|
|||||||
describe('and user changes sorting', () => {
|
describe('and user changes sorting', () => {
|
||||||
it('should call api with correct params', async () => {
|
it('should call api with correct params', async () => {
|
||||||
const { getLibraryPanelsSpy } = await getTestContext({ showSort: true });
|
const { getLibraryPanelsSpy } = await getTestContext({ showSort: true });
|
||||||
getLibraryPanelsSpy.mockClear();
|
|
||||||
|
|
||||||
userEvent.type(screen.getByText(/sort \(default a–z\)/i), 'Desc{enter}');
|
await userEvent.type(screen.getByText(/sort \(default a–z\)/i), 'Desc{enter}');
|
||||||
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1));
|
await waitFor(() =>
|
||||||
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
|
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
|
||||||
searchString: '',
|
searchString: '',
|
||||||
sortDirection: 'alpha-desc',
|
sortDirection: 'alpha-desc',
|
||||||
folderFilter: [],
|
folderFilter: [],
|
||||||
page: 0,
|
page: 0,
|
||||||
typeFilter: [],
|
typeFilter: [],
|
||||||
perPage: 40,
|
perPage: 40,
|
||||||
});
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -147,18 +147,18 @@ describe('LibraryPanelsSearch', () => {
|
|||||||
describe('and user changes panel filter', () => {
|
describe('and user changes panel filter', () => {
|
||||||
it('should call api with correct params', async () => {
|
it('should call api with correct params', async () => {
|
||||||
const { getLibraryPanelsSpy } = await getTestContext({ showPanelFilter: true });
|
const { getLibraryPanelsSpy } = await getTestContext({ showPanelFilter: true });
|
||||||
getLibraryPanelsSpy.mockClear();
|
|
||||||
|
|
||||||
userEvent.type(screen.getByRole('combobox', { name: /panel type filter/i }), 'Graph{enter}');
|
await userEvent.type(screen.getByRole('combobox', { name: /panel type filter/i }), 'Graph{enter}');
|
||||||
userEvent.type(screen.getByRole('combobox', { name: /panel type filter/i }), 'Time Series{enter}');
|
await userEvent.type(screen.getByRole('combobox', { name: /panel type filter/i }), 'Time Series{enter}');
|
||||||
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1));
|
await waitFor(() =>
|
||||||
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
|
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
|
||||||
searchString: '',
|
searchString: '',
|
||||||
folderFilter: [],
|
folderFilter: [],
|
||||||
page: 0,
|
page: 0,
|
||||||
typeFilter: ['graph', 'timeseries'],
|
typeFilter: ['graph', 'timeseries'],
|
||||||
perPage: 40,
|
perPage: 40,
|
||||||
});
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -175,20 +175,20 @@ describe('LibraryPanelsSearch', () => {
|
|||||||
describe('and user changes folder filter', () => {
|
describe('and user changes folder filter', () => {
|
||||||
it('should call api with correct params', async () => {
|
it('should call api with correct params', async () => {
|
||||||
const { getLibraryPanelsSpy } = await getTestContext({ showFolderFilter: true });
|
const { getLibraryPanelsSpy } = await getTestContext({ showFolderFilter: true });
|
||||||
getLibraryPanelsSpy.mockClear();
|
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('combobox', { name: /folder filter/i }));
|
await userEvent.click(screen.getByRole('combobox', { name: /folder filter/i }));
|
||||||
userEvent.type(screen.getByRole('combobox', { name: /folder filter/i }), '{enter}', {
|
await userEvent.type(screen.getByRole('combobox', { name: /folder filter/i }), '{enter}', {
|
||||||
skipClick: true,
|
skipClick: true,
|
||||||
});
|
});
|
||||||
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1));
|
await waitFor(() =>
|
||||||
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
|
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
|
||||||
searchString: '',
|
searchString: '',
|
||||||
folderFilter: ['0'],
|
folderFilter: ['0'],
|
||||||
page: 0,
|
page: 0,
|
||||||
typeFilter: [],
|
typeFilter: [],
|
||||||
perPage: 40,
|
perPage: 40,
|
||||||
});
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -69,10 +69,10 @@ describe('PlaylistEditPage', () => {
|
|||||||
const { putMock } = await getTestContext();
|
const { putMock } = await getTestContext();
|
||||||
|
|
||||||
expect(locationService.getLocation().pathname).toEqual('/');
|
expect(locationService.getLocation().pathname).toEqual('/');
|
||||||
userEvent.clear(screen.getByRole('textbox', { name: /playlist name/i }));
|
await userEvent.clear(screen.getByRole('textbox', { name: /playlist name/i }));
|
||||||
userEvent.type(screen.getByRole('textbox', { name: /playlist name/i }), 'A Name');
|
await userEvent.type(screen.getByRole('textbox', { name: /playlist name/i }), 'A Name');
|
||||||
userEvent.clear(screen.getByRole('textbox', { name: /playlist interval/i }));
|
await userEvent.clear(screen.getByRole('textbox', { name: /playlist interval/i }));
|
||||||
userEvent.type(screen.getByRole('textbox', { name: /playlist interval/i }), '10s');
|
await userEvent.type(screen.getByRole('textbox', { name: /playlist interval/i }), '10s');
|
||||||
fireEvent.submit(screen.getByRole('button', { name: /save/i }));
|
fireEvent.submit(screen.getByRole('button', { name: /save/i }));
|
||||||
await waitFor(() => expect(putMock).toHaveBeenCalledTimes(1));
|
await waitFor(() => expect(putMock).toHaveBeenCalledTimes(1));
|
||||||
expect(putMock).toHaveBeenCalledWith('/api/playlists/1', {
|
expect(putMock).toHaveBeenCalledWith('/api/playlists/1', {
|
||||||
|
@@ -96,11 +96,11 @@ describe('PlaylistForm', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('when deleting a playlist item', () => {
|
describe('when deleting a playlist item', () => {
|
||||||
it('then the item should be removed and other items should be correct', () => {
|
it('then the item should be removed and other items should be correct', async () => {
|
||||||
getTestContext(playlist);
|
getTestContext(playlist);
|
||||||
|
|
||||||
expect(rows()).toHaveLength(3);
|
expect(rows()).toHaveLength(3);
|
||||||
userEvent.click(within(rows()[2]).getByRole('button', { name: /delete playlist item/i }));
|
await userEvent.click(within(rows()[2]).getByRole('button', { name: /delete playlist item/i }));
|
||||||
expect(rows()).toHaveLength(2);
|
expect(rows()).toHaveLength(2);
|
||||||
expectCorrectRow({ index: 0, type: 'id', title: 'first item', first: true });
|
expectCorrectRow({ index: 0, type: 'id', title: 'first item', first: true });
|
||||||
expectCorrectRow({ index: 1, type: 'id', title: 'middle item', last: true });
|
expectCorrectRow({ index: 1, type: 'id', title: 'middle item', last: true });
|
||||||
@@ -108,10 +108,10 @@ describe('PlaylistForm', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('when moving a playlist item up', () => {
|
describe('when moving a playlist item up', () => {
|
||||||
it('then the item should be removed and other items should be correct', () => {
|
it('then the item should be removed and other items should be correct', async () => {
|
||||||
getTestContext(playlist);
|
getTestContext(playlist);
|
||||||
|
|
||||||
userEvent.click(within(rows()[2]).getByRole('button', { name: /move playlist item order up/i }));
|
await userEvent.click(within(rows()[2]).getByRole('button', { name: /move playlist item order up/i }));
|
||||||
expectCorrectRow({ index: 0, type: 'id', title: 'first item', first: true });
|
expectCorrectRow({ index: 0, type: 'id', title: 'first item', first: true });
|
||||||
expectCorrectRow({ index: 1, type: 'tag', title: 'last item' });
|
expectCorrectRow({ index: 1, type: 'tag', title: 'last item' });
|
||||||
expectCorrectRow({ index: 2, type: 'id', title: 'middle item', last: true });
|
expectCorrectRow({ index: 2, type: 'id', title: 'middle item', last: true });
|
||||||
@@ -119,10 +119,10 @@ describe('PlaylistForm', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('when moving a playlist item down', () => {
|
describe('when moving a playlist item down', () => {
|
||||||
it('then the item should be removed and other items should be correct', () => {
|
it('then the item should be removed and other items should be correct', async () => {
|
||||||
getTestContext(playlist);
|
getTestContext(playlist);
|
||||||
|
|
||||||
userEvent.click(within(rows()[0]).getByRole('button', { name: /move playlist item order down/i }));
|
await userEvent.click(within(rows()[0]).getByRole('button', { name: /move playlist item order down/i }));
|
||||||
expectCorrectRow({ index: 0, type: 'id', title: 'middle item', first: true });
|
expectCorrectRow({ index: 0, type: 'id', title: 'middle item', first: true });
|
||||||
expectCorrectRow({ index: 1, type: 'id', title: 'first item' });
|
expectCorrectRow({ index: 1, type: 'id', title: 'first item' });
|
||||||
expectCorrectRow({ index: 2, type: 'tag', title: 'last item', last: true });
|
expectCorrectRow({ index: 2, type: 'tag', title: 'last item', last: true });
|
||||||
@@ -152,7 +152,7 @@ describe('PlaylistForm', () => {
|
|||||||
it('then an alert should appear and nothing should be submitted', async () => {
|
it('then an alert should appear and nothing should be submitted', async () => {
|
||||||
const { onSubmitMock } = getTestContext(playlist);
|
const { onSubmitMock } = getTestContext(playlist);
|
||||||
|
|
||||||
userEvent.clear(screen.getByRole('textbox', { name: /playlist interval/i }));
|
await userEvent.clear(screen.getByRole('textbox', { name: /playlist interval/i }));
|
||||||
fireEvent.submit(screen.getByRole('button', { name: /save/i }));
|
fireEvent.submit(screen.getByRole('button', { name: /save/i }));
|
||||||
expect(await screen.findAllByRole('alert')).toHaveLength(1);
|
expect(await screen.findAllByRole('alert')).toHaveLength(1);
|
||||||
expect(onSubmitMock).not.toHaveBeenCalled();
|
expect(onSubmitMock).not.toHaveBeenCalled();
|
||||||
|
@@ -66,7 +66,7 @@ describe('PlaylistNewPage', () => {
|
|||||||
const { backendSrvMock } = getTestContext();
|
const { backendSrvMock } = getTestContext();
|
||||||
|
|
||||||
expect(locationService.getLocation().pathname).toEqual('/');
|
expect(locationService.getLocation().pathname).toEqual('/');
|
||||||
userEvent.type(screen.getByRole('textbox', { name: /playlist name/i }), 'A Name');
|
await userEvent.type(screen.getByRole('textbox', { name: /playlist name/i }), 'A Name');
|
||||||
fireEvent.submit(screen.getByRole('button', { name: /save/i }));
|
fireEvent.submit(screen.getByRole('button', { name: /save/i }));
|
||||||
await waitFor(() => expect(backendSrvMock).toHaveBeenCalledTimes(1));
|
await waitFor(() => expect(backendSrvMock).toHaveBeenCalledTimes(1));
|
||||||
expect(backendSrvMock).toHaveBeenCalledWith('/api/playlists', {
|
expect(backendSrvMock).toHaveBeenCalledWith('/api/playlists', {
|
||||||
|
@@ -349,7 +349,7 @@ describe('Browse list of plugins', () => {
|
|||||||
expect(listOption).not.toBeChecked();
|
expect(listOption).not.toBeChecked();
|
||||||
|
|
||||||
// Switch to "list" view
|
// Switch to "list" view
|
||||||
userEvent.click(listOption);
|
await userEvent.click(listOption);
|
||||||
expect(gridOption).not.toBeChecked();
|
expect(gridOption).not.toBeChecked();
|
||||||
expect(listOption).toBeChecked();
|
expect(listOption).toBeChecked();
|
||||||
|
|
||||||
|
@@ -447,14 +447,14 @@ describe('Plugin details page', () => {
|
|||||||
await waitFor(() => expect(queryByText(PluginTabLabels.OVERVIEW)).toBeInTheDocument());
|
await waitFor(() => expect(queryByText(PluginTabLabels.OVERVIEW)).toBeInTheDocument());
|
||||||
|
|
||||||
// Open the confirmation modal
|
// Open the confirmation modal
|
||||||
userEvent.click(getByRole('button', { name: /uninstall/i }));
|
await userEvent.click(getByRole('button', { name: /uninstall/i }));
|
||||||
|
|
||||||
expect(queryByText('Uninstall Akumuli')).toBeInTheDocument();
|
expect(queryByText('Uninstall Akumuli')).toBeInTheDocument();
|
||||||
expect(queryByText('Are you sure you want to uninstall this plugin?')).toBeInTheDocument();
|
expect(queryByText('Are you sure you want to uninstall this plugin?')).toBeInTheDocument();
|
||||||
expect(api.uninstallPlugin).toHaveBeenCalledTimes(0);
|
expect(api.uninstallPlugin).toHaveBeenCalledTimes(0);
|
||||||
|
|
||||||
// Confirm the uninstall
|
// Confirm the uninstall
|
||||||
userEvent.click(getByRole('button', { name: /confirm/i }));
|
await userEvent.click(getByRole('button', { name: /confirm/i }));
|
||||||
expect(api.uninstallPlugin).toHaveBeenCalledTimes(1);
|
expect(api.uninstallPlugin).toHaveBeenCalledTimes(1);
|
||||||
expect(api.uninstallPlugin).toHaveBeenCalledWith(id);
|
expect(api.uninstallPlugin).toHaveBeenCalledWith(id);
|
||||||
|
|
||||||
@@ -635,7 +635,7 @@ describe('Plugin details page', () => {
|
|||||||
await waitFor(() => queryByText('Uninstall'));
|
await waitFor(() => queryByText('Uninstall'));
|
||||||
|
|
||||||
// Click on "Enable"
|
// Click on "Enable"
|
||||||
userEvent.click(getByRole('button', { name: /enable/i }));
|
await userEvent.click(getByRole('button', { name: /enable/i }));
|
||||||
|
|
||||||
// Check if the API request was initiated
|
// Check if the API request was initiated
|
||||||
expect(api.updatePluginSettings).toHaveBeenCalledTimes(1);
|
expect(api.updatePluginSettings).toHaveBeenCalledTimes(1);
|
||||||
@@ -675,7 +675,7 @@ describe('Plugin details page', () => {
|
|||||||
await waitFor(() => queryByText('Uninstall'));
|
await waitFor(() => queryByText('Uninstall'));
|
||||||
|
|
||||||
// Click on "Disable"
|
// Click on "Disable"
|
||||||
userEvent.click(getByRole('button', { name: /disable/i }));
|
await userEvent.click(getByRole('button', { name: /disable/i }));
|
||||||
|
|
||||||
// Check if the API request was initiated
|
// Check if the API request was initiated
|
||||||
expect(api.updatePluginSettings).toHaveBeenCalledTimes(1);
|
expect(api.updatePluginSettings).toHaveBeenCalledTimes(1);
|
||||||
|
@@ -83,9 +83,9 @@ describe('ChangePasswordPage', () => {
|
|||||||
it('should call changePassword if change password is valid', async () => {
|
it('should call changePassword if change password is valid', async () => {
|
||||||
const { props } = await getTestContext();
|
const { props } = await getTestContext();
|
||||||
|
|
||||||
userEvent.type(screen.getByLabelText('Old password'), 'test');
|
await userEvent.type(screen.getByLabelText('Old password'), 'test');
|
||||||
userEvent.type(screen.getByLabelText('New password'), 'admin');
|
await userEvent.type(screen.getByLabelText('New password'), 'admin');
|
||||||
userEvent.type(screen.getByLabelText('Confirm password'), 'admin');
|
await userEvent.type(screen.getByLabelText('Confirm password'), 'admin');
|
||||||
fireEvent.click(screen.getByRole('button', { name: 'Change Password' }));
|
fireEvent.click(screen.getByRole('button', { name: 'Change Password' }));
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(props.changePassword).toHaveBeenCalledTimes(1);
|
expect(props.changePassword).toHaveBeenCalledTimes(1);
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render, screen, waitFor } from '@testing-library/react';
|
import { render, screen, waitFor } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event';
|
||||||
import { within } from '@testing-library/dom';
|
import { within } from '@testing-library/dom';
|
||||||
import { OrgRole } from '@grafana/data';
|
import { OrgRole } from '@grafana/data';
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
@@ -239,10 +239,10 @@ describe('UserProfileEditPage', () => {
|
|||||||
const { props } = await getTestContext();
|
const { props } = await getTestContext();
|
||||||
|
|
||||||
const { email, saveProfile } = getSelectors();
|
const { email, saveProfile } = getSelectors();
|
||||||
userEvent.clear(email());
|
await userEvent.clear(email());
|
||||||
userEvent.type(email(), 'test@test.se');
|
await userEvent.type(email(), 'test@test.se');
|
||||||
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
|
||||||
userEvent.click(saveProfile(), undefined, { skipPointerEventsCheck: true });
|
await userEvent.click(saveProfile(), { pointerEventsCheck: PointerEventsCheckLevel.Never });
|
||||||
|
|
||||||
await waitFor(() => expect(props.updateUserProfile).toHaveBeenCalledTimes(1));
|
await waitFor(() => expect(props.updateUserProfile).toHaveBeenCalledTimes(1));
|
||||||
expect(props.updateUserProfile).toHaveBeenCalledWith({
|
expect(props.updateUserProfile).toHaveBeenCalledWith({
|
||||||
@@ -261,7 +261,7 @@ describe('UserProfileEditPage', () => {
|
|||||||
name: /select organisation/i,
|
name: /select organisation/i,
|
||||||
});
|
});
|
||||||
|
|
||||||
userEvent.click(orgsAdminSelectButton());
|
await userEvent.click(orgsAdminSelectButton());
|
||||||
|
|
||||||
await waitFor(() => expect(props.changeUserOrg).toHaveBeenCalledTimes(1));
|
await waitFor(() => expect(props.changeUserOrg).toHaveBeenCalledTimes(1));
|
||||||
expect(props.changeUserOrg).toHaveBeenCalledWith({
|
expect(props.changeUserOrg).toHaveBeenCalledWith({
|
||||||
@@ -280,7 +280,7 @@ describe('UserProfileEditPage', () => {
|
|||||||
name: /revoke user session/i,
|
name: /revoke user session/i,
|
||||||
});
|
});
|
||||||
|
|
||||||
userEvent.click(sessionsRevokeButton());
|
await userEvent.click(sessionsRevokeButton());
|
||||||
|
|
||||||
await waitFor(() => expect(props.revokeUserSession).toHaveBeenCalledTimes(1));
|
await waitFor(() => expect(props.revokeUserSession).toHaveBeenCalledTimes(1));
|
||||||
expect(props.revokeUserSession).toHaveBeenCalledWith(0);
|
expect(props.revokeUserSession).toHaveBeenCalledWith(0);
|
||||||
|
@@ -20,13 +20,13 @@ describe('AdHocFilter', () => {
|
|||||||
const { addFilter } = setup();
|
const { addFilter } = setup();
|
||||||
|
|
||||||
// Select key
|
// Select key
|
||||||
userEvent.click(screen.getByLabelText('Add Filter'));
|
await userEvent.click(screen.getByLabelText('Add Filter'));
|
||||||
const selectEl = screen.getByTestId('AdHocFilterKey-add-key-wrapper');
|
const selectEl = screen.getByTestId('AdHocFilterKey-add-key-wrapper');
|
||||||
expect(selectEl).toBeInTheDocument();
|
expect(selectEl).toBeInTheDocument();
|
||||||
await selectEvent.select(selectEl, 'key3', { container: document.body });
|
await selectEvent.select(selectEl, 'key3', { container: document.body });
|
||||||
|
|
||||||
// Select value
|
// Select value
|
||||||
userEvent.click(screen.getByText('select value'));
|
await userEvent.click(screen.getByText('select value'));
|
||||||
// There are already some filters rendered
|
// There are already some filters rendered
|
||||||
const selectEl2 = screen.getAllByTestId('AdHocFilterValue-value-wrapper')[2];
|
const selectEl2 = screen.getAllByTestId('AdHocFilterValue-value-wrapper')[2];
|
||||||
await selectEvent.select(selectEl2, 'val3', { container: document.body });
|
await selectEvent.select(selectEl2, 'val3', { container: document.body });
|
||||||
@@ -39,7 +39,7 @@ describe('AdHocFilter', () => {
|
|||||||
const { removeFilter } = setup();
|
const { removeFilter } = setup();
|
||||||
|
|
||||||
// Select key
|
// Select key
|
||||||
userEvent.click(screen.getByText('key1'));
|
await userEvent.click(screen.getByText('key1'));
|
||||||
const selectEl = screen.getAllByTestId('AdHocFilterKey-key-wrapper')[0];
|
const selectEl = screen.getAllByTestId('AdHocFilterKey-key-wrapper')[0];
|
||||||
expect(selectEl).toBeInTheDocument();
|
expect(selectEl).toBeInTheDocument();
|
||||||
await selectEvent.select(selectEl, '-- remove filter --', { container: document.body });
|
await selectEvent.select(selectEl, '-- remove filter --', { container: document.body });
|
||||||
@@ -52,7 +52,7 @@ describe('AdHocFilter', () => {
|
|||||||
const { changeFilter } = setup();
|
const { changeFilter } = setup();
|
||||||
|
|
||||||
// Select key
|
// Select key
|
||||||
userEvent.click(screen.getByText('val1'));
|
await userEvent.click(screen.getByText('val1'));
|
||||||
const selectEl = screen.getAllByTestId('AdHocFilterValue-value-wrapper')[0];
|
const selectEl = screen.getAllByTestId('AdHocFilterValue-value-wrapper')[0];
|
||||||
expect(selectEl).toBeInTheDocument();
|
expect(selectEl).toBeInTheDocument();
|
||||||
await selectEvent.select(selectEl, 'val4', { container: document.body });
|
await selectEvent.select(selectEl, 'val4', { container: document.body });
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import * as runtime from '@grafana/runtime';
|
import * as runtime from '@grafana/runtime';
|
||||||
import { render, screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
|
import { act, render, screen, waitFor } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
|
|
||||||
import { VariablesUnknownTable, VariablesUnknownTableProps } from './VariablesUnknownTable';
|
import { VariablesUnknownTable, VariablesUnknownTableProps } from './VariablesUnknownTable';
|
||||||
@@ -36,25 +36,17 @@ describe('VariablesUnknownTable', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('when expanding the section', () => {
|
describe('when expanding the section', () => {
|
||||||
it('then it should show loading spinner', async () => {
|
|
||||||
await getTestContext();
|
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
|
||||||
await waitFor(() => expect(screen.getByText('Loading...')).toBeInTheDocument());
|
|
||||||
});
|
|
||||||
|
|
||||||
it('then it should call getUnknownsNetwork', async () => {
|
it('then it should call getUnknownsNetwork', async () => {
|
||||||
const { getUnknownsNetworkSpy } = await getTestContext();
|
const { getUnknownsNetworkSpy } = await getTestContext();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
||||||
await waitFor(() => expect(getUnknownsNetworkSpy).toHaveBeenCalledTimes(1));
|
await waitFor(() => expect(getUnknownsNetworkSpy).toHaveBeenCalledTimes(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('then it should report the interaction', async () => {
|
it('then it should report the interaction', async () => {
|
||||||
const { reportInteractionSpy } = await getTestContext();
|
const { reportInteractionSpy } = await getTestContext();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
||||||
await waitFor(() => expect(screen.getByText('Loading...')).toBeInTheDocument());
|
|
||||||
|
|
||||||
expect(reportInteractionSpy).toHaveBeenCalledTimes(1);
|
expect(reportInteractionSpy).toHaveBeenCalledTimes(1);
|
||||||
expect(reportInteractionSpy).toHaveBeenCalledWith('Unknown variables section expanded');
|
expect(reportInteractionSpy).toHaveBeenCalledWith('Unknown variables section expanded');
|
||||||
@@ -64,14 +56,14 @@ describe('VariablesUnknownTable', () => {
|
|||||||
it('then it should not call getUnknownsNetwork', async () => {
|
it('then it should not call getUnknownsNetwork', async () => {
|
||||||
const { getUnknownsNetworkSpy } = await getTestContext();
|
const { getUnknownsNetworkSpy } = await getTestContext();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
||||||
await waitFor(() => expect(screen.getByRole('button')).toHaveAttribute('aria-expanded', 'true'));
|
await waitFor(() => expect(screen.getByRole('button')).toHaveAttribute('aria-expanded', 'true'));
|
||||||
expect(getUnknownsNetworkSpy).toHaveBeenCalledTimes(1);
|
expect(getUnknownsNetworkSpy).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
||||||
await waitFor(() => expect(screen.getByRole('button')).toHaveAttribute('aria-expanded', 'false'));
|
await waitFor(() => expect(screen.getByRole('button')).toHaveAttribute('aria-expanded', 'false'));
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
||||||
await waitFor(() => expect(screen.getByRole('button')).toHaveAttribute('aria-expanded', 'true'));
|
await waitFor(() => expect(screen.getByRole('button')).toHaveAttribute('aria-expanded', 'true'));
|
||||||
|
|
||||||
expect(getUnknownsNetworkSpy).toHaveBeenCalledTimes(1);
|
expect(getUnknownsNetworkSpy).toHaveBeenCalledTimes(1);
|
||||||
@@ -82,8 +74,7 @@ describe('VariablesUnknownTable', () => {
|
|||||||
it('then it should render the correct message', async () => {
|
it('then it should render the correct message', async () => {
|
||||||
await getTestContext();
|
await getTestContext();
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
||||||
await waitForElementToBeRemoved(() => screen.getByText('Loading...'));
|
|
||||||
|
|
||||||
expect(screen.getByText('No renamed or missing variables found.')).toBeInTheDocument();
|
expect(screen.getByText('No renamed or missing variables found.')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
@@ -95,8 +86,7 @@ describe('VariablesUnknownTable', () => {
|
|||||||
const usages = [{ variable, nodes: [], edges: [], showGraph: false }];
|
const usages = [{ variable, nodes: [], edges: [], showGraph: false }];
|
||||||
const { reportInteractionSpy } = await getTestContext({}, usages);
|
const { reportInteractionSpy } = await getTestContext({}, usages);
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
||||||
await waitForElementToBeRemoved(() => screen.getByText('Loading...'));
|
|
||||||
|
|
||||||
expect(screen.queryByText('No renamed or missing variables found.')).not.toBeInTheDocument();
|
expect(screen.queryByText('No renamed or missing variables found.')).not.toBeInTheDocument();
|
||||||
expect(screen.getByText('Renamed Variable')).toBeInTheDocument();
|
expect(screen.getByText('Renamed Variable')).toBeInTheDocument();
|
||||||
@@ -117,16 +107,22 @@ describe('VariablesUnknownTable', () => {
|
|||||||
it('then it should report slow expansion', async () => {
|
it('then it should report slow expansion', async () => {
|
||||||
const variable = customBuilder().withId('Renamed Variable').withName('Renamed Variable').build();
|
const variable = customBuilder().withId('Renamed Variable').withName('Renamed Variable').build();
|
||||||
const usages = [{ variable, nodes: [], edges: [], showGraph: false }];
|
const usages = [{ variable, nodes: [], edges: [], showGraph: false }];
|
||||||
const { reportInteractionSpy } = await getTestContext({}, usages);
|
const { reportInteractionSpy, rerender } = await getTestContext({}, usages);
|
||||||
const dateNowStart = 1000;
|
const dateNowStart = 1000;
|
||||||
const dateNowStop = 2000;
|
const dateNowStop = 2000;
|
||||||
Date.now = jest.fn().mockReturnValueOnce(dateNowStart).mockReturnValue(dateNowStop);
|
Date.now = jest.fn().mockReturnValueOnce(dateNowStart).mockReturnValue(dateNowStop);
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
|
||||||
await waitForElementToBeRemoved(() => screen.getByText('Loading...'));
|
const props: VariablesUnknownTableProps = {
|
||||||
|
variables: [],
|
||||||
|
dashboard: null,
|
||||||
|
};
|
||||||
|
await act(async () => {
|
||||||
|
rerender(<VariablesUnknownTable {...props} />);
|
||||||
|
});
|
||||||
|
|
||||||
// make sure we report the interaction for slow expansion
|
// make sure we report the interaction for slow expansion
|
||||||
expect(reportInteractionSpy).toHaveBeenCalledTimes(2);
|
await waitFor(() => expect(reportInteractionSpy).toHaveBeenCalledTimes(2));
|
||||||
expect(reportInteractionSpy.mock.calls[0][0]).toEqual('Unknown variables section expanded');
|
expect(reportInteractionSpy.mock.calls[0][0]).toEqual('Unknown variables section expanded');
|
||||||
expect(reportInteractionSpy.mock.calls[1][0]).toEqual('Slow unknown variables expansion');
|
expect(reportInteractionSpy.mock.calls[1][0]).toEqual('Slow unknown variables expansion');
|
||||||
expect(reportInteractionSpy.mock.calls[1][1]).toEqual({ elapsed: 1000 });
|
expect(reportInteractionSpy.mock.calls[1][1]).toEqual({ elapsed: 1000 });
|
||||||
|
@@ -71,11 +71,11 @@ describe('OptionPicker', () => {
|
|||||||
expect(getSubMenu('A + C')).toBeInTheDocument();
|
expect(getSubMenu('A + C')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('link text should be clickable', () => {
|
it('link text should be clickable', async () => {
|
||||||
const { dispatch } = setupTestContext();
|
const { dispatch } = setupTestContext();
|
||||||
|
|
||||||
dispatch.mockClear();
|
dispatch.mockClear();
|
||||||
userEvent.click(getSubMenu('A + C'));
|
await userEvent.click(getSubMenu('A + C'));
|
||||||
expect(dispatch).toHaveBeenCalledTimes(1);
|
expect(dispatch).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -89,14 +89,14 @@ describe('OptionPicker', () => {
|
|||||||
expect(getSubMenu('A + C')).toBeInTheDocument();
|
expect(getSubMenu('A + C')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('link text should be clickable', () => {
|
it('link text should be clickable', async () => {
|
||||||
const { dispatch } = setupTestContext({
|
const { dispatch } = setupTestContext({
|
||||||
variable: defaultVariable,
|
variable: defaultVariable,
|
||||||
pickerState: { id: 'Other' },
|
pickerState: { id: 'Other' },
|
||||||
});
|
});
|
||||||
|
|
||||||
dispatch.mockClear();
|
dispatch.mockClear();
|
||||||
userEvent.click(getSubMenu('A + C'));
|
await userEvent.click(getSubMenu('A + C'));
|
||||||
expect(dispatch).toHaveBeenCalledTimes(1);
|
expect(dispatch).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -110,13 +110,13 @@ describe('OptionPicker', () => {
|
|||||||
expect(screen.getByLabelText(selectors.components.LoadingIndicator.icon)).toBeInTheDocument();
|
expect(screen.getByLabelText(selectors.components.LoadingIndicator.icon)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('link text should not be clickable', () => {
|
it('link text should not be clickable', async () => {
|
||||||
const { dispatch } = setupTestContext({
|
const { dispatch } = setupTestContext({
|
||||||
variable: { ...defaultVariable, state: LoadingState.Loading },
|
variable: { ...defaultVariable, state: LoadingState.Loading },
|
||||||
});
|
});
|
||||||
|
|
||||||
dispatch.mockClear();
|
dispatch.mockClear();
|
||||||
userEvent.click(getSubMenu('A + C'));
|
await userEvent.click(getSubMenu('A + C'));
|
||||||
expect(dispatch).toHaveBeenCalledTimes(0);
|
expect(dispatch).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -69,13 +69,13 @@ describe('QueryVariableEditor', () => {
|
|||||||
${'regex'} | ${'onPropChange'} | ${[{ propName: 'regex', propValue: 't', updateOptions: true }]}
|
${'regex'} | ${'onPropChange'} | ${[{ propName: 'regex', propValue: 't', updateOptions: true }]}
|
||||||
`(
|
`(
|
||||||
'$fieldName field and tabs away then $propName should be called with correct args',
|
'$fieldName field and tabs away then $propName should be called with correct args',
|
||||||
({ fieldName, propName, expectedArgs }) => {
|
async ({ fieldName, propName, expectedArgs }) => {
|
||||||
const { props } = setupTestContext({});
|
const { props } = setupTestContext({});
|
||||||
const propUnderTest = props[propName];
|
const propUnderTest = props[propName];
|
||||||
const fieldAccessor = fieldAccessors[fieldName];
|
const fieldAccessor = fieldAccessors[fieldName];
|
||||||
|
|
||||||
userEvent.type(fieldAccessor(), 't');
|
await userEvent.type(fieldAccessor(), 't');
|
||||||
userEvent.tab();
|
await userEvent.tab();
|
||||||
|
|
||||||
expect(propUnderTest).toHaveBeenCalledTimes(1);
|
expect(propUnderTest).toHaveBeenCalledTimes(1);
|
||||||
expect(propUnderTest).toHaveBeenCalledWith(...expectedArgs);
|
expect(propUnderTest).toHaveBeenCalledWith(...expectedArgs);
|
||||||
@@ -90,14 +90,14 @@ describe('QueryVariableEditor', () => {
|
|||||||
${'regex'} | ${'onPropChange'}
|
${'regex'} | ${'onPropChange'}
|
||||||
`(
|
`(
|
||||||
'$fieldName field but reverts the change and tabs away then $propName should not be called',
|
'$fieldName field but reverts the change and tabs away then $propName should not be called',
|
||||||
({ fieldName, propName }) => {
|
async ({ fieldName, propName }) => {
|
||||||
const { props } = setupTestContext({});
|
const { props } = setupTestContext({});
|
||||||
const propUnderTest = props[propName];
|
const propUnderTest = props[propName];
|
||||||
const fieldAccessor = fieldAccessors[fieldName];
|
const fieldAccessor = fieldAccessors[fieldName];
|
||||||
|
|
||||||
userEvent.type(fieldAccessor(), 't');
|
await userEvent.type(fieldAccessor(), 't');
|
||||||
userEvent.type(fieldAccessor(), '{backspace}');
|
await userEvent.type(fieldAccessor(), '{backspace}');
|
||||||
userEvent.tab();
|
await userEvent.tab();
|
||||||
|
|
||||||
expect(propUnderTest).not.toHaveBeenCalled();
|
expect(propUnderTest).not.toHaveBeenCalled();
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { fireEvent, render, screen, act, within } from '@testing-library/react';
|
import { fireEvent, render, screen, within } from '@testing-library/react';
|
||||||
import { setupMockedDataSource } from '../../__mocks__/CloudWatchDataSource';
|
import { setupMockedDataSource } from '../../__mocks__/CloudWatchDataSource';
|
||||||
import { CloudWatchMetricsQuery } from '../../types';
|
import { CloudWatchMetricsQuery } from '../../types';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
@@ -60,7 +60,7 @@ describe('Dimensions', () => {
|
|||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
render(<Dimensions {...props} query={props.query} onChange={onChange} dimensionKeys={[]} />);
|
render(<Dimensions {...props} query={props.query} onChange={onChange} dimensionKeys={[]} />);
|
||||||
|
|
||||||
userEvent.click(screen.getByLabelText('Add'));
|
await userEvent.click(screen.getByLabelText('Add'));
|
||||||
expect(screen.getByTestId('cloudwatch-dimensions-filter-item')).toBeInTheDocument();
|
expect(screen.getByTestId('cloudwatch-dimensions-filter-item')).toBeInTheDocument();
|
||||||
expect(onChange).not.toHaveBeenCalled();
|
expect(onChange).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
@@ -74,13 +74,13 @@ describe('Dimensions', () => {
|
|||||||
<Dimensions {...props} query={props.query} onChange={onChange} dimensionKeys={[]} />
|
<Dimensions {...props} query={props.query} onChange={onChange} dimensionKeys={[]} />
|
||||||
);
|
);
|
||||||
|
|
||||||
userEvent.click(screen.getByLabelText('Add'));
|
await userEvent.click(screen.getByLabelText('Add'));
|
||||||
const filterItemElement = screen.getByTestId('cloudwatch-dimensions-filter-item');
|
const filterItemElement = screen.getByTestId('cloudwatch-dimensions-filter-item');
|
||||||
expect(filterItemElement).toBeInTheDocument();
|
expect(filterItemElement).toBeInTheDocument();
|
||||||
|
|
||||||
const keyElement = container.querySelector('#cloudwatch-dimensions-filter-item-key');
|
const keyElement = container.querySelector('#cloudwatch-dimensions-filter-item-key');
|
||||||
expect(keyElement).toBeInTheDocument();
|
expect(keyElement).toBeInTheDocument();
|
||||||
userEvent.type(keyElement!, 'my-key');
|
await userEvent.type(keyElement!, 'my-key');
|
||||||
fireEvent.keyDown(keyElement!, { keyCode: 13 });
|
fireEvent.keyDown(keyElement!, { keyCode: 13 });
|
||||||
expect(onChange).not.toHaveBeenCalled();
|
expect(onChange).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
@@ -95,24 +95,20 @@ describe('Dimensions', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const label = await screen.findByLabelText('Add');
|
const label = await screen.findByLabelText('Add');
|
||||||
userEvent.click(label);
|
await userEvent.click(label);
|
||||||
const filterItemElement = screen.getByTestId('cloudwatch-dimensions-filter-item');
|
const filterItemElement = screen.getByTestId('cloudwatch-dimensions-filter-item');
|
||||||
expect(filterItemElement).toBeInTheDocument();
|
expect(filterItemElement).toBeInTheDocument();
|
||||||
|
|
||||||
const keyElement = container.querySelector('#cloudwatch-dimensions-filter-item-key');
|
const keyElement = container.querySelector('#cloudwatch-dimensions-filter-item-key');
|
||||||
expect(keyElement).toBeInTheDocument();
|
expect(keyElement).toBeInTheDocument();
|
||||||
await act(async () => {
|
await userEvent.type(keyElement!, 'my-key');
|
||||||
userEvent.type(keyElement!, 'my-key');
|
fireEvent.keyDown(keyElement!, { keyCode: 13 });
|
||||||
fireEvent.keyDown(keyElement!, { keyCode: 13 });
|
|
||||||
});
|
|
||||||
expect(onChange).not.toHaveBeenCalled();
|
expect(onChange).not.toHaveBeenCalled();
|
||||||
|
|
||||||
const valueElement = container.querySelector('#cloudwatch-dimensions-filter-item-value');
|
const valueElement = container.querySelector('#cloudwatch-dimensions-filter-item-value');
|
||||||
expect(valueElement).toBeInTheDocument();
|
expect(valueElement).toBeInTheDocument();
|
||||||
await act(async () => {
|
await userEvent.type(valueElement!, 'my-value');
|
||||||
userEvent.type(valueElement!, 'my-value');
|
fireEvent.keyDown(valueElement!, { keyCode: 13 });
|
||||||
fireEvent.keyDown(valueElement!, { keyCode: 13 });
|
|
||||||
});
|
|
||||||
expect(onChange).not.toHaveBeenCalledWith({
|
expect(onChange).not.toHaveBeenCalledWith({
|
||||||
...props.query,
|
...props.query,
|
||||||
dimensions: {
|
dimensions: {
|
||||||
|
@@ -47,7 +47,7 @@ describe('MetricStatEditor', () => {
|
|||||||
const statisticElement = await screen.findByLabelText('Statistic');
|
const statisticElement = await screen.findByLabelText('Statistic');
|
||||||
expect(statisticElement).toBeInTheDocument();
|
expect(statisticElement).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.type(statisticElement, statistic);
|
await userEvent.type(statisticElement, statistic);
|
||||||
fireEvent.keyDown(statisticElement, { keyCode: 13 });
|
fireEvent.keyDown(statisticElement, { keyCode: 13 });
|
||||||
expect(onChange).toHaveBeenCalledWith({ ...props.query, statistic });
|
expect(onChange).toHaveBeenCalledWith({ ...props.query, statistic });
|
||||||
expect(onRunQuery).toHaveBeenCalled();
|
expect(onRunQuery).toHaveBeenCalled();
|
||||||
@@ -62,7 +62,7 @@ describe('MetricStatEditor', () => {
|
|||||||
const statisticElement = await screen.findByLabelText('Statistic');
|
const statisticElement = await screen.findByLabelText('Statistic');
|
||||||
expect(statisticElement).toBeInTheDocument();
|
expect(statisticElement).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.type(statisticElement, statistic);
|
await userEvent.type(statisticElement, statistic);
|
||||||
fireEvent.keyDown(statisticElement, { keyCode: 13 });
|
fireEvent.keyDown(statisticElement, { keyCode: 13 });
|
||||||
expect(onChange).not.toHaveBeenCalled();
|
expect(onChange).not.toHaveBeenCalled();
|
||||||
expect(onRunQuery).not.toHaveBeenCalled();
|
expect(onRunQuery).not.toHaveBeenCalled();
|
||||||
|
@@ -79,7 +79,7 @@ describe('DashboardQueryEditor', () => {
|
|||||||
);
|
);
|
||||||
const select = screen.getByText('Choose panel');
|
const select = screen.getByText('Choose panel');
|
||||||
|
|
||||||
userEvent.click(select);
|
await userEvent.click(select);
|
||||||
|
|
||||||
const myFirstPanel = await screen.findByText('My first panel');
|
const myFirstPanel = await screen.findByText('My first panel');
|
||||||
expect(myFirstPanel).toBeInTheDocument();
|
expect(myFirstPanel).toBeInTheDocument();
|
||||||
@@ -102,7 +102,7 @@ describe('DashboardQueryEditor', () => {
|
|||||||
);
|
);
|
||||||
const select = screen.getByText('Choose panel');
|
const select = screen.getByText('Choose panel');
|
||||||
|
|
||||||
userEvent.click(select);
|
await userEvent.click(select);
|
||||||
|
|
||||||
expect(screen.queryByText('My first panel')).not.toBeInTheDocument();
|
expect(screen.queryByText('My first panel')).not.toBeInTheDocument();
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@ import { useCreatableSelectPersistedBehaviour } from './useCreatableSelectPersis
|
|||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
|
|
||||||
describe('useCreatableSelectPersistedBehaviour', () => {
|
describe('useCreatableSelectPersistedBehaviour', () => {
|
||||||
it('Should make a Select accept custom values', () => {
|
it('Should make a Select accept custom values', async () => {
|
||||||
const MyComp = (_: { force?: boolean }) => (
|
const MyComp = (_: { force?: boolean }) => (
|
||||||
<InlineField label="label">
|
<InlineField label="label">
|
||||||
<Select
|
<Select
|
||||||
@@ -25,28 +25,28 @@ describe('useCreatableSelectPersistedBehaviour', () => {
|
|||||||
expect(input).toBeInTheDocument();
|
expect(input).toBeInTheDocument();
|
||||||
|
|
||||||
// we open the menu
|
// we open the menu
|
||||||
userEvent.click(input);
|
await userEvent.click(input);
|
||||||
|
|
||||||
expect(screen.getByText('Option 1')).toBeInTheDocument();
|
expect(screen.getByText('Option 1')).toBeInTheDocument();
|
||||||
|
|
||||||
// we type in the input 'Option 2', which should prompt an option creation
|
// we type in the input 'Option 2', which should prompt an option creation
|
||||||
userEvent.type(input, 'Option 2');
|
await userEvent.type(input, 'Option 2');
|
||||||
const creatableOption = screen.getByLabelText('Select option');
|
const creatableOption = screen.getByLabelText('Select option');
|
||||||
expect(creatableOption).toHaveTextContent('Create: Option 2');
|
expect(creatableOption).toHaveTextContent('Create: Option 2');
|
||||||
|
|
||||||
// we click on the creatable option to trigger its creation
|
// we click on the creatable option to trigger its creation
|
||||||
userEvent.click(creatableOption);
|
await userEvent.click(creatableOption);
|
||||||
|
|
||||||
// Forcing a rerender
|
// Forcing a rerender
|
||||||
rerender(<MyComp force={true} />);
|
rerender(<MyComp force={true} />);
|
||||||
|
|
||||||
// we open the menu again
|
// we open the menu again
|
||||||
userEvent.click(input);
|
await userEvent.click(input);
|
||||||
// the created option should be available
|
// the created option should be available
|
||||||
expect(screen.getByText('Option 2')).toBeInTheDocument();
|
expect(screen.getByText('Option 2')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should handle onChange properly', () => {
|
it('Should handle onChange properly', async () => {
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const MyComp = () => (
|
const MyComp = () => (
|
||||||
<InlineField label="label">
|
<InlineField label="label">
|
||||||
@@ -67,28 +67,28 @@ describe('useCreatableSelectPersistedBehaviour', () => {
|
|||||||
expect(input).toBeInTheDocument();
|
expect(input).toBeInTheDocument();
|
||||||
|
|
||||||
// we open the menu
|
// we open the menu
|
||||||
userEvent.click(input);
|
await userEvent.click(input);
|
||||||
|
|
||||||
const option1 = screen.getByText('Option 1');
|
const option1 = screen.getByText('Option 1');
|
||||||
expect(option1).toBeInTheDocument();
|
expect(option1).toBeInTheDocument();
|
||||||
|
|
||||||
// Should call onChange when selecting an already existing option
|
// Should call onChange when selecting an already existing option
|
||||||
userEvent.click(option1);
|
await userEvent.click(option1);
|
||||||
expect(onChange).toHaveBeenLastCalledWith(
|
expect(onChange).toHaveBeenLastCalledWith(
|
||||||
{ value: 'Option 1', label: 'Option 1' },
|
{ value: 'Option 1', label: 'Option 1' },
|
||||||
{ action: 'select-option', name: undefined, option: undefined }
|
{ action: 'select-option', name: undefined, option: undefined }
|
||||||
);
|
);
|
||||||
|
|
||||||
userEvent.click(input);
|
await userEvent.click(input);
|
||||||
|
|
||||||
// we type in the input 'Option 2', which should prompt an option creation
|
// we type in the input 'Option 2', which should prompt an option creation
|
||||||
userEvent.type(input, 'Option 2');
|
await userEvent.type(input, 'Option 2');
|
||||||
userEvent.click(screen.getByLabelText('Select option'));
|
await userEvent.click(screen.getByLabelText('Select option'));
|
||||||
|
|
||||||
expect(onChange).toHaveBeenLastCalledWith({ value: 'Option 2' });
|
expect(onChange).toHaveBeenLastCalledWith({ value: 'Option 2' });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should create an option for value if value is not in options', () => {
|
it('Should create an option for value if value is not in options', async () => {
|
||||||
const MyComp = (_: { force?: boolean }) => (
|
const MyComp = (_: { force?: boolean }) => (
|
||||||
<InlineField label="label">
|
<InlineField label="label">
|
||||||
<Select
|
<Select
|
||||||
@@ -109,7 +109,7 @@ describe('useCreatableSelectPersistedBehaviour', () => {
|
|||||||
expect(input).toBeInTheDocument();
|
expect(input).toBeInTheDocument();
|
||||||
|
|
||||||
// we open the menu
|
// we open the menu
|
||||||
userEvent.click(input);
|
await userEvent.click(input);
|
||||||
|
|
||||||
// we expect 2 elemnts having "Option 2": the input itself and the option.
|
// we expect 2 elemnts having "Option 2": the input itself and the option.
|
||||||
expect(screen.getAllByText('Option 2')).toHaveLength(2);
|
expect(screen.getAllByText('Option 2')).toHaveLength(2);
|
||||||
|
@@ -83,9 +83,9 @@ describe('MetricsQueryEditor', () => {
|
|||||||
const checkbox = await screen.findByLabelText('web-server');
|
const checkbox = await screen.findByLabelText('web-server');
|
||||||
expect(checkbox).toBeInTheDocument();
|
expect(checkbox).toBeInTheDocument();
|
||||||
expect(checkbox).not.toBeChecked();
|
expect(checkbox).not.toBeChecked();
|
||||||
userEvent.click(checkbox);
|
await userEvent.click(checkbox);
|
||||||
expect(checkbox).toBeChecked();
|
expect(checkbox).toBeChecked();
|
||||||
userEvent.click(await screen.findByRole('button', { name: 'Apply' }));
|
await userEvent.click(await screen.findByRole('button', { name: 'Apply' }));
|
||||||
|
|
||||||
expect(onChange).toBeCalledTimes(1);
|
expect(onChange).toBeCalledTimes(1);
|
||||||
expect(onChange).toBeCalledWith(
|
expect(onChange).toBeCalledWith(
|
||||||
@@ -136,9 +136,9 @@ describe('MetricsQueryEditor', () => {
|
|||||||
const checkbox = await screen.findByLabelText('db-server');
|
const checkbox = await screen.findByLabelText('db-server');
|
||||||
expect(checkbox).toBeInTheDocument();
|
expect(checkbox).toBeInTheDocument();
|
||||||
expect(checkbox).not.toBeChecked();
|
expect(checkbox).not.toBeChecked();
|
||||||
userEvent.click(checkbox);
|
await userEvent.click(checkbox);
|
||||||
expect(checkbox).toBeChecked();
|
expect(checkbox).toBeChecked();
|
||||||
userEvent.click(await screen.findByRole('button', { name: 'Apply' }));
|
await userEvent.click(await screen.findByRole('button', { name: 'Apply' }));
|
||||||
|
|
||||||
expect(onChange).toBeCalledTimes(1);
|
expect(onChange).toBeCalledTimes(1);
|
||||||
expect(onChange).toBeCalledWith(
|
expect(onChange).toBeCalledWith(
|
||||||
|
@@ -100,7 +100,7 @@ describe('AzureMonitor ResourcePicker', () => {
|
|||||||
advancedSection.click();
|
advancedSection.click();
|
||||||
|
|
||||||
const advancedInput = await screen.findByLabelText('Resource URI');
|
const advancedInput = await screen.findByLabelText('Resource URI');
|
||||||
userEvent.type(advancedInput, '/subscriptions/def-123');
|
await userEvent.type(advancedInput, '/subscriptions/def-123');
|
||||||
|
|
||||||
const applyButton = screen.getByRole('button', { name: 'Apply' });
|
const applyButton = screen.getByRole('button', { name: 'Apply' });
|
||||||
applyButton.click();
|
applyButton.click();
|
||||||
|
@@ -137,7 +137,7 @@ describe('VariableEditor:', () => {
|
|||||||
};
|
};
|
||||||
render(<VariableEditor {...props} />);
|
render(<VariableEditor {...props} />);
|
||||||
await waitFor(() => screen.queryByText('Grafana template variable function'));
|
await waitFor(() => screen.queryByText('Grafana template variable function'));
|
||||||
userEvent.type(screen.getByDisplayValue('Su'), 'bscriptions()');
|
await userEvent.type(screen.getByDisplayValue('Su'), 'bscriptions()');
|
||||||
expect(screen.getByDisplayValue('Subscriptions()')).toBeInTheDocument();
|
expect(screen.getByDisplayValue('Subscriptions()')).toBeInTheDocument();
|
||||||
screen.getByDisplayValue('Subscriptions()').blur();
|
screen.getByDisplayValue('Subscriptions()').blur();
|
||||||
await waitFor(() => screen.queryByText('None'));
|
await waitFor(() => screen.queryByText('None'));
|
||||||
|
@@ -91,7 +91,7 @@ describe('Render', () => {
|
|||||||
updateOptions: onUpdate,
|
updateOptions: onUpdate,
|
||||||
}));
|
}));
|
||||||
expect(screen.queryByText('is no longer supported', { exact: false })).toBeInTheDocument();
|
expect(screen.queryByText('is no longer supported', { exact: false })).toBeInTheDocument();
|
||||||
userEvent.click(screen.getByText('Clear Azure Monitor Logs Credentials'));
|
await userEvent.click(screen.getByText('Clear Azure Monitor Logs Credentials'));
|
||||||
expect(onUpdate).toHaveBeenCalled();
|
expect(onUpdate).toHaveBeenCalled();
|
||||||
const newOpts = onUpdate.mock.calls[0][0]({});
|
const newOpts = onUpdate.mock.calls[0][0]({});
|
||||||
expect(newOpts).toEqual({ jsonData: { azureLogAnalyticsSameAs: true } });
|
expect(newOpts).toEqual({ jsonData: { azureLogAnalyticsSameAs: true } });
|
||||||
|
@@ -74,7 +74,7 @@ describe('RawInfluxQLEditor', () => {
|
|||||||
// value before
|
// value before
|
||||||
expect(queryTextarea).toHaveValue('test query 1');
|
expect(queryTextarea).toHaveValue('test query 1');
|
||||||
|
|
||||||
userEvent.type(queryTextarea, 'new changes');
|
await userEvent.type(queryTextarea, 'new changes');
|
||||||
|
|
||||||
// the field should have a new value, but no onChange yet.
|
// the field should have a new value, but no onChange yet.
|
||||||
expect(queryTextarea).toHaveValue('test query 1new changes');
|
expect(queryTextarea).toHaveValue('test query 1new changes');
|
||||||
@@ -97,7 +97,7 @@ describe('RawInfluxQLEditor', () => {
|
|||||||
// value before
|
// value before
|
||||||
expect(aliasInput).toHaveValue('alias42');
|
expect(aliasInput).toHaveValue('alias42');
|
||||||
|
|
||||||
userEvent.type(aliasInput, 'new changes');
|
await userEvent.type(aliasInput, 'new changes');
|
||||||
|
|
||||||
// the field should have a new value, but no onChange yet.
|
// the field should have a new value, but no onChange yet.
|
||||||
expect(aliasInput).toHaveValue('alias42new changes');
|
expect(aliasInput).toHaveValue('alias42new changes');
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { InfluxQuery } from '../../types';
|
import { InfluxQuery } from '../../types';
|
||||||
import InfluxDatasource from '../../datasource';
|
import InfluxDatasource from '../../datasource';
|
||||||
import { render, screen, act } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { Editor } from './Editor';
|
import { Editor } from './Editor';
|
||||||
import * as mockedMeta from '../../influxQLMetadataQuery';
|
import * as mockedMeta from '../../influxQLMetadataQuery';
|
||||||
@@ -95,9 +95,7 @@ describe('InfluxDB InfluxQL Visual Editor field-filtering', () => {
|
|||||||
expect(mockedMeta.getTagKeysForMeasurementAndTags).toHaveBeenCalledTimes(1);
|
expect(mockedMeta.getTagKeysForMeasurementAndTags).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
// we click the WHERE/cpu button
|
// we click the WHERE/cpu button
|
||||||
await act(async () => {
|
await userEvent.click(screen.getByRole('button', { name: 'cpu' }));
|
||||||
userEvent.click(screen.getByRole('button', { name: 'cpu' }));
|
|
||||||
});
|
|
||||||
|
|
||||||
// and verify getTagKeysForMeasurementAndTags was called again,
|
// and verify getTagKeysForMeasurementAndTags was called again,
|
||||||
// and in the tags-param we did not receive the `field1` part.
|
// and in the tags-param we did not receive the `field1` part.
|
||||||
@@ -105,18 +103,14 @@ describe('InfluxDB InfluxQL Visual Editor field-filtering', () => {
|
|||||||
expect((mockedMeta.getTagKeysForMeasurementAndTags as jest.Mock).mock.calls[1][2]).toStrictEqual(ONLY_TAGS);
|
expect((mockedMeta.getTagKeysForMeasurementAndTags as jest.Mock).mock.calls[1][2]).toStrictEqual(ONLY_TAGS);
|
||||||
|
|
||||||
// now we click on the WHERE/host2 button
|
// now we click on the WHERE/host2 button
|
||||||
await act(async () => {
|
await userEvent.click(screen.getByRole('button', { name: 'host2' }));
|
||||||
userEvent.click(screen.getByRole('button', { name: 'host2' }));
|
|
||||||
});
|
|
||||||
|
|
||||||
// verify `getTagValues` was called once, and in the tags-param we did not receive `field1`
|
// verify `getTagValues` was called once, and in the tags-param we did not receive `field1`
|
||||||
expect(mockedMeta.getTagValues).toHaveBeenCalledTimes(1);
|
expect(mockedMeta.getTagValues).toHaveBeenCalledTimes(1);
|
||||||
expect((mockedMeta.getTagValues as jest.Mock).mock.calls[0][3]).toStrictEqual(ONLY_TAGS);
|
expect((mockedMeta.getTagValues as jest.Mock).mock.calls[0][3]).toStrictEqual(ONLY_TAGS);
|
||||||
|
|
||||||
// now we click on the FROM/cpudata button
|
// now we click on the FROM/cpudata button
|
||||||
await act(async () => {
|
await userEvent.click(screen.getByRole('button', { name: 'cpudata' }));
|
||||||
userEvent.click(screen.getByRole('button', { name: 'cpudata' }));
|
|
||||||
});
|
|
||||||
|
|
||||||
// verify `getTagValues` was called once, and in the tags-param we did not receive `field1`
|
// verify `getTagValues` was called once, and in the tags-param we did not receive `field1`
|
||||||
expect(mockedMeta.getAllMeasurementsForTags).toHaveBeenCalledTimes(1);
|
expect(mockedMeta.getAllMeasurementsForTags).toHaveBeenCalledTimes(1);
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { act, render, screen, waitFor } from '@testing-library/react';
|
import { render, screen, waitFor } from '@testing-library/react';
|
||||||
import { backendSrv } from 'app/core/services/backend_srv';
|
import { backendSrv } from 'app/core/services/backend_srv';
|
||||||
import { createFetchResponse } from 'test/helpers/createFetchResponse';
|
import { createFetchResponse } from 'test/helpers/createFetchResponse';
|
||||||
import { DataQueryRequest, DataSourceInstanceSettings, dateTime, PluginType } from '@grafana/data';
|
import { DataQueryRequest, DataSourceInstanceSettings, dateTime, PluginType } from '@grafana/data';
|
||||||
@@ -9,6 +9,7 @@ import React from 'react';
|
|||||||
import SearchForm from './SearchForm';
|
import SearchForm from './SearchForm';
|
||||||
import { testResponse } from '../testResponse';
|
import { testResponse } from '../testResponse';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
|
import { UserEvent } from '@testing-library/user-event/dist/types/setup';
|
||||||
|
|
||||||
describe('SearchForm', () => {
|
describe('SearchForm', () => {
|
||||||
it('should call the `onChange` function on click of the Input', async () => {
|
it('should call the `onChange` function on click of the Input', async () => {
|
||||||
@@ -38,7 +39,7 @@ describe('SearchForm', () => {
|
|||||||
const asyncServiceSelect = await waitFor(() => screen.getByRole('combobox', { name: 'select-service-name' }));
|
const asyncServiceSelect = await waitFor(() => screen.getByRole('combobox', { name: 'select-service-name' }));
|
||||||
expect(asyncServiceSelect).toBeInTheDocument();
|
expect(asyncServiceSelect).toBeInTheDocument();
|
||||||
|
|
||||||
userEvent.click(asyncServiceSelect);
|
await userEvent.click(asyncServiceSelect);
|
||||||
|
|
||||||
const jaegerService = await screen.findByText('jaeger-query');
|
const jaegerService = await screen.findByText('jaeger-query');
|
||||||
expect(jaegerService).toBeInTheDocument();
|
expect(jaegerService).toBeInTheDocument();
|
||||||
@@ -68,13 +69,21 @@ describe('SearchForm', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('SearchForm', () => {
|
describe('SearchForm', () => {
|
||||||
|
let user: UserEvent;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
// 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 });
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.useRealTimers();
|
||||||
|
});
|
||||||
|
|
||||||
it('should show loader if there is a delay fetching options', async () => {
|
it('should show loader if there is a delay fetching options', async () => {
|
||||||
const promise = Promise.resolve();
|
const handleOnChange = jest.fn();
|
||||||
const handleOnChange = jest.fn(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
return promise;
|
|
||||||
}, 3000);
|
|
||||||
});
|
|
||||||
const query = {
|
const query = {
|
||||||
...defaultQuery,
|
...defaultQuery,
|
||||||
targets: [
|
targets: [
|
||||||
@@ -91,12 +100,19 @@ describe('SearchForm', () => {
|
|||||||
|
|
||||||
render(<SearchForm datasource={ds} query={query} onChange={handleOnChange} />);
|
render(<SearchForm datasource={ds} query={query} onChange={handleOnChange} />);
|
||||||
|
|
||||||
|
jest.spyOn(ds, 'metadataRequest').mockImplementation(() => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve(['jaeger-query']);
|
||||||
|
}, 3000);
|
||||||
|
});
|
||||||
|
});
|
||||||
const asyncServiceSelect = screen.getByRole('combobox', { name: 'select-service-name' });
|
const asyncServiceSelect = screen.getByRole('combobox', { name: 'select-service-name' });
|
||||||
userEvent.click(asyncServiceSelect);
|
await user.click(asyncServiceSelect);
|
||||||
const loader = screen.getByText('Loading options...');
|
expect(screen.getByText('Loading options...')).toBeInTheDocument();
|
||||||
|
|
||||||
expect(loader).toBeInTheDocument();
|
jest.advanceTimersByTime(3000);
|
||||||
await act(() => promise);
|
await waitFor(() => expect(screen.queryByText('Loading options...')).not.toBeInTheDocument());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render, screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
|
import { render, screen, waitFor } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
|
|
||||||
import { createTheme } from '@grafana/data';
|
import { createTheme } from '@grafana/data';
|
||||||
@@ -118,9 +118,9 @@ describe('LokiLabelBrowser', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Clear label selection manually because it's saved in localStorage
|
// Clear label selection manually because it's saved in localStorage
|
||||||
afterEach(() => {
|
afterEach(async () => {
|
||||||
const clearBtn = screen.getByLabelText('Selector clear button');
|
const clearBtn = screen.getByLabelText('Selector clear button');
|
||||||
userEvent.click(clearBtn);
|
await userEvent.click(clearBtn);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders and loader shows when empty, and then first set of labels', async () => {
|
it('renders and loader shows when empty, and then first set of labels', async () => {
|
||||||
@@ -143,10 +143,10 @@ describe('LokiLabelBrowser', () => {
|
|||||||
const props = setupProps();
|
const props = setupProps();
|
||||||
render(<UnthemedLokiLabelBrowser {...props} />);
|
render(<UnthemedLokiLabelBrowser {...props} />);
|
||||||
// Selecting label2
|
// Selecting label2
|
||||||
const label2 = await screen.findByRole('option', { name: /label2/, selected: false });
|
const label2 = await screen.findByRole('option', { name: 'label2', selected: false });
|
||||||
expect(screen.queryByRole('list', { name: /Values/ })).not.toBeInTheDocument();
|
expect(screen.queryByRole('list', { name: /Values/ })).not.toBeInTheDocument();
|
||||||
userEvent.click(label2);
|
await userEvent.click(label2);
|
||||||
expect(screen.queryByRole('option', { name: /label2/, selected: true })).toBeInTheDocument();
|
expect(screen.queryByRole('option', { name: 'label2', selected: true })).toBeInTheDocument();
|
||||||
// List of values for label2 appears
|
// List of values for label2 appears
|
||||||
expect(await screen.findAllByRole('list')).toHaveLength(1);
|
expect(await screen.findAllByRole('list')).toHaveLength(1);
|
||||||
expect(screen.queryByLabelText(/Values for/)).toHaveTextContent('label2');
|
expect(screen.queryByLabelText(/Values for/)).toHaveTextContent('label2');
|
||||||
@@ -154,24 +154,24 @@ describe('LokiLabelBrowser', () => {
|
|||||||
expect(screen.queryByRole('option', { name: 'value2-2' })).toBeInTheDocument();
|
expect(screen.queryByRole('option', { name: 'value2-2' })).toBeInTheDocument();
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
||||||
// Selecting label1, list for its values appears
|
// Selecting label1, list for its values appears
|
||||||
const label1 = await screen.findByRole('option', { name: /label1/, selected: false });
|
const label1 = await screen.findByRole('option', { name: 'label1', selected: false });
|
||||||
userEvent.click(label1);
|
await userEvent.click(label1);
|
||||||
expect(screen.queryByRole('option', { name: /label1/, selected: true })).toBeInTheDocument();
|
expect(screen.queryByRole('option', { name: 'label1', selected: true })).toBeInTheDocument();
|
||||||
await screen.findByLabelText('Values for label1');
|
await screen.findByLabelText('Values for label1');
|
||||||
expect(await screen.findAllByRole('list')).toHaveLength(2);
|
expect(await screen.findAllByRole('list')).toHaveLength(2);
|
||||||
// Selecting value2-2 of label2
|
// Selecting value2-2 of label2
|
||||||
const value = await screen.findByRole('option', { name: 'value2-2', selected: false });
|
const value = await screen.findByRole('option', { name: 'value2-2', selected: false });
|
||||||
userEvent.click(value);
|
await userEvent.click(value);
|
||||||
await screen.findByRole('option', { name: 'value2-2', selected: true });
|
await screen.findByRole('option', { name: 'value2-2', selected: true });
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label2="value2-2"}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label2="value2-2"}');
|
||||||
// Selecting value2-1 of label2, both values now selected
|
// Selecting value2-1 of label2, both values now selected
|
||||||
const value2 = await screen.findByRole('option', { name: 'value2-1', selected: false });
|
const value2 = await screen.findByRole('option', { name: 'value2-1', selected: false });
|
||||||
userEvent.click(value2);
|
await userEvent.click(value2);
|
||||||
// await screen.findByRole('option', {name: 'value2-1', selected: true});
|
// await screen.findByRole('option', {name: 'value2-1', selected: true});
|
||||||
await screen.findByText('{label2=~"value2-1|value2-2"}');
|
await screen.findByText('{label2=~"value2-1|value2-2"}');
|
||||||
// Deselecting value2-2, one value should remain
|
// Deselecting value2-2, one value should remain
|
||||||
const selectedValue = await screen.findByRole('option', { name: 'value2-2', selected: true });
|
const selectedValue = await screen.findByRole('option', { name: 'value2-2', selected: true });
|
||||||
userEvent.click(selectedValue);
|
await userEvent.click(selectedValue);
|
||||||
await screen.findByRole('option', { name: 'value2-1', selected: true });
|
await screen.findByRole('option', { name: 'value2-1', selected: true });
|
||||||
await screen.findByRole('option', { name: 'value2-2', selected: false });
|
await screen.findByRole('option', { name: 'value2-2', selected: false });
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label2="value2-1"}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label2="value2-1"}');
|
||||||
@@ -183,28 +183,30 @@ describe('LokiLabelBrowser', () => {
|
|||||||
|
|
||||||
// Selecting label2
|
// Selecting label2
|
||||||
const label2 = await screen.findByRole('option', { name: /label2/, selected: false });
|
const label2 = await screen.findByRole('option', { name: /label2/, selected: false });
|
||||||
userEvent.click(label2);
|
await userEvent.click(label2);
|
||||||
// List of values for label2 appears
|
// List of values for label2 appears
|
||||||
expect(await screen.findAllByRole('list')).toHaveLength(1);
|
expect(screen.queryByLabelText(/Values for/)).toHaveTextContent('label2');
|
||||||
|
expect(screen.queryByRole('option', { name: 'value2-1' })).toBeInTheDocument();
|
||||||
|
expect(screen.queryByRole('option', { name: 'value2-2' })).toBeInTheDocument();
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
||||||
// Selecting label1, list for its values appears
|
// Selecting label1, list for its values appears
|
||||||
const label1 = await screen.findByRole('option', { name: /label1/, selected: false });
|
const label1 = await screen.findByRole('option', { name: 'label1', selected: false });
|
||||||
userEvent.click(label1);
|
await userEvent.click(label1);
|
||||||
await screen.findByLabelText('Values for label1');
|
await screen.findByLabelText('Values for label1');
|
||||||
expect(await screen.findAllByRole('list')).toHaveLength(2);
|
expect(await screen.findAllByRole('list')).toHaveLength(2);
|
||||||
// Selecting value2-1 of label2
|
// Selecting value2-1 of label2
|
||||||
const value2 = await screen.findByRole('option', { name: 'value2-1', selected: false });
|
const value2 = await screen.findByRole('option', { name: 'value2-1', selected: false });
|
||||||
userEvent.click(value2);
|
await userEvent.click(value2);
|
||||||
await screen.findByText('{label2="value2-1"}');
|
await screen.findByText('{label2="value2-1"}');
|
||||||
|
|
||||||
// Selecting value from label1 for combined selector
|
// Selecting value from label1 for combined selector
|
||||||
const value1 = await screen.findByRole('option', { name: 'value1-2', selected: false });
|
const value1 = await screen.findByRole('option', { name: 'value1-2', selected: false });
|
||||||
userEvent.click(value1);
|
await userEvent.click(value1);
|
||||||
await screen.findByRole('option', { name: 'value1-2', selected: true });
|
await screen.findByRole('option', { name: 'value1-2', selected: true });
|
||||||
await screen.findByText('{label1="value1-2",label2="value2-1"}');
|
await screen.findByText('{label1="value1-2",label2="value2-1"}');
|
||||||
// Deselect label1 should remove label and value
|
// Deselect label1 should remove label and value
|
||||||
const selectedLabel = (await screen.findAllByRole('option', { name: /label1/, selected: true }))[0];
|
const selectedLabel = (await screen.findAllByRole('option', { name: /label1/, selected: true }))[0];
|
||||||
userEvent.click(selectedLabel);
|
await userEvent.click(selectedLabel);
|
||||||
await screen.findByRole('option', { name: /label1/, selected: false });
|
await screen.findByRole('option', { name: /label1/, selected: false });
|
||||||
expect(await screen.findAllByRole('list')).toHaveLength(1);
|
expect(await screen.findAllByRole('list')).toHaveLength(1);
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label2="value2-1"}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label2="value2-1"}');
|
||||||
@@ -215,25 +217,27 @@ describe('LokiLabelBrowser', () => {
|
|||||||
render(<UnthemedLokiLabelBrowser {...props} />);
|
render(<UnthemedLokiLabelBrowser {...props} />);
|
||||||
|
|
||||||
// Selecting label2
|
// Selecting label2
|
||||||
const label2 = await screen.findByRole('option', { name: /label2/, selected: false });
|
const label2 = await screen.findByRole('option', { name: 'label2', selected: false });
|
||||||
userEvent.click(label2);
|
await userEvent.click(label2);
|
||||||
// List of values for label2 appears
|
// List of values for label2 appears
|
||||||
expect(await screen.findAllByRole('list')).toHaveLength(1);
|
expect(screen.queryByLabelText(/Values for/)).toHaveTextContent('label2');
|
||||||
|
expect(screen.queryByRole('option', { name: 'value2-1' })).toBeInTheDocument();
|
||||||
|
expect(screen.queryByRole('option', { name: 'value2-2' })).toBeInTheDocument();
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
||||||
// Selecting label1, list for its values appears
|
// Selecting label1, list for its values appears
|
||||||
const label1 = await screen.findByRole('option', { name: /label1/, selected: false });
|
const label1 = await screen.findByRole('option', { name: 'label1', selected: false });
|
||||||
userEvent.click(label1);
|
await userEvent.click(label1);
|
||||||
await screen.findByLabelText('Values for label1');
|
await screen.findByLabelText('Values for label1');
|
||||||
expect(await screen.findAllByRole('list')).toHaveLength(2);
|
expect(await screen.findAllByRole('list')).toHaveLength(2);
|
||||||
// Selecting value2-1 of label2
|
// Selecting value2-1 of label2
|
||||||
const value2 = await screen.findByRole('option', { name: 'value2-1', selected: false });
|
const value2 = await screen.findByRole('option', { name: 'value2-1', selected: false });
|
||||||
userEvent.click(value2);
|
await userEvent.click(value2);
|
||||||
await screen.findByText('{label2="value2-1"}');
|
await screen.findByText('{label2="value2-1"}');
|
||||||
|
|
||||||
// Clear selector
|
// Clear selector
|
||||||
const clearBtn = screen.getByLabelText('Selector clear button');
|
const clearBtn = screen.getByLabelText('Selector clear button');
|
||||||
userEvent.click(clearBtn);
|
await userEvent.click(clearBtn);
|
||||||
await screen.findByRole('option', { name: /label2/, selected: false });
|
await screen.findByRole('option', { name: 'label2', selected: false });
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -242,14 +246,14 @@ describe('LokiLabelBrowser', () => {
|
|||||||
render(<UnthemedLokiLabelBrowser {...props} />);
|
render(<UnthemedLokiLabelBrowser {...props} />);
|
||||||
// Selecting label2 and label1
|
// Selecting label2 and label1
|
||||||
const label2 = await screen.findByRole('option', { name: /label2/, selected: false });
|
const label2 = await screen.findByRole('option', { name: /label2/, selected: false });
|
||||||
userEvent.click(label2);
|
await userEvent.click(label2);
|
||||||
const label1 = await screen.findByRole('option', { name: /label1/, selected: false });
|
const label1 = await screen.findByRole('option', { name: /label1/, selected: false });
|
||||||
userEvent.click(label1);
|
await userEvent.click(label1);
|
||||||
await screen.findByLabelText('Values for label1');
|
await screen.findByLabelText('Values for label1');
|
||||||
await screen.findByLabelText('Values for label2');
|
await screen.findByLabelText('Values for label2');
|
||||||
expect(await screen.findAllByRole('option', { name: /value/ })).toHaveLength(4);
|
expect(await screen.findAllByRole('option', { name: /value/ })).toHaveLength(4);
|
||||||
// Typing '1' to filter for values
|
// Typing '1' to filter for values
|
||||||
userEvent.type(screen.getByLabelText('Filter expression for values'), 'val1');
|
await userEvent.type(screen.getByLabelText('Filter expression for values'), 'val1');
|
||||||
expect(screen.getByLabelText('Filter expression for values')).toHaveValue('val1');
|
expect(screen.getByLabelText('Filter expression for values')).toHaveValue('val1');
|
||||||
expect(screen.queryByRole('option', { name: 'value2-2' })).not.toBeInTheDocument();
|
expect(screen.queryByRole('option', { name: 'value2-2' })).not.toBeInTheDocument();
|
||||||
expect(await screen.findAllByRole('option', { name: /value/ })).toHaveLength(3);
|
expect(await screen.findAllByRole('option', { name: /value/ })).toHaveLength(3);
|
||||||
@@ -260,25 +264,25 @@ describe('LokiLabelBrowser', () => {
|
|||||||
render(<UnthemedLokiLabelBrowser {...props} />);
|
render(<UnthemedLokiLabelBrowser {...props} />);
|
||||||
// Selecting label2 and label1
|
// Selecting label2 and label1
|
||||||
const label2 = await screen.findByRole('option', { name: /label2/, selected: false });
|
const label2 = await screen.findByRole('option', { name: /label2/, selected: false });
|
||||||
userEvent.click(label2);
|
await userEvent.click(label2);
|
||||||
const label1 = await screen.findByRole('option', { name: /label1/, selected: false });
|
const label1 = await screen.findByRole('option', { name: /label1/, selected: false });
|
||||||
userEvent.click(label1);
|
await userEvent.click(label1);
|
||||||
await screen.findByLabelText('Values for label1');
|
await screen.findByLabelText('Values for label1');
|
||||||
await screen.findByLabelText('Values for label2');
|
await screen.findByLabelText('Values for label2');
|
||||||
expect(await screen.findAllByRole('option', { name: /value/ })).toHaveLength(4);
|
expect(await screen.findAllByRole('option', { name: /value/ })).toHaveLength(4);
|
||||||
expect(screen.queryByRole('option', { name: /label3/ })).toHaveTextContent('label3');
|
expect(screen.queryByRole('option', { name: /label3/ })).toHaveTextContent('label3');
|
||||||
// Click value1-1 which triggers facetting for value3-x, and still show all value1-x
|
// Click value1-1 which triggers facetting for value3-x, and still show all value1-x
|
||||||
const value1 = await screen.findByRole('option', { name: 'value1-1', selected: false });
|
const value1 = await screen.findByRole('option', { name: 'value1-1', selected: false });
|
||||||
userEvent.click(value1);
|
await userEvent.click(value1);
|
||||||
await waitForElementToBeRemoved(screen.queryByRole('option', { name: 'value2-2' }));
|
await waitFor(() => expect(screen.queryByRole('option', { name: 'value2-2' })).not.toBeInTheDocument());
|
||||||
expect(screen.queryByRole('option', { name: 'value1-2' })).toBeInTheDocument();
|
expect(screen.queryByRole('option', { name: 'value1-2' })).toBeInTheDocument();
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label1="value1-1"}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label1="value1-1"}');
|
||||||
expect(screen.queryByRole('option', { name: /label3/ })).toHaveTextContent('label3 (1)');
|
expect(screen.queryByRole('option', { name: /label3/ })).toHaveTextContent('label3 (1)');
|
||||||
// Click value1-2 for which facetting will allow more values for value3-x
|
// Click value1-2 for which facetting will allow more values for value3-x
|
||||||
const value12 = await screen.findByRole('option', { name: 'value1-2', selected: false });
|
const value12 = await screen.findByRole('option', { name: 'value1-2', selected: false });
|
||||||
userEvent.click(value12);
|
await userEvent.click(value12);
|
||||||
await screen.findByRole('option', { name: 'value1-2', selected: true });
|
await screen.findByRole('option', { name: 'value1-2', selected: true });
|
||||||
userEvent.click(screen.getByRole('option', { name: /label3/ }));
|
await userEvent.click(screen.getByRole('option', { name: /label3/ }));
|
||||||
await screen.findByLabelText('Values for label3');
|
await screen.findByLabelText('Values for label3');
|
||||||
expect(screen.queryByRole('option', { name: 'value1-1', selected: true })).toBeInTheDocument();
|
expect(screen.queryByRole('option', { name: 'value1-1', selected: true })).toBeInTheDocument();
|
||||||
expect(screen.queryByRole('option', { name: 'value1-2', selected: true })).toBeInTheDocument();
|
expect(screen.queryByRole('option', { name: 'value1-2', selected: true })).toBeInTheDocument();
|
||||||
|
@@ -15,10 +15,10 @@ describe('LokiQueryBuilder', () => {
|
|||||||
it('tries to load labels when no labels are selected', async () => {
|
it('tries to load labels when no labels are selected', async () => {
|
||||||
const { datasource } = setup();
|
const { datasource } = setup();
|
||||||
datasource.languageProvider.fetchSeriesLabels = jest.fn().mockReturnValue({ job: ['a'], instance: ['b'] });
|
datasource.languageProvider.fetchSeriesLabels = jest.fn().mockReturnValue({ job: ['a'], instance: ['b'] });
|
||||||
userEvent.click(screen.getByLabelText('Add'));
|
await userEvent.click(screen.getByLabelText('Add'));
|
||||||
const labels = screen.getByText(/Labels/);
|
const labels = screen.getByText(/Labels/);
|
||||||
const selects = getAllByRole(labels.parentElement!.parentElement!.parentElement!, 'combobox');
|
const selects = getAllByRole(labels.parentElement!.parentElement!.parentElement!, 'combobox');
|
||||||
userEvent.click(selects[3]);
|
await userEvent.click(selects[3]);
|
||||||
await waitFor(() => expect(screen.getByText('job')).toBeInTheDocument());
|
await waitFor(() => expect(screen.getByText('job')).toBeInTheDocument());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -30,7 +30,7 @@ describe('LokiQueryBuilderContainer', () => {
|
|||||||
};
|
};
|
||||||
render(<LokiQueryBuilderContainer {...props} />);
|
render(<LokiQueryBuilderContainer {...props} />);
|
||||||
expect(screen.getByText('testjob')).toBeInTheDocument();
|
expect(screen.getByText('testjob')).toBeInTheDocument();
|
||||||
addOperation('Range functions', 'Rate');
|
await addOperation('Range functions', 'Rate');
|
||||||
expect(props.onChange).toBeCalledWith({
|
expect(props.onChange).toBeCalledWith({
|
||||||
expr: 'rate({job="testjob"} [$__interval])',
|
expr: 'rate({job="testjob"} [$__interval])',
|
||||||
refId: 'A',
|
refId: 'A',
|
||||||
|
@@ -25,7 +25,7 @@ describe('LokiQueryBuilderOptions', () => {
|
|||||||
screen.getByTitle('Click to edit options').click();
|
screen.getByTitle('Click to edit options').click();
|
||||||
|
|
||||||
const element = screen.getByLabelText('Legend');
|
const element = screen.getByLabelText('Legend');
|
||||||
userEvent.type(element, 'asd');
|
await userEvent.type(element, 'asd');
|
||||||
fireEvent.keyDown(element, { key: 'Enter', code: 'Enter', charCode: 13 });
|
fireEvent.keyDown(element, { key: 'Enter', code: 'Enter', charCode: 13 });
|
||||||
|
|
||||||
expect(props.onChange).toHaveBeenCalledWith({
|
expect(props.onChange).toHaveBeenCalledWith({
|
||||||
|
@@ -73,7 +73,7 @@ describe('LokiQueryEditorSelector', () => {
|
|||||||
|
|
||||||
it('changes to builder mode', async () => {
|
it('changes to builder mode', async () => {
|
||||||
const { onChange } = renderWithMode(QueryEditorMode.Code);
|
const { onChange } = renderWithMode(QueryEditorMode.Code);
|
||||||
switchToMode(QueryEditorMode.Builder);
|
await switchToMode(QueryEditorMode.Builder);
|
||||||
expect(onChange).toBeCalledWith({
|
expect(onChange).toBeCalledWith({
|
||||||
refId: 'A',
|
refId: 'A',
|
||||||
expr: defaultQuery.expr,
|
expr: defaultQuery.expr,
|
||||||
@@ -108,7 +108,7 @@ describe('LokiQueryEditorSelector', () => {
|
|||||||
|
|
||||||
it('changes to code mode', async () => {
|
it('changes to code mode', async () => {
|
||||||
const { onChange } = renderWithMode(QueryEditorMode.Builder);
|
const { onChange } = renderWithMode(QueryEditorMode.Builder);
|
||||||
switchToMode(QueryEditorMode.Code);
|
await switchToMode(QueryEditorMode.Code);
|
||||||
expect(onChange).toBeCalledWith({
|
expect(onChange).toBeCalledWith({
|
||||||
refId: 'A',
|
refId: 'A',
|
||||||
expr: defaultQuery.expr,
|
expr: defaultQuery.expr,
|
||||||
@@ -119,7 +119,7 @@ describe('LokiQueryEditorSelector', () => {
|
|||||||
|
|
||||||
it('changes to explain mode', async () => {
|
it('changes to explain mode', async () => {
|
||||||
const { onChange } = renderWithMode(QueryEditorMode.Code);
|
const { onChange } = renderWithMode(QueryEditorMode.Code);
|
||||||
switchToMode(QueryEditorMode.Explain);
|
await switchToMode(QueryEditorMode.Explain);
|
||||||
expect(onChange).toBeCalledWith({
|
expect(onChange).toBeCalledWith({
|
||||||
refId: 'A',
|
refId: 'A',
|
||||||
expr: defaultQuery.expr,
|
expr: defaultQuery.expr,
|
||||||
@@ -134,7 +134,7 @@ describe('LokiQueryEditorSelector', () => {
|
|||||||
expr: 'rate({instance="host.docker.internal:3000"}[$__interval])',
|
expr: 'rate({instance="host.docker.internal:3000"}[$__interval])',
|
||||||
editorMode: QueryEditorMode.Code,
|
editorMode: QueryEditorMode.Code,
|
||||||
});
|
});
|
||||||
switchToMode(QueryEditorMode.Builder);
|
await switchToMode(QueryEditorMode.Builder);
|
||||||
rerender(
|
rerender(
|
||||||
<LokiQueryEditorSelector
|
<LokiQueryEditorSelector
|
||||||
{...defaultProps}
|
{...defaultProps}
|
||||||
@@ -178,7 +178,7 @@ function expectExplain() {
|
|||||||
expect(screen.getByText(/Fetch all log/)).toBeInTheDocument();
|
expect(screen.getByText(/Fetch all log/)).toBeInTheDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
function switchToMode(mode: QueryEditorMode) {
|
async function switchToMode(mode: QueryEditorMode) {
|
||||||
const label = {
|
const label = {
|
||||||
[QueryEditorMode.Code]: /Code/,
|
[QueryEditorMode.Code]: /Code/,
|
||||||
[QueryEditorMode.Explain]: /Explain/,
|
[QueryEditorMode.Explain]: /Explain/,
|
||||||
@@ -186,5 +186,5 @@ function switchToMode(mode: QueryEditorMode) {
|
|||||||
}[mode];
|
}[mode];
|
||||||
|
|
||||||
const switchEl = screen.getByLabelText(label);
|
const switchEl = screen.getByLabelText(label);
|
||||||
userEvent.click(switchEl);
|
await userEvent.click(switchEl);
|
||||||
}
|
}
|
||||||
|
@@ -94,22 +94,22 @@ describe('PromQueryEditorByApp', () => {
|
|||||||
expect(queryByTestId(alertingTestIds.editor)).toBeNull();
|
expect(queryByTestId(alertingTestIds.editor)).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not run query onBlur in explore', () => {
|
it('should not run query onBlur in explore', async () => {
|
||||||
const { getByTestId, onRunQuery } = setup(CoreApp.Explore);
|
const { getByTestId, onRunQuery } = setup(CoreApp.Explore);
|
||||||
|
|
||||||
const input = getByTestId('dummy-code-input');
|
const input = getByTestId('dummy-code-input');
|
||||||
expect(input).toBeInTheDocument();
|
expect(input).toBeInTheDocument();
|
||||||
userEvent.type(input, 'metric');
|
await userEvent.type(input, 'metric');
|
||||||
input.blur();
|
input.blur();
|
||||||
expect(onRunQuery).not.toHaveBeenCalled();
|
expect(onRunQuery).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should run query onBlur in dashboard', () => {
|
it('should run query onBlur in dashboard', async () => {
|
||||||
const { getByTestId, onRunQuery } = setup(CoreApp.Dashboard);
|
const { getByTestId, onRunQuery } = setup(CoreApp.Dashboard);
|
||||||
|
|
||||||
const input = getByTestId('dummy-code-input');
|
const input = getByTestId('dummy-code-input');
|
||||||
expect(input).toBeInTheDocument();
|
expect(input).toBeInTheDocument();
|
||||||
userEvent.type(input, 'metric');
|
await userEvent.type(input, 'metric');
|
||||||
input.blur();
|
input.blur();
|
||||||
expect(onRunQuery).toHaveBeenCalled();
|
expect(onRunQuery).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render, screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
|
import { render, screen, waitFor } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
|
|
||||||
import { getTheme } from '@grafana/ui';
|
import { getTheme } from '@grafana/ui';
|
||||||
@@ -142,9 +142,9 @@ describe('PrometheusMetricsBrowser', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Clear label selection manually because it's saved in localStorage
|
// Clear label selection manually because it's saved in localStorage
|
||||||
afterEach(() => {
|
afterEach(async () => {
|
||||||
const clearBtn = screen.getByLabelText('Selector clear button');
|
const clearBtn = screen.getByLabelText('Selector clear button');
|
||||||
userEvent.click(clearBtn);
|
await userEvent.click(clearBtn);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders and loader shows when empty, and then first set of labels', async () => {
|
it('renders and loader shows when empty, and then first set of labels', async () => {
|
||||||
@@ -167,35 +167,34 @@ describe('PrometheusMetricsBrowser', () => {
|
|||||||
const props = setupProps();
|
const props = setupProps();
|
||||||
render(<UnthemedPrometheusMetricsBrowser {...props} />);
|
render(<UnthemedPrometheusMetricsBrowser {...props} />);
|
||||||
// Selecting label2
|
// Selecting label2
|
||||||
const label2 = await screen.findByRole('option', { name: /label2/, selected: false });
|
const label2 = await screen.findByRole('option', { name: 'label2', selected: false });
|
||||||
expect(screen.queryByRole('list', { name: /Values/ })).not.toBeInTheDocument();
|
expect(screen.queryByRole('list', { name: /Values/ })).not.toBeInTheDocument();
|
||||||
userEvent.click(label2);
|
await userEvent.click(label2);
|
||||||
expect(screen.queryByRole('option', { name: /label2/, selected: true })).toBeInTheDocument();
|
expect(screen.queryByRole('option', { name: 'label2', selected: true })).toBeInTheDocument();
|
||||||
// List of values for label2 appears
|
// List of values for label2 appears
|
||||||
expect(await screen.findAllByRole('list')).toHaveLength(1);
|
|
||||||
expect(screen.queryByLabelText(/Values for/)).toHaveTextContent('label2');
|
expect(screen.queryByLabelText(/Values for/)).toHaveTextContent('label2');
|
||||||
expect(screen.queryByRole('option', { name: 'value2-1' })).toBeInTheDocument();
|
expect(screen.queryByRole('option', { name: 'value2-1' })).toBeInTheDocument();
|
||||||
expect(screen.queryByRole('option', { name: 'value2-2' })).toBeInTheDocument();
|
expect(screen.queryByRole('option', { name: 'value2-2' })).toBeInTheDocument();
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
||||||
// Selecting label1, list for its values appears
|
// Selecting label1, list for its values appears
|
||||||
const label1 = await screen.findByRole('option', { name: /label1/, selected: false });
|
const label1 = await screen.findByRole('option', { name: 'label1', selected: false });
|
||||||
userEvent.click(label1);
|
await userEvent.click(label1);
|
||||||
expect(screen.queryByRole('option', { name: /label1/, selected: true })).toBeInTheDocument();
|
expect(screen.queryByRole('option', { name: 'label1', selected: true })).toBeInTheDocument();
|
||||||
await screen.findByLabelText('Values for label1');
|
await screen.findByLabelText('Values for label1');
|
||||||
expect(await screen.findAllByRole('list', { name: /Values/ })).toHaveLength(2);
|
expect(await screen.findAllByRole('list', { name: /Values/ })).toHaveLength(2);
|
||||||
// Selecting value2-2 of label2
|
// Selecting value2-2 of label2
|
||||||
const value = await screen.findByRole('option', { name: 'value2-2', selected: false });
|
const value = await screen.findByRole('option', { name: 'value2-2', selected: false });
|
||||||
userEvent.click(value);
|
await userEvent.click(value);
|
||||||
await screen.findByRole('option', { name: 'value2-2', selected: true });
|
await screen.findByRole('option', { name: 'value2-2', selected: true });
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label2="value2-2"}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label2="value2-2"}');
|
||||||
// Selecting value2-1 of label2, both values now selected
|
// Selecting value2-1 of label2, both values now selected
|
||||||
const value2 = await screen.findByRole('option', { name: 'value2-1', selected: false });
|
const value2 = await screen.findByRole('option', { name: 'value2-1', selected: false });
|
||||||
userEvent.click(value2);
|
await userEvent.click(value2);
|
||||||
// await screen.findByRole('option', {name: 'value2-1', selected: true});
|
// await screen.findByRole('option', {name: 'value2-1', selected: true});
|
||||||
await screen.findByText('{label2=~"value2-1|value2-2"}');
|
await screen.findByText('{label2=~"value2-1|value2-2"}');
|
||||||
// Deselecting value2-2, one value should remain
|
// Deselecting value2-2, one value should remain
|
||||||
const selectedValue = await screen.findByRole('option', { name: 'value2-2', selected: true });
|
const selectedValue = await screen.findByRole('option', { name: 'value2-2', selected: true });
|
||||||
userEvent.click(selectedValue);
|
await userEvent.click(selectedValue);
|
||||||
await screen.findByRole('option', { name: 'value2-1', selected: true });
|
await screen.findByRole('option', { name: 'value2-1', selected: true });
|
||||||
await screen.findByRole('option', { name: 'value2-2', selected: false });
|
await screen.findByRole('option', { name: 'value2-2', selected: false });
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label2="value2-1"}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label2="value2-1"}');
|
||||||
@@ -206,29 +205,31 @@ describe('PrometheusMetricsBrowser', () => {
|
|||||||
render(<UnthemedPrometheusMetricsBrowser {...props} />);
|
render(<UnthemedPrometheusMetricsBrowser {...props} />);
|
||||||
|
|
||||||
// Selecting label2
|
// Selecting label2
|
||||||
const label2 = await screen.findByRole('option', { name: /label2/, selected: false });
|
const label2 = await screen.findByRole('option', { name: 'label2', selected: false });
|
||||||
userEvent.click(label2);
|
await userEvent.click(label2);
|
||||||
// List of values for label2 appears
|
// List of values for label2 appears
|
||||||
expect(await screen.findAllByRole('list')).toHaveLength(1);
|
expect(screen.queryByLabelText(/Values for/)).toHaveTextContent('label2');
|
||||||
|
expect(screen.queryByRole('option', { name: 'value2-1' })).toBeInTheDocument();
|
||||||
|
expect(screen.queryByRole('option', { name: 'value2-2' })).toBeInTheDocument();
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
||||||
// Selecting label1, list for its values appears
|
// Selecting label1, list for its values appears
|
||||||
const label1 = await screen.findByRole('option', { name: /label1/, selected: false });
|
const label1 = await screen.findByRole('option', { name: 'label1', selected: false });
|
||||||
userEvent.click(label1);
|
await userEvent.click(label1);
|
||||||
await screen.findByLabelText('Values for label1');
|
await screen.findByLabelText('Values for label1');
|
||||||
expect(await screen.findAllByRole('list', { name: /Values/ })).toHaveLength(2);
|
expect(await screen.findAllByRole('list', { name: /Values/ })).toHaveLength(2);
|
||||||
// Selecting value2-1 of label2
|
// Selecting value2-1 of label2
|
||||||
const value2 = await screen.findByRole('option', { name: 'value2-1', selected: false });
|
const value2 = await screen.findByRole('option', { name: 'value2-1', selected: false });
|
||||||
userEvent.click(value2);
|
await userEvent.click(value2);
|
||||||
await screen.findByText('{label2="value2-1"}');
|
await screen.findByText('{label2="value2-1"}');
|
||||||
|
|
||||||
// Selecting value from label1 for combined selector
|
// Selecting value from label1 for combined selector
|
||||||
const value1 = await screen.findByRole('option', { name: 'value1-2', selected: false });
|
const value1 = await screen.findByRole('option', { name: 'value1-2', selected: false });
|
||||||
userEvent.click(value1);
|
await userEvent.click(value1);
|
||||||
await screen.findByRole('option', { name: 'value1-2', selected: true });
|
await screen.findByRole('option', { name: 'value1-2', selected: true });
|
||||||
await screen.findByText('{label1="value1-2",label2="value2-1"}');
|
await screen.findByText('{label1="value1-2",label2="value2-1"}');
|
||||||
// Deselect label1 should remove label and value
|
// Deselect label1 should remove label and value
|
||||||
const selectedLabel = (await screen.findAllByRole('option', { name: /label1/, selected: true }))[0];
|
const selectedLabel = (await screen.findAllByRole('option', { name: /label1/, selected: true }))[0];
|
||||||
userEvent.click(selectedLabel);
|
await userEvent.click(selectedLabel);
|
||||||
await screen.findByRole('option', { name: /label1/, selected: false });
|
await screen.findByRole('option', { name: /label1/, selected: false });
|
||||||
expect(await screen.findAllByRole('list', { name: /Values/ })).toHaveLength(1);
|
expect(await screen.findAllByRole('list', { name: /Values/ })).toHaveLength(1);
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label2="value2-1"}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label2="value2-1"}');
|
||||||
@@ -239,25 +240,27 @@ describe('PrometheusMetricsBrowser', () => {
|
|||||||
render(<UnthemedPrometheusMetricsBrowser {...props} />);
|
render(<UnthemedPrometheusMetricsBrowser {...props} />);
|
||||||
|
|
||||||
// Selecting label2
|
// Selecting label2
|
||||||
const label2 = await screen.findByRole('option', { name: /label2/, selected: false });
|
const label2 = await screen.findByRole('option', { name: 'label2', selected: false });
|
||||||
userEvent.click(label2);
|
await userEvent.click(label2);
|
||||||
// List of values for label2 appears
|
// List of values for label2 appears
|
||||||
expect(await screen.findAllByRole('list')).toHaveLength(1);
|
expect(screen.queryByLabelText(/Values for/)).toHaveTextContent('label2');
|
||||||
|
expect(screen.queryByRole('option', { name: 'value2-1' })).toBeInTheDocument();
|
||||||
|
expect(screen.queryByRole('option', { name: 'value2-2' })).toBeInTheDocument();
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
||||||
// Selecting label1, list for its values appears
|
// Selecting label1, list for its values appears
|
||||||
const label1 = await screen.findByRole('option', { name: /label1/, selected: false });
|
const label1 = await screen.findByRole('option', { name: 'label1', selected: false });
|
||||||
userEvent.click(label1);
|
await userEvent.click(label1);
|
||||||
await screen.findByLabelText('Values for label1');
|
await screen.findByLabelText('Values for label1');
|
||||||
expect(await screen.findAllByRole('list', { name: /Values/ })).toHaveLength(2);
|
expect(await screen.findAllByRole('list', { name: /Values/ })).toHaveLength(2);
|
||||||
// Selecting value2-1 of label2
|
// Selecting value2-1 of label2
|
||||||
const value2 = await screen.findByRole('option', { name: 'value2-1', selected: false });
|
const value2 = await screen.findByRole('option', { name: 'value2-1', selected: false });
|
||||||
userEvent.click(value2);
|
await userEvent.click(value2);
|
||||||
await screen.findByText('{label2="value2-1"}');
|
await screen.findByText('{label2="value2-1"}');
|
||||||
|
|
||||||
// Clear selector
|
// Clear selector
|
||||||
const clearBtn = screen.getByLabelText('Selector clear button');
|
const clearBtn = screen.getByLabelText('Selector clear button');
|
||||||
userEvent.click(clearBtn);
|
await userEvent.click(clearBtn);
|
||||||
await screen.findByRole('option', { name: /label2/, selected: false });
|
await screen.findByRole('option', { name: 'label2', selected: false });
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{}');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -266,14 +269,14 @@ describe('PrometheusMetricsBrowser', () => {
|
|||||||
render(<UnthemedPrometheusMetricsBrowser {...props} />);
|
render(<UnthemedPrometheusMetricsBrowser {...props} />);
|
||||||
// Selecting label2 and label1
|
// Selecting label2 and label1
|
||||||
const label2 = await screen.findByRole('option', { name: /label2/, selected: false });
|
const label2 = await screen.findByRole('option', { name: /label2/, selected: false });
|
||||||
userEvent.click(label2);
|
await userEvent.click(label2);
|
||||||
const label1 = await screen.findByRole('option', { name: /label1/, selected: false });
|
const label1 = await screen.findByRole('option', { name: /label1/, selected: false });
|
||||||
userEvent.click(label1);
|
await userEvent.click(label1);
|
||||||
await screen.findByLabelText('Values for label1');
|
await screen.findByLabelText('Values for label1');
|
||||||
await screen.findByLabelText('Values for label2');
|
await screen.findByLabelText('Values for label2');
|
||||||
expect(await screen.findAllByRole('option', { name: /value/ })).toHaveLength(4);
|
expect(await screen.findAllByRole('option', { name: /value/ })).toHaveLength(4);
|
||||||
// Typing '1' to filter for values
|
// Typing '1' to filter for values
|
||||||
userEvent.type(screen.getByLabelText('Filter expression for label values'), '1');
|
await userEvent.type(screen.getByLabelText('Filter expression for label values'), '1');
|
||||||
expect(screen.getByLabelText('Filter expression for label values')).toHaveValue('1');
|
expect(screen.getByLabelText('Filter expression for label values')).toHaveValue('1');
|
||||||
expect(await screen.findAllByRole('option', { name: /value/ })).toHaveLength(3);
|
expect(await screen.findAllByRole('option', { name: /value/ })).toHaveLength(3);
|
||||||
expect(screen.queryByRole('option', { name: 'value2-2' })).not.toBeInTheDocument();
|
expect(screen.queryByRole('option', { name: 'value2-2' })).not.toBeInTheDocument();
|
||||||
@@ -284,26 +287,26 @@ describe('PrometheusMetricsBrowser', () => {
|
|||||||
render(<UnthemedPrometheusMetricsBrowser {...props} />);
|
render(<UnthemedPrometheusMetricsBrowser {...props} />);
|
||||||
// Selecting label2 and label1
|
// Selecting label2 and label1
|
||||||
const label2 = await screen.findByRole('option', { name: /label2/, selected: false });
|
const label2 = await screen.findByRole('option', { name: /label2/, selected: false });
|
||||||
userEvent.click(label2);
|
await userEvent.click(label2);
|
||||||
const label1 = await screen.findByRole('option', { name: /label1/, selected: false });
|
const label1 = await screen.findByRole('option', { name: /label1/, selected: false });
|
||||||
userEvent.click(label1);
|
await userEvent.click(label1);
|
||||||
await screen.findByLabelText('Values for label1');
|
await screen.findByLabelText('Values for label1');
|
||||||
await screen.findByLabelText('Values for label2');
|
await screen.findByLabelText('Values for label2');
|
||||||
expect(await screen.findAllByRole('option', { name: /value/ })).toHaveLength(4);
|
expect(await screen.findAllByRole('option', { name: /value/ })).toHaveLength(4);
|
||||||
expect(screen.queryByRole('option', { name: /label3/ })).toHaveTextContent('label3');
|
expect(screen.queryByRole('option', { name: /label3/ })).toHaveTextContent('label3');
|
||||||
// Click value1-1 which triggers facetting for value3-x, and still show all value1-x
|
// Click value1-1 which triggers facetting for value3-x, and still show all value1-x
|
||||||
const value1 = await screen.findByRole('option', { name: 'value1-1', selected: false });
|
const value1 = await screen.findByRole('option', { name: 'value1-1', selected: false });
|
||||||
userEvent.click(value1);
|
await userEvent.click(value1);
|
||||||
await waitForElementToBeRemoved(screen.queryByRole('option', { name: 'value2-2' }));
|
await waitFor(() => expect(screen.queryByRole('option', { name: 'value2-2' })).not.toBeInTheDocument());
|
||||||
expect(screen.queryByRole('option', { name: 'value1-2' })).toBeInTheDocument();
|
expect(screen.queryByRole('option', { name: 'value1-2' })).toBeInTheDocument();
|
||||||
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label1="value1-1"}');
|
expect(screen.queryByLabelText('selector')).toHaveTextContent('{label1="value1-1"}');
|
||||||
expect(screen.queryByRole('option', { name: /label3/ })).toHaveTextContent('label3 (1)');
|
expect(screen.queryByRole('option', { name: /label3/ })).toHaveTextContent('label3 (1)');
|
||||||
// Click value1-2 for which facetting will allow more values for value3-x
|
// Click value1-2 for which facetting will allow more values for value3-x
|
||||||
const value12 = await screen.findByRole('option', { name: 'value1-2', selected: false });
|
const value12 = await screen.findByRole('option', { name: 'value1-2', selected: false });
|
||||||
userEvent.click(value12);
|
await userEvent.click(value12);
|
||||||
await screen.findByRole('option', { name: 'value1-2', selected: true });
|
await screen.findByRole('option', { name: 'value1-2', selected: true });
|
||||||
await screen.findByRole('option', { name: /label3/, selected: false });
|
await screen.findByRole('option', { name: /label3/, selected: false });
|
||||||
userEvent.click(screen.getByRole('option', { name: /label3/ }));
|
await userEvent.click(screen.getByRole('option', { name: /label3/ }));
|
||||||
await screen.findByLabelText('Values for label3');
|
await screen.findByLabelText('Values for label3');
|
||||||
expect(screen.queryByRole('option', { name: 'value1-1', selected: true })).toBeInTheDocument();
|
expect(screen.queryByRole('option', { name: 'value1-1', selected: true })).toBeInTheDocument();
|
||||||
expect(screen.queryByRole('option', { name: 'value1-2', selected: true })).toBeInTheDocument();
|
expect(screen.queryByRole('option', { name: 'value1-2', selected: true })).toBeInTheDocument();
|
||||||
|
@@ -29,7 +29,7 @@ describe('MetricSelect', () => {
|
|||||||
render(<MetricSelect {...props} />);
|
render(<MetricSelect {...props} />);
|
||||||
await openMetricSelect();
|
await openMetricSelect();
|
||||||
const input = screen.getByRole('combobox');
|
const input = screen.getByRole('combobox');
|
||||||
userEvent.type(input, 'new');
|
await userEvent.type(input, 'new');
|
||||||
await waitFor(() => expect(screen.getByText('Create: new')).toBeInTheDocument());
|
await waitFor(() => expect(screen.getByText('Create: new')).toBeInTheDocument());
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ describe('MetricSelect', () => {
|
|||||||
render(<MetricSelect {...props} />);
|
render(<MetricSelect {...props} />);
|
||||||
await openMetricSelect();
|
await openMetricSelect();
|
||||||
const input = screen.getByRole('combobox');
|
const input = screen.getByRole('combobox');
|
||||||
userEvent.type(input, 'unique');
|
await userEvent.type(input, 'unique');
|
||||||
await waitFor(() => expect(screen.getAllByLabelText('Select option')).toHaveLength(3));
|
await waitFor(() => expect(screen.getAllByLabelText('Select option')).toHaveLength(3));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ describe('MetricSelect', () => {
|
|||||||
render(<MetricSelect {...props} />);
|
render(<MetricSelect {...props} />);
|
||||||
await openMetricSelect();
|
await openMetricSelect();
|
||||||
const input = screen.getByRole('combobox');
|
const input = screen.getByRole('combobox');
|
||||||
userEvent.type(input, 'more unique');
|
await userEvent.type(input, 'more unique');
|
||||||
await waitFor(() => expect(screen.getAllByLabelText('Select option')).toHaveLength(2));
|
await waitFor(() => expect(screen.getAllByLabelText('Select option')).toHaveLength(2));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ describe('MetricSelect', () => {
|
|||||||
render(<MetricSelect {...props} />);
|
render(<MetricSelect {...props} />);
|
||||||
await openMetricSelect();
|
await openMetricSelect();
|
||||||
const input = screen.getByRole('combobox');
|
const input = screen.getByRole('combobox');
|
||||||
userEvent.type(input, 'more unique metric');
|
await userEvent.type(input, 'more unique metric');
|
||||||
await waitFor(() => expect(screen.getAllByLabelText('Select option')).toHaveLength(2));
|
await waitFor(() => expect(screen.getAllByLabelText('Select option')).toHaveLength(2));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ describe('MetricSelect', () => {
|
|||||||
const { container } = render(<MetricSelect {...props} />);
|
const { container } = render(<MetricSelect {...props} />);
|
||||||
await openMetricSelect();
|
await openMetricSelect();
|
||||||
const input = screen.getByRole('combobox');
|
const input = screen.getByRole('combobox');
|
||||||
userEvent.type(input, 'more');
|
await userEvent.type(input, 'more');
|
||||||
await waitFor(() => expect(container.querySelectorAll('mark')).toHaveLength(1));
|
await waitFor(() => expect(container.querySelectorAll('mark')).toHaveLength(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ describe('MetricSelect', () => {
|
|||||||
const { container } = render(<MetricSelect {...props} />);
|
const { container } = render(<MetricSelect {...props} />);
|
||||||
await openMetricSelect();
|
await openMetricSelect();
|
||||||
const input = screen.getByRole('combobox');
|
const input = screen.getByRole('combobox');
|
||||||
userEvent.type(input, 'more metric');
|
await userEvent.type(input, 'more metric');
|
||||||
await waitFor(() => expect(container.querySelectorAll('mark')).toHaveLength(2));
|
await waitFor(() => expect(container.querySelectorAll('mark')).toHaveLength(2));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ describe('MetricSelect', () => {
|
|||||||
const { container } = render(<MetricSelect {...props} />);
|
const { container } = render(<MetricSelect {...props} />);
|
||||||
await openMetricSelect();
|
await openMetricSelect();
|
||||||
const input = screen.getByRole('combobox');
|
const input = screen.getByRole('combobox');
|
||||||
userEvent.type(input, 'unique metric');
|
await userEvent.type(input, 'unique metric');
|
||||||
await waitFor(() => expect(container.querySelectorAll('mark')).toHaveLength(4));
|
await waitFor(() => expect(container.querySelectorAll('mark')).toHaveLength(4));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -85,12 +85,12 @@ describe('MetricSelect', () => {
|
|||||||
const { container } = render(<MetricSelect {...props} />);
|
const { container } = render(<MetricSelect {...props} />);
|
||||||
await openMetricSelect();
|
await openMetricSelect();
|
||||||
const input = screen.getByRole('combobox');
|
const input = screen.getByRole('combobox');
|
||||||
userEvent.type(input, 'new');
|
await userEvent.type(input, 'new');
|
||||||
await waitFor(() => expect(container.querySelector('mark')).not.toBeInTheDocument());
|
await waitFor(() => expect(container.querySelector('mark')).not.toBeInTheDocument());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
async function openMetricSelect() {
|
async function openMetricSelect() {
|
||||||
const select = await screen.getByText('Select metric').parentElement!;
|
const select = await screen.getByText('Select metric').parentElement!;
|
||||||
userEvent.click(select);
|
await userEvent.click(select);
|
||||||
}
|
}
|
||||||
|
@@ -70,7 +70,7 @@ describe('PromQueryBuilder', () => {
|
|||||||
|
|
||||||
it('tries to load metrics without labels', async () => {
|
it('tries to load metrics without labels', async () => {
|
||||||
const { languageProvider, container } = setup();
|
const { languageProvider, container } = setup();
|
||||||
openMetricSelect(container);
|
await openMetricSelect(container);
|
||||||
await waitFor(() => expect(languageProvider.getLabelValues).toBeCalledWith('__name__'));
|
await waitFor(() => expect(languageProvider.getLabelValues).toBeCalledWith('__name__'));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -79,27 +79,27 @@ describe('PromQueryBuilder', () => {
|
|||||||
...defaultQuery,
|
...defaultQuery,
|
||||||
labels: [{ label: 'label_name', op: '=', value: 'label_value' }],
|
labels: [{ label: 'label_name', op: '=', value: 'label_value' }],
|
||||||
});
|
});
|
||||||
openMetricSelect(container);
|
await openMetricSelect(container);
|
||||||
await waitFor(() => expect(languageProvider.getSeries).toBeCalledWith('{label_name="label_value"}', true));
|
await waitFor(() => expect(languageProvider.getSeries).toBeCalledWith('{label_name="label_value"}', true));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tries to load variables in metric field', async () => {
|
it('tries to load variables in metric field', async () => {
|
||||||
const { datasource, container } = setup();
|
const { datasource, container } = setup();
|
||||||
datasource.getVariables = jest.fn().mockReturnValue([]);
|
datasource.getVariables = jest.fn().mockReturnValue([]);
|
||||||
openMetricSelect(container);
|
await openMetricSelect(container);
|
||||||
await waitFor(() => expect(datasource.getVariables).toBeCalled());
|
await waitFor(() => expect(datasource.getVariables).toBeCalled());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tries to load labels when metric selected', async () => {
|
it('tries to load labels when metric selected', async () => {
|
||||||
const { languageProvider } = setup();
|
const { languageProvider } = setup();
|
||||||
openLabelNameSelect();
|
await openLabelNameSelect();
|
||||||
await waitFor(() => expect(languageProvider.fetchSeriesLabels).toBeCalledWith('{__name__="random_metric"}'));
|
await waitFor(() => expect(languageProvider.fetchSeriesLabels).toBeCalledWith('{__name__="random_metric"}'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('tries to load variables in label field', async () => {
|
it('tries to load variables in label field', async () => {
|
||||||
const { datasource } = setup();
|
const { datasource } = setup();
|
||||||
datasource.getVariables = jest.fn().mockReturnValue([]);
|
datasource.getVariables = jest.fn().mockReturnValue([]);
|
||||||
openLabelNameSelect();
|
await openLabelNameSelect();
|
||||||
await waitFor(() => expect(datasource.getVariables).toBeCalled());
|
await waitFor(() => expect(datasource.getVariables).toBeCalled());
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ describe('PromQueryBuilder', () => {
|
|||||||
{ label: 'foo', op: '=', value: 'bar' },
|
{ label: 'foo', op: '=', value: 'bar' },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
openLabelNameSelect(1);
|
await openLabelNameSelect(1);
|
||||||
await waitFor(() =>
|
await waitFor(() =>
|
||||||
expect(languageProvider.fetchSeriesLabels).toBeCalledWith('{label_name="label_value", __name__="random_metric"}')
|
expect(languageProvider.fetchSeriesLabels).toBeCalledWith('{label_name="label_value", __name__="random_metric"}')
|
||||||
);
|
);
|
||||||
@@ -122,7 +122,7 @@ describe('PromQueryBuilder', () => {
|
|||||||
...defaultQuery,
|
...defaultQuery,
|
||||||
metric: '',
|
metric: '',
|
||||||
});
|
});
|
||||||
openLabelNameSelect();
|
await openLabelNameSelect();
|
||||||
await waitFor(() => expect(languageProvider.fetchLabels).toBeCalled());
|
await waitFor(() => expect(languageProvider.fetchLabels).toBeCalled());
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -132,8 +132,8 @@ describe('PromQueryBuilder', () => {
|
|||||||
labels: [],
|
labels: [],
|
||||||
operations: [],
|
operations: [],
|
||||||
});
|
});
|
||||||
openMetricSelect(container);
|
await openMetricSelect(container);
|
||||||
userEvent.click(screen.getByText('histogram_metric_bucket'));
|
await userEvent.click(screen.getByText('histogram_metric_bucket'));
|
||||||
await waitFor(() => expect(screen.getByText('hint: add histogram_quantile()')).toBeInTheDocument());
|
await waitFor(() => expect(screen.getByText('hint: add histogram_quantile()')).toBeInTheDocument());
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -143,8 +143,8 @@ describe('PromQueryBuilder', () => {
|
|||||||
labels: [],
|
labels: [],
|
||||||
operations: [],
|
operations: [],
|
||||||
});
|
});
|
||||||
openMetricSelect(container);
|
await openMetricSelect(container);
|
||||||
userEvent.click(screen.getByText('histogram_metric_sum'));
|
await userEvent.click(screen.getByText('histogram_metric_sum'));
|
||||||
await waitFor(() => expect(screen.getByText('hint: add rate()')).toBeInTheDocument());
|
await waitFor(() => expect(screen.getByText('hint: add rate()')).toBeInTheDocument());
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -154,8 +154,8 @@ describe('PromQueryBuilder', () => {
|
|||||||
labels: [],
|
labels: [],
|
||||||
operations: [],
|
operations: [],
|
||||||
});
|
});
|
||||||
openMetricSelect(container);
|
await openMetricSelect(container);
|
||||||
userEvent.click(screen.getByText('histogram_metric_sum'));
|
await userEvent.click(screen.getByText('histogram_metric_sum'));
|
||||||
await waitFor(() => expect(screen.getByText('hint: add rate()')).toBeInTheDocument());
|
await waitFor(() => expect(screen.getByText('hint: add rate()')).toBeInTheDocument());
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -176,9 +176,9 @@ describe('PromQueryBuilder', () => {
|
|||||||
},
|
},
|
||||||
data
|
data
|
||||||
);
|
);
|
||||||
openMetricSelect(container);
|
await openMetricSelect(container);
|
||||||
userEvent.click(screen.getByText('histogram_metric_sum'));
|
await userEvent.click(screen.getByText('histogram_metric_sum'));
|
||||||
await waitFor(() => expect(screen.getAllByText(/hint:/g)).toHaveLength(2));
|
await waitFor(() => expect(screen.getAllByText(/hint:/)).toHaveLength(2));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -205,14 +205,14 @@ function setup(query: PromVisualQuery = defaultQuery, data?: PanelData) {
|
|||||||
return { languageProvider, datasource, container };
|
return { languageProvider, datasource, container };
|
||||||
}
|
}
|
||||||
|
|
||||||
function openMetricSelect(container: HTMLElement) {
|
async function openMetricSelect(container: HTMLElement) {
|
||||||
const select = container.querySelector('#prometheus-metric-select');
|
const select = container.querySelector('#prometheus-metric-select');
|
||||||
if (select) {
|
if (select) {
|
||||||
userEvent.click(select);
|
await userEvent.click(select);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function openLabelNameSelect(index = 0) {
|
async function openLabelNameSelect(index = 0) {
|
||||||
const { name } = getLabelSelects(index);
|
const { name } = getLabelSelects(index);
|
||||||
userEvent.click(name);
|
await userEvent.click(name);
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@ describe('PromQueryBuilderContainer', () => {
|
|||||||
const { props } = setup({ expr: 'rate(metric_test{job="testjob"}[$__rate_interval])' });
|
const { props } = setup({ expr: 'rate(metric_test{job="testjob"}[$__rate_interval])' });
|
||||||
|
|
||||||
expect(screen.getByText('metric_test')).toBeInTheDocument();
|
expect(screen.getByText('metric_test')).toBeInTheDocument();
|
||||||
addOperation('Range functions', 'Rate');
|
await addOperation('Range functions', 'Rate');
|
||||||
expect(props.onChange).toBeCalledWith({
|
expect(props.onChange).toBeCalledWith({
|
||||||
expr: 'rate(metric_test{job="testjob"}[$__rate_interval])',
|
expr: 'rate(metric_test{job="testjob"}[$__rate_interval])',
|
||||||
refId: 'A',
|
refId: 'A',
|
||||||
@@ -23,7 +23,7 @@ describe('PromQueryBuilderContainer', () => {
|
|||||||
|
|
||||||
it('Can add rest param', async () => {
|
it('Can add rest param', async () => {
|
||||||
const { container } = setup({ expr: 'sum(ALERTS)' });
|
const { container } = setup({ expr: 'sum(ALERTS)' });
|
||||||
userEvent.click(screen.getByTestId('operations.0.add-rest-param'));
|
await userEvent.click(screen.getByTestId('operations.0.add-rest-param'));
|
||||||
|
|
||||||
waitFor(() => {
|
waitFor(() => {
|
||||||
expect(container.querySelector(`${getOperationParamId(0, 0)}`)).toBeInTheDocument();
|
expect(container.querySelector(`${getOperationParamId(0, 0)}`)).toBeInTheDocument();
|
||||||
|
@@ -81,7 +81,7 @@ describe('PromQueryEditorSelector', () => {
|
|||||||
|
|
||||||
it('changes to builder mode', async () => {
|
it('changes to builder mode', async () => {
|
||||||
const { onChange } = renderWithMode(QueryEditorMode.Code);
|
const { onChange } = renderWithMode(QueryEditorMode.Code);
|
||||||
switchToMode(QueryEditorMode.Builder);
|
await switchToMode(QueryEditorMode.Builder);
|
||||||
expect(onChange).toBeCalledWith({
|
expect(onChange).toBeCalledWith({
|
||||||
refId: 'A',
|
refId: 'A',
|
||||||
expr: defaultQuery.expr,
|
expr: defaultQuery.expr,
|
||||||
@@ -116,7 +116,7 @@ describe('PromQueryEditorSelector', () => {
|
|||||||
|
|
||||||
it('changes to code mode', async () => {
|
it('changes to code mode', async () => {
|
||||||
const { onChange } = renderWithMode(QueryEditorMode.Builder);
|
const { onChange } = renderWithMode(QueryEditorMode.Builder);
|
||||||
switchToMode(QueryEditorMode.Code);
|
await switchToMode(QueryEditorMode.Code);
|
||||||
expect(onChange).toBeCalledWith({
|
expect(onChange).toBeCalledWith({
|
||||||
refId: 'A',
|
refId: 'A',
|
||||||
expr: defaultQuery.expr,
|
expr: defaultQuery.expr,
|
||||||
@@ -127,7 +127,7 @@ describe('PromQueryEditorSelector', () => {
|
|||||||
|
|
||||||
it('changes to explain mode', async () => {
|
it('changes to explain mode', async () => {
|
||||||
const { onChange } = renderWithMode(QueryEditorMode.Code);
|
const { onChange } = renderWithMode(QueryEditorMode.Code);
|
||||||
switchToMode(QueryEditorMode.Explain);
|
await switchToMode(QueryEditorMode.Explain);
|
||||||
expect(onChange).toBeCalledWith({
|
expect(onChange).toBeCalledWith({
|
||||||
refId: 'A',
|
refId: 'A',
|
||||||
expr: defaultQuery.expr,
|
expr: defaultQuery.expr,
|
||||||
@@ -142,7 +142,7 @@ describe('PromQueryEditorSelector', () => {
|
|||||||
expr: 'rate(test_metric{instance="host.docker.internal:3000"}[$__interval])',
|
expr: 'rate(test_metric{instance="host.docker.internal:3000"}[$__interval])',
|
||||||
editorMode: QueryEditorMode.Code,
|
editorMode: QueryEditorMode.Code,
|
||||||
});
|
});
|
||||||
switchToMode(QueryEditorMode.Builder);
|
await switchToMode(QueryEditorMode.Builder);
|
||||||
rerender(
|
rerender(
|
||||||
<PromQueryEditorSelector
|
<PromQueryEditorSelector
|
||||||
{...defaultProps}
|
{...defaultProps}
|
||||||
@@ -187,7 +187,7 @@ function expectExplain() {
|
|||||||
expect(screen.getByText(/Fetch all series/)).toBeInTheDocument();
|
expect(screen.getByText(/Fetch all series/)).toBeInTheDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
function switchToMode(mode: QueryEditorMode) {
|
async function switchToMode(mode: QueryEditorMode) {
|
||||||
const label = {
|
const label = {
|
||||||
[QueryEditorMode.Code]: /Code/,
|
[QueryEditorMode.Code]: /Code/,
|
||||||
[QueryEditorMode.Explain]: /Explain/,
|
[QueryEditorMode.Explain]: /Explain/,
|
||||||
@@ -195,5 +195,5 @@ function switchToMode(mode: QueryEditorMode) {
|
|||||||
}[mode];
|
}[mode];
|
||||||
|
|
||||||
const switchEl = screen.getByLabelText(label);
|
const switchEl = screen.getByLabelText(label);
|
||||||
userEvent.click(switchEl);
|
await userEvent.click(switchEl);
|
||||||
}
|
}
|
||||||
|
@@ -31,7 +31,7 @@ describe('LabelFilters', () => {
|
|||||||
|
|
||||||
it('adds new label', async () => {
|
it('adds new label', async () => {
|
||||||
const { onChange } = setup([{ label: 'foo', op: '=', value: 'bar' }]);
|
const { onChange } = setup([{ label: 'foo', op: '=', value: 'bar' }]);
|
||||||
userEvent.click(getAddButton());
|
await userEvent.click(getAddButton());
|
||||||
expect(screen.getAllByText(/Choose/)).toHaveLength(2);
|
expect(screen.getAllByText(/Choose/)).toHaveLength(2);
|
||||||
const { name, value } = getLabelSelects(1);
|
const { name, value } = getLabelSelects(1);
|
||||||
await selectOptionInTest(name, 'baz');
|
await selectOptionInTest(name, 'baz');
|
||||||
@@ -44,7 +44,7 @@ describe('LabelFilters', () => {
|
|||||||
|
|
||||||
it('removes label', async () => {
|
it('removes label', async () => {
|
||||||
const { onChange } = setup([{ label: 'foo', op: '=', value: 'bar' }]);
|
const { onChange } = setup([{ label: 'foo', op: '=', value: 'bar' }]);
|
||||||
userEvent.click(screen.getByLabelText(/remove/));
|
await userEvent.click(screen.getByLabelText(/remove/));
|
||||||
expect(onChange).toBeCalledWith([]);
|
expect(onChange).toBeCalledWith([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -36,7 +36,7 @@ describe('OperationList', () => {
|
|||||||
const { onChange } = setup();
|
const { onChange } = setup();
|
||||||
const removeOperationButtons = screen.getAllByTitle('Remove operation');
|
const removeOperationButtons = screen.getAllByTitle('Remove operation');
|
||||||
expect(removeOperationButtons).toHaveLength(2);
|
expect(removeOperationButtons).toHaveLength(2);
|
||||||
userEvent.click(removeOperationButtons[1]);
|
await userEvent.click(removeOperationButtons[1]);
|
||||||
expect(onChange).toBeCalledWith({
|
expect(onChange).toBeCalledWith({
|
||||||
labels: [{ label: 'instance', op: '=', value: 'localhost:9090' }],
|
labels: [{ label: 'instance', op: '=', value: 'localhost:9090' }],
|
||||||
metric: 'random_metric',
|
metric: 'random_metric',
|
||||||
@@ -46,7 +46,7 @@ describe('OperationList', () => {
|
|||||||
|
|
||||||
it('adds an operation', async () => {
|
it('adds an operation', async () => {
|
||||||
const { onChange } = setup();
|
const { onChange } = setup();
|
||||||
addOperation('Aggregations', 'Min');
|
await addOperation('Aggregations', 'Min');
|
||||||
expect(onChange).toBeCalledWith({
|
expect(onChange).toBeCalledWith({
|
||||||
labels: [{ label: 'instance', op: '=', value: 'localhost:9090' }],
|
labels: [{ label: 'instance', op: '=', value: 'localhost:9090' }],
|
||||||
metric: 'random_metric',
|
metric: 'random_metric',
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
import { screen, fireEvent } from '@testing-library/react';
|
import { screen, fireEvent } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
|
|
||||||
export function addOperation(section: string, op: string) {
|
export async function addOperation(section: string, op: string) {
|
||||||
const addOperationButton = screen.getByTitle('Add operation');
|
const addOperationButton = screen.getByTitle('Add operation');
|
||||||
expect(addOperationButton).toBeInTheDocument();
|
expect(addOperationButton).toBeInTheDocument();
|
||||||
userEvent.click(addOperationButton);
|
await userEvent.click(addOperationButton);
|
||||||
const sectionItem = screen.getByTitle(section);
|
const sectionItem = screen.getByTitle(section);
|
||||||
expect(sectionItem).toBeInTheDocument();
|
expect(sectionItem).toBeInTheDocument();
|
||||||
// Weirdly the userEvent.click doesn't work here, it reports the item has pointer-events: none. Don't see that
|
// Weirdly the await userEvent.click doesn't work here, it reports the item has pointer-events: none. Don't see that
|
||||||
// anywhere when debugging so not sure what style is it picking up.
|
// anywhere when debugging so not sure what style is it picking up.
|
||||||
fireEvent.click(sectionItem.children[0]);
|
fireEvent.click(sectionItem.children[0]);
|
||||||
const opItem = screen.getByTitle(op);
|
const opItem = screen.getByTitle(op);
|
||||||
|
@@ -1,20 +1,25 @@
|
|||||||
import NativeSearch from './NativeSearch';
|
import NativeSearch from './NativeSearch';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act, render, screen } from '@testing-library/react';
|
import { render, screen, waitFor } from '@testing-library/react';
|
||||||
import { TempoDatasource, TempoQuery } from '../datasource';
|
import { TempoDatasource, TempoQuery } from '../datasource';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
|
import { UserEvent } from '@testing-library/user-event/dist/types/setup';
|
||||||
|
|
||||||
const getOptions = jest.fn().mockImplementation(() => {
|
const getOptions = jest.fn().mockImplementation(() => {
|
||||||
return Promise.resolve([
|
return new Promise((resolve) => {
|
||||||
{
|
setTimeout(() => {
|
||||||
value: 'customer',
|
resolve([
|
||||||
label: 'customer',
|
{
|
||||||
},
|
value: 'customer',
|
||||||
{
|
label: 'customer',
|
||||||
value: 'driver',
|
},
|
||||||
label: 'driver',
|
{
|
||||||
},
|
value: 'driver',
|
||||||
]);
|
label: 'driver',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.mock('../language_provider', () => {
|
jest.mock('../language_provider', () => {
|
||||||
@@ -31,6 +36,36 @@ const mockQuery = {
|
|||||||
} as TempoQuery;
|
} as TempoQuery;
|
||||||
|
|
||||||
describe('NativeSearch', () => {
|
describe('NativeSearch', () => {
|
||||||
|
let user: UserEvent;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
// 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 });
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.useRealTimers();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show loader when there is a delay', async () => {
|
||||||
|
render(
|
||||||
|
<NativeSearch datasource={{} as TempoDatasource} query={mockQuery} onChange={jest.fn()} onRunQuery={jest.fn()} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const asyncServiceSelect = screen.getByRole('combobox', { name: 'select-span-name' });
|
||||||
|
|
||||||
|
await user.click(asyncServiceSelect);
|
||||||
|
const loader = screen.getByText('Loading options...');
|
||||||
|
|
||||||
|
expect(loader).toBeInTheDocument();
|
||||||
|
|
||||||
|
jest.advanceTimersByTime(1000);
|
||||||
|
|
||||||
|
await waitFor(() => expect(screen.queryByText('Loading options...')).not.toBeInTheDocument());
|
||||||
|
});
|
||||||
|
|
||||||
it('should call the `onChange` function on click of the Input', async () => {
|
it('should call the `onChange` function on click of the Input', async () => {
|
||||||
const promise = Promise.resolve();
|
const promise = Promise.resolve();
|
||||||
const handleOnChange = jest.fn(() => promise);
|
const handleOnChange = jest.fn(() => promise);
|
||||||
@@ -54,56 +89,12 @@ describe('NativeSearch', () => {
|
|||||||
const asyncServiceSelect = await screen.findByRole('combobox', { name: 'select-span-name' });
|
const asyncServiceSelect = await screen.findByRole('combobox', { name: 'select-span-name' });
|
||||||
|
|
||||||
expect(asyncServiceSelect).toBeInTheDocument();
|
expect(asyncServiceSelect).toBeInTheDocument();
|
||||||
userEvent.click(asyncServiceSelect);
|
await user.click(asyncServiceSelect);
|
||||||
|
jest.advanceTimersByTime(1000);
|
||||||
|
|
||||||
const driverOption = await screen.findByText('driver');
|
const driverOption = await screen.findByText('driver');
|
||||||
userEvent.click(driverOption);
|
await user.click(driverOption);
|
||||||
|
|
||||||
expect(handleOnChange).toHaveBeenCalledWith(fakeOptionChoice);
|
expect(handleOnChange).toHaveBeenCalledWith(fakeOptionChoice);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('TempoLanguageProvider with delay', () => {
|
|
||||||
const getOptions2 = jest.fn().mockImplementation(() => {
|
|
||||||
return Promise.resolve([
|
|
||||||
{
|
|
||||||
value: 'customer',
|
|
||||||
label: 'customer',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'driver',
|
|
||||||
label: 'driver',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
jest.mock('../language_provider', () => {
|
|
||||||
return jest.fn().mockImplementation(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
return { getOptions2 };
|
|
||||||
}, 3000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show loader', async () => {
|
|
||||||
const promise = Promise.resolve();
|
|
||||||
const handleOnChange = jest.fn(() => promise);
|
|
||||||
|
|
||||||
render(
|
|
||||||
<NativeSearch
|
|
||||||
datasource={{} as TempoDatasource}
|
|
||||||
query={mockQuery}
|
|
||||||
onChange={handleOnChange}
|
|
||||||
onRunQuery={() => {}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
const asyncServiceSelect = screen.getByRole('combobox', { name: 'select-span-name' });
|
|
||||||
|
|
||||||
userEvent.click(asyncServiceSelect);
|
|
||||||
const loader = screen.getByText('Loading options...');
|
|
||||||
|
|
||||||
expect(loader).toBeInTheDocument();
|
|
||||||
await act(() => promise);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
@@ -200,7 +200,7 @@ describe('AnnoListPanel', () => {
|
|||||||
|
|
||||||
getMock.mockClear();
|
getMock.mockClear();
|
||||||
expect(screen.getByText(/result text/i)).toBeInTheDocument();
|
expect(screen.getByText(/result text/i)).toBeInTheDocument();
|
||||||
userEvent.click(screen.getByText(/result text/i));
|
await userEvent.click(screen.getByText(/result text/i));
|
||||||
await waitFor(() => expect(getMock).toHaveBeenCalledTimes(1));
|
await waitFor(() => expect(getMock).toHaveBeenCalledTimes(1));
|
||||||
|
|
||||||
expect(getMock).toHaveBeenCalledWith('/api/search', { dashboardIds: 14 });
|
expect(getMock).toHaveBeenCalledWith('/api/search', { dashboardIds: 14 });
|
||||||
@@ -215,7 +215,7 @@ describe('AnnoListPanel', () => {
|
|||||||
|
|
||||||
getMock.mockClear();
|
getMock.mockClear();
|
||||||
expect(screen.getByText('Result tag B')).toBeInTheDocument();
|
expect(screen.getByText('Result tag B')).toBeInTheDocument();
|
||||||
userEvent.click(screen.getByText('Result tag B'));
|
await userEvent.click(screen.getByText('Result tag B'));
|
||||||
|
|
||||||
expect(getMock).toHaveBeenCalledTimes(1);
|
expect(getMock).toHaveBeenCalledTimes(1);
|
||||||
expect(getMock).toHaveBeenCalledWith(
|
expect(getMock).toHaveBeenCalledWith(
|
||||||
@@ -239,7 +239,7 @@ describe('AnnoListPanel', () => {
|
|||||||
|
|
||||||
getMock.mockClear();
|
getMock.mockClear();
|
||||||
expect(screen.getByRole('img')).toBeInTheDocument();
|
expect(screen.getByRole('img')).toBeInTheDocument();
|
||||||
userEvent.click(screen.getByRole('img'));
|
await userEvent.click(screen.getByRole('img'));
|
||||||
|
|
||||||
expect(getMock).toHaveBeenCalledTimes(1);
|
expect(getMock).toHaveBeenCalledTimes(1);
|
||||||
expect(getMock).toHaveBeenCalledWith(
|
expect(getMock).toHaveBeenCalledWith(
|
||||||
|
@@ -3,7 +3,6 @@ import { render, screen, fireEvent, waitFor, getByText } from '@testing-library/
|
|||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { NodeGraph } from './NodeGraph';
|
import { NodeGraph } from './NodeGraph';
|
||||||
import { makeEdgesDataFrame, makeNodesDataFrame } from './utils';
|
import { makeEdgesDataFrame, makeNodesDataFrame } from './utils';
|
||||||
import { act } from 'react-dom/test-utils';
|
|
||||||
|
|
||||||
jest.mock('react-use/lib/useMeasure', () => {
|
jest.mock('react-use/lib/useMeasure', () => {
|
||||||
return {
|
return {
|
||||||
@@ -32,9 +31,9 @@ describe('NodeGraph', () => {
|
|||||||
const zoomOut = await screen.findByTitle(/Zoom out/);
|
const zoomOut = await screen.findByTitle(/Zoom out/);
|
||||||
|
|
||||||
expect(getScale()).toBe(1);
|
expect(getScale()).toBe(1);
|
||||||
userEvent.click(zoomIn);
|
await userEvent.click(zoomIn);
|
||||||
expect(getScale()).toBe(1.5);
|
expect(getScale()).toBe(1.5);
|
||||||
userEvent.click(zoomOut);
|
await userEvent.click(zoomOut);
|
||||||
expect(getScale()).toBe(1);
|
expect(getScale()).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -84,17 +83,11 @@ describe('NodeGraph', () => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
const node = await screen.findByLabelText(/Node: service:0/);
|
const node = await screen.findByLabelText(/Node: service:0/);
|
||||||
// This shows warning because there is no position for the click. We cannot add any because we use pageX/Y in the
|
await userEvent.click(node);
|
||||||
// context menu which is experimental (but supported) property and userEvents does not seem to support that
|
|
||||||
act(() => {
|
|
||||||
userEvent.click(node);
|
|
||||||
});
|
|
||||||
await screen.findByText(/Node traces/);
|
await screen.findByText(/Node traces/);
|
||||||
|
|
||||||
const edge = await screen.findByLabelText(/Edge from/);
|
const edge = await screen.findByLabelText(/Edge from/);
|
||||||
act(() => {
|
await userEvent.click(edge);
|
||||||
userEvent.click(edge);
|
|
||||||
});
|
|
||||||
await screen.findByText(/Edge traces/);
|
await screen.findByText(/Edge traces/);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -183,9 +176,7 @@ describe('NodeGraph', () => {
|
|||||||
expect(node).toBeInTheDocument();
|
expect(node).toBeInTheDocument();
|
||||||
|
|
||||||
const marker = await screen.findByLabelText(/Hidden nodes marker: 3/);
|
const marker = await screen.findByLabelText(/Hidden nodes marker: 3/);
|
||||||
act(() => {
|
await userEvent.click(marker);
|
||||||
userEvent.click(marker);
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(screen.queryByLabelText(/Node: service:0/)).not.toBeInTheDocument();
|
expect(screen.queryByLabelText(/Node: service:0/)).not.toBeInTheDocument();
|
||||||
expect(screen.getByLabelText(/Node: service:4/)).toBeInTheDocument();
|
expect(screen.getByLabelText(/Node: service:4/)).toBeInTheDocument();
|
||||||
@@ -210,7 +201,7 @@ describe('NodeGraph', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const button = await screen.findByTitle(/Grid layout/);
|
const button = await screen.findByTitle(/Grid layout/);
|
||||||
userEvent.click(button);
|
await userEvent.click(button);
|
||||||
|
|
||||||
await expectNodePositionCloseTo('service:0', { x: -60, y: -60 });
|
await expectNodePositionCloseTo('service:0', { x: -60, y: -60 });
|
||||||
await expectNodePositionCloseTo('service:1', { x: 60, y: -60 });
|
await expectNodePositionCloseTo('service:1', { x: 60, y: -60 });
|
||||||
|
36
yarn.lock
36
yarn.lock
@@ -3997,7 +3997,7 @@ __metadata:
|
|||||||
"@testing-library/jest-dom": 5.16.2
|
"@testing-library/jest-dom": 5.16.2
|
||||||
"@testing-library/react": 12.1.4
|
"@testing-library/react": 12.1.4
|
||||||
"@testing-library/react-hooks": 7.0.2
|
"@testing-library/react-hooks": 7.0.2
|
||||||
"@testing-library/user-event": 13.5.0
|
"@testing-library/user-event": 14.0.0
|
||||||
"@types/d3-interpolate": ^1.4.0
|
"@types/d3-interpolate": ^1.4.0
|
||||||
"@types/history": 4.7.11
|
"@types/history": 4.7.11
|
||||||
"@types/jest": 27.4.1
|
"@types/jest": 27.4.1
|
||||||
@@ -4180,7 +4180,7 @@ __metadata:
|
|||||||
"@sentry/browser": 6.19.1
|
"@sentry/browser": 6.19.1
|
||||||
"@testing-library/dom": 8.13.0
|
"@testing-library/dom": 8.13.0
|
||||||
"@testing-library/react": 12.1.4
|
"@testing-library/react": 12.1.4
|
||||||
"@testing-library/user-event": ^13.5.0
|
"@testing-library/user-event": 14.0.0
|
||||||
"@types/angular": 1.8.4
|
"@types/angular": 1.8.4
|
||||||
"@types/history": 4.7.11
|
"@types/history": 4.7.11
|
||||||
"@types/jest": 27.4.1
|
"@types/jest": 27.4.1
|
||||||
@@ -4387,7 +4387,7 @@ __metadata:
|
|||||||
"@testing-library/jest-dom": 5.16.2
|
"@testing-library/jest-dom": 5.16.2
|
||||||
"@testing-library/react": 12.1.4
|
"@testing-library/react": 12.1.4
|
||||||
"@testing-library/react-hooks": 7.0.2
|
"@testing-library/react-hooks": 7.0.2
|
||||||
"@testing-library/user-event": 13.5.0
|
"@testing-library/user-event": 14.0.0
|
||||||
"@types/classnames": 2.3.0
|
"@types/classnames": 2.3.0
|
||||||
"@types/common-tags": ^1.8.0
|
"@types/common-tags": ^1.8.0
|
||||||
"@types/d3": 7.1.0
|
"@types/d3": 7.1.0
|
||||||
@@ -9030,7 +9030,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@testing-library/dom@npm:8.13.0":
|
"@testing-library/dom@npm:8.13.0, @testing-library/dom@npm:>=7, @testing-library/dom@npm:^8.0.0":
|
||||||
version: 8.13.0
|
version: 8.13.0
|
||||||
resolution: "@testing-library/dom@npm:8.13.0"
|
resolution: "@testing-library/dom@npm:8.13.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -9046,22 +9046,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@testing-library/dom@npm:>=7, @testing-library/dom@npm:^8.0.0":
|
|
||||||
version: 8.10.1
|
|
||||||
resolution: "@testing-library/dom@npm:8.10.1"
|
|
||||||
dependencies:
|
|
||||||
"@babel/code-frame": ^7.10.4
|
|
||||||
"@babel/runtime": ^7.12.5
|
|
||||||
"@types/aria-query": ^4.2.0
|
|
||||||
aria-query: ^5.0.0
|
|
||||||
chalk: ^4.1.0
|
|
||||||
dom-accessibility-api: ^0.5.9
|
|
||||||
lz-string: ^1.4.4
|
|
||||||
pretty-format: ^27.0.2
|
|
||||||
checksum: c11da16d981d4479fa18b2e90a62d2c19871da414016a4f80136394cf35e833ca4de4b56a64225f6bd5d3a13842176236d3508d217e3858c5e2ef35a3f391d5b
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@testing-library/jest-dom@npm:5.16.2":
|
"@testing-library/jest-dom@npm:5.16.2":
|
||||||
version: 5.16.2
|
version: 5.16.2
|
||||||
resolution: "@testing-library/jest-dom@npm:5.16.2"
|
resolution: "@testing-library/jest-dom@npm:5.16.2"
|
||||||
@@ -9115,14 +9099,12 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@testing-library/user-event@npm:13.5.0, @testing-library/user-event@npm:^13.5.0":
|
"@testing-library/user-event@npm:14.0.0":
|
||||||
version: 13.5.0
|
version: 14.0.0
|
||||||
resolution: "@testing-library/user-event@npm:13.5.0"
|
resolution: "@testing-library/user-event@npm:14.0.0"
|
||||||
dependencies:
|
|
||||||
"@babel/runtime": ^7.12.5
|
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
"@testing-library/dom": ">=7.21.4"
|
"@testing-library/dom": ">=7.21.4"
|
||||||
checksum: 16319de685fbb7008f1ba667928f458b2d08196918002daca56996de80ef35e6d9de26e9e1ece7d00a004692b95a597cf9142fff0dc53f2f51606a776584f549
|
checksum: 171a40e680616e6a34299f9fb783dcadcd36f255256a53fe06cb71f4149715d8e5b84e65ea1c144af179f2e4b1799af92c79a8fc0c4c0ee2e94a713f2c476efd
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -20472,7 +20454,7 @@ __metadata:
|
|||||||
"@testing-library/jest-dom": 5.16.2
|
"@testing-library/jest-dom": 5.16.2
|
||||||
"@testing-library/react": 12.1.4
|
"@testing-library/react": 12.1.4
|
||||||
"@testing-library/react-hooks": 7.0.2
|
"@testing-library/react-hooks": 7.0.2
|
||||||
"@testing-library/user-event": 13.5.0
|
"@testing-library/user-event": 14.0.0
|
||||||
"@types/angular": 1.8.4
|
"@types/angular": 1.8.4
|
||||||
"@types/angular-route": 1.7.2
|
"@types/angular-route": 1.7.2
|
||||||
"@types/classnames": 2.3.0
|
"@types/classnames": 2.3.0
|
||||||
|
Reference in New Issue
Block a user