|
|
|
@ -1,13 +1,5 @@ |
|
|
|
|
import { |
|
|
|
|
render, |
|
|
|
|
waitFor, |
|
|
|
|
screen, |
|
|
|
|
fireEvent, |
|
|
|
|
waitForElementToBeRemoved, |
|
|
|
|
within, |
|
|
|
|
Matcher, |
|
|
|
|
getByRole, |
|
|
|
|
} from '@testing-library/react'; |
|
|
|
|
import { render, waitFor, screen, fireEvent, within, Matcher, getByRole } from '@testing-library/react'; |
|
|
|
|
import userEvent from '@testing-library/user-event'; |
|
|
|
|
import { merge, uniqueId } from 'lodash'; |
|
|
|
|
import React from 'react'; |
|
|
|
|
import { DeepPartial } from 'react-hook-form'; |
|
|
|
@ -280,6 +272,9 @@ describe('CorrelationsPage', () => { |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('shows CTA', async () => { |
|
|
|
|
const CTAButton = await screen.findByRole('button', { name: /add correlation/i }); |
|
|
|
|
expect(CTAButton).toBeInTheDocument(); |
|
|
|
|
|
|
|
|
|
// insert form should not be present
|
|
|
|
|
expect(screen.queryByRole('button', { name: /add$/i })).not.toBeInTheDocument(); |
|
|
|
|
|
|
|
|
@ -289,51 +284,43 @@ describe('CorrelationsPage', () => { |
|
|
|
|
// there's no table in the page
|
|
|
|
|
expect(screen.queryByRole('table')).not.toBeInTheDocument(); |
|
|
|
|
|
|
|
|
|
const CTAButton = screen.getByRole('button', { name: /add correlation/i }); |
|
|
|
|
expect(CTAButton).toBeInTheDocument(); |
|
|
|
|
|
|
|
|
|
fireEvent.click(CTAButton); |
|
|
|
|
|
|
|
|
|
// wait for the form to be rendered and query editor to be mounted
|
|
|
|
|
await waitForElementToBeRemoved(() => screen.queryByText(/loading query editor/i)); |
|
|
|
|
await userEvent.click(CTAButton); |
|
|
|
|
|
|
|
|
|
// form's submit button
|
|
|
|
|
expect(screen.getByRole('button', { name: /add$/i })).toBeInTheDocument(); |
|
|
|
|
expect(await screen.findByRole('button', { name: /add$/i })).toBeInTheDocument(); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('correctly adds first correlation', async () => { |
|
|
|
|
const CTAButton = screen.getByRole('button', { name: /add correlation/i }); |
|
|
|
|
const CTAButton = await screen.findByRole('button', { name: /add correlation/i }); |
|
|
|
|
expect(CTAButton).toBeInTheDocument(); |
|
|
|
|
|
|
|
|
|
// there's no table in the page, as we are adding the first correlation
|
|
|
|
|
expect(screen.queryByRole('table')).not.toBeInTheDocument(); |
|
|
|
|
|
|
|
|
|
fireEvent.click(CTAButton); |
|
|
|
|
await userEvent.click(CTAButton); |
|
|
|
|
|
|
|
|
|
fireEvent.change(screen.getByRole('textbox', { name: /label/i }), { target: { value: 'A Label' } }); |
|
|
|
|
fireEvent.change(screen.getByRole('textbox', { name: /description/i }), { target: { value: 'A Description' } }); |
|
|
|
|
await userEvent.clear(screen.getByRole('textbox', { name: /label/i })); |
|
|
|
|
await userEvent.type(screen.getByRole('textbox', { name: /label/i }), 'A Label'); |
|
|
|
|
await userEvent.clear(screen.getByRole('textbox', { name: /description/i })); |
|
|
|
|
await userEvent.type(screen.getByRole('textbox', { name: /description/i }), 'A Description'); |
|
|
|
|
|
|
|
|
|
// set source datasource picker value
|
|
|
|
|
fireEvent.keyDown(screen.getByLabelText(/^source$/i), { keyCode: 40 }); |
|
|
|
|
fireEvent.click(screen.getByText('loki')); |
|
|
|
|
await userEvent.click(screen.getByText('loki')); |
|
|
|
|
|
|
|
|
|
// set target datasource picker value
|
|
|
|
|
fireEvent.keyDown(screen.getByLabelText(/^target$/i), { keyCode: 40 }); |
|
|
|
|
fireEvent.click(screen.getByText('prometheus')); |
|
|
|
|
|
|
|
|
|
fireEvent.change(screen.getByRole('textbox', { name: /target field/i }), { target: { value: 'Line' } }); |
|
|
|
|
await userEvent.click(screen.getByText('prometheus')); |
|
|
|
|
|
|
|
|
|
await waitForElementToBeRemoved(() => screen.queryByText(/loading query editor/i)); |
|
|
|
|
await userEvent.clear(screen.getByRole('textbox', { name: /target field/i })); |
|
|
|
|
await userEvent.type(screen.getByRole('textbox', { name: /target field/i }), 'Line'); |
|
|
|
|
|
|
|
|
|
fireEvent.click(screen.getByRole('button', { name: /add$/i })); |
|
|
|
|
|
|
|
|
|
// Waits for the form to be removed, meaning the correlation got successfully saved
|
|
|
|
|
await waitForElementToBeRemoved(() => screen.queryByRole('button', { name: /add$/i })); |
|
|
|
|
await userEvent.click(await screen.findByRole('button', { name: /add$/i })); |
|
|
|
|
|
|
|
|
|
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_added'); |
|
|
|
|
|
|
|
|
|
// the table showing correlations should have appeared
|
|
|
|
|
expect(screen.getByRole('table')).toBeInTheDocument(); |
|
|
|
|
expect(await screen.findByRole('table')).toBeInTheDocument(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
@ -413,12 +400,15 @@ describe('CorrelationsPage', () => { |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('shows a table with correlations', async () => { |
|
|
|
|
expect(screen.getByRole('table')).toBeInTheDocument(); |
|
|
|
|
expect(await screen.findByRole('table')).toBeInTheDocument(); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('correctly sorts by source', async () => { |
|
|
|
|
// wait for table to appear
|
|
|
|
|
await screen.findByRole('table'); |
|
|
|
|
|
|
|
|
|
const sourceHeader = getByRole(getHeaderByName('Source'), 'button'); |
|
|
|
|
fireEvent.click(sourceHeader); |
|
|
|
|
await userEvent.click(sourceHeader); |
|
|
|
|
let cells = queryCellsByColumnName('Source'); |
|
|
|
|
cells.forEach((cell, i, allCells) => { |
|
|
|
|
const prevCell = allCells[i - 1]; |
|
|
|
@ -427,7 +417,7 @@ describe('CorrelationsPage', () => { |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
fireEvent.click(sourceHeader); |
|
|
|
|
await userEvent.click(sourceHeader); |
|
|
|
|
cells = queryCellsByColumnName('Source'); |
|
|
|
|
cells.forEach((cell, i, allCells) => { |
|
|
|
|
const prevCell = allCells[i - 1]; |
|
|
|
@ -438,46 +428,47 @@ describe('CorrelationsPage', () => { |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('correctly adds new correlation', async () => { |
|
|
|
|
const addNewButton = screen.getByRole('button', { name: /add new/i }); |
|
|
|
|
const addNewButton = await screen.findByRole('button', { name: /add new/i }); |
|
|
|
|
expect(addNewButton).toBeInTheDocument(); |
|
|
|
|
fireEvent.click(addNewButton); |
|
|
|
|
await userEvent.click(addNewButton); |
|
|
|
|
|
|
|
|
|
fireEvent.change(screen.getByRole('textbox', { name: /label/i }), { target: { value: 'A Label' } }); |
|
|
|
|
fireEvent.change(screen.getByRole('textbox', { name: /description/i }), { target: { value: 'A Description' } }); |
|
|
|
|
await userEvent.clear(screen.getByRole('textbox', { name: /label/i })); |
|
|
|
|
await userEvent.type(screen.getByRole('textbox', { name: /label/i }), 'A Label'); |
|
|
|
|
await userEvent.clear(screen.getByRole('textbox', { name: /description/i })); |
|
|
|
|
await userEvent.type(screen.getByRole('textbox', { name: /description/i }), 'A Description'); |
|
|
|
|
|
|
|
|
|
// set source datasource picker value
|
|
|
|
|
fireEvent.keyDown(screen.getByLabelText(/^source$/i), { keyCode: 40 }); |
|
|
|
|
fireEvent.click(within(screen.getByLabelText('Select options menu')).getByText('prometheus')); |
|
|
|
|
await userEvent.click(within(screen.getByLabelText('Select options menu')).getByText('prometheus')); |
|
|
|
|
|
|
|
|
|
// set target datasource picker value
|
|
|
|
|
fireEvent.keyDown(screen.getByLabelText(/^target$/i), { keyCode: 40 }); |
|
|
|
|
fireEvent.click(screen.getByText('elastic')); |
|
|
|
|
await userEvent.click(screen.getByText('elastic')); |
|
|
|
|
|
|
|
|
|
fireEvent.change(screen.getByRole('textbox', { name: /target field/i }), { target: { value: 'Line' } }); |
|
|
|
|
await userEvent.clear(screen.getByRole('textbox', { name: /target field/i })); |
|
|
|
|
await userEvent.type(screen.getByRole('textbox', { name: /target field/i }), 'Line'); |
|
|
|
|
|
|
|
|
|
await waitForElementToBeRemoved(() => screen.queryByText(/loading query editor/i)); |
|
|
|
|
|
|
|
|
|
fireEvent.click(screen.getByRole('button', { name: /add$/i })); |
|
|
|
|
|
|
|
|
|
// the form should get removed after successful submissions
|
|
|
|
|
await waitForElementToBeRemoved(() => screen.queryByRole('button', { name: /add$/i })); |
|
|
|
|
await userEvent.click(screen.getByRole('button', { name: /add$/i })); |
|
|
|
|
|
|
|
|
|
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_added'); |
|
|
|
|
|
|
|
|
|
// the table showing correlations should have appeared
|
|
|
|
|
expect(await screen.findByRole('table')).toBeInTheDocument(); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('correctly closes the form when clicking on the close icon', async () => { |
|
|
|
|
const addNewButton = screen.getByRole('button', { name: /add new/i }); |
|
|
|
|
const addNewButton = await screen.findByRole('button', { name: /add new/i }); |
|
|
|
|
expect(addNewButton).toBeInTheDocument(); |
|
|
|
|
fireEvent.click(addNewButton); |
|
|
|
|
await userEvent.click(addNewButton); |
|
|
|
|
|
|
|
|
|
fireEvent.click(screen.getByRole('button', { name: /close$/i })); |
|
|
|
|
await userEvent.click(screen.getByRole('button', { name: /close$/i })); |
|
|
|
|
|
|
|
|
|
expect(screen.queryByRole('button', { name: /add$/i })).not.toBeInTheDocument(); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('correctly deletes correlations', async () => { |
|
|
|
|
// A row with the correlation should exist
|
|
|
|
|
expect(screen.getByRole('cell', { name: /some label/i })).toBeInTheDocument(); |
|
|
|
|
expect(await screen.findByRole('cell', { name: /some label/i })).toBeInTheDocument(); |
|
|
|
|
|
|
|
|
|
const tableRows = queryRowsByCellValue('Source', 'loki'); |
|
|
|
|
|
|
|
|
@ -485,36 +476,37 @@ describe('CorrelationsPage', () => { |
|
|
|
|
|
|
|
|
|
expect(deleteButton).toBeInTheDocument(); |
|
|
|
|
|
|
|
|
|
fireEvent.click(deleteButton); |
|
|
|
|
await userEvent.click(deleteButton); |
|
|
|
|
|
|
|
|
|
const confirmButton = within(tableRows[0]).getByRole('button', { name: /delete$/i }); |
|
|
|
|
expect(confirmButton).toBeInTheDocument(); |
|
|
|
|
|
|
|
|
|
fireEvent.click(confirmButton); |
|
|
|
|
await userEvent.click(confirmButton); |
|
|
|
|
|
|
|
|
|
await waitForElementToBeRemoved(() => screen.queryByRole('cell', { name: /some label$/i })); |
|
|
|
|
expect(screen.queryByRole('cell', { name: /some label$/i })).not.toBeInTheDocument(); |
|
|
|
|
|
|
|
|
|
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_deleted'); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('correctly edits correlations', async () => { |
|
|
|
|
// wait for table to appear
|
|
|
|
|
await screen.findByRole('table'); |
|
|
|
|
|
|
|
|
|
const tableRows = queryRowsByCellValue('Source', 'loki'); |
|
|
|
|
|
|
|
|
|
const rowExpanderButton = within(tableRows[0]).getByRole('button', { name: /toggle row expanded/i }); |
|
|
|
|
fireEvent.click(rowExpanderButton); |
|
|
|
|
await userEvent.click(rowExpanderButton); |
|
|
|
|
|
|
|
|
|
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_details_expanded'); |
|
|
|
|
|
|
|
|
|
await waitForElementToBeRemoved(() => screen.queryByText(/loading query editor/i)); |
|
|
|
|
|
|
|
|
|
fireEvent.change(screen.getByRole('textbox', { name: /label/i }), { target: { value: 'edited label' } }); |
|
|
|
|
fireEvent.change(screen.getByRole('textbox', { name: /description/i }), { |
|
|
|
|
target: { value: 'edited description' }, |
|
|
|
|
}); |
|
|
|
|
await userEvent.clear(screen.getByRole('textbox', { name: /label/i })); |
|
|
|
|
await userEvent.type(screen.getByRole('textbox', { name: /label/i }), 'edited label'); |
|
|
|
|
await userEvent.clear(screen.getByRole('textbox', { name: /description/i })); |
|
|
|
|
await userEvent.type(screen.getByRole('textbox', { name: /description/i }), 'edited description'); |
|
|
|
|
|
|
|
|
|
expect(screen.queryByRole('cell', { name: /edited label$/i })).not.toBeInTheDocument(); |
|
|
|
|
|
|
|
|
|
fireEvent.click(screen.getByRole('button', { name: /save$/i })); |
|
|
|
|
await userEvent.click(screen.getByRole('button', { name: /save$/i })); |
|
|
|
|
|
|
|
|
|
await waitFor(() => { |
|
|
|
|
expect(screen.queryByRole('cell', { name: /edited label$/i })).toBeInTheDocument(); |
|
|
|
@ -554,24 +546,21 @@ describe('CorrelationsPage', () => { |
|
|
|
|
|
|
|
|
|
it("doesn't render delete button", async () => { |
|
|
|
|
// A row with the correlation should exist
|
|
|
|
|
expect(screen.getByRole('cell', { name: /some label/i })).toBeInTheDocument(); |
|
|
|
|
expect(await screen.findByRole('cell', { name: /some label/i })).toBeInTheDocument(); |
|
|
|
|
|
|
|
|
|
expect(screen.queryByRole('button', { name: /delete correlation/i })).not.toBeInTheDocument(); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('edit form is read only', async () => { |
|
|
|
|
// A row with the correlation should exist
|
|
|
|
|
const rowExpanderButton = screen.getByRole('button', { name: /toggle row expanded/i }); |
|
|
|
|
const rowExpanderButton = await screen.findByRole('button', { name: /toggle row expanded/i }); |
|
|
|
|
|
|
|
|
|
fireEvent.click(rowExpanderButton); |
|
|
|
|
await userEvent.click(rowExpanderButton); |
|
|
|
|
|
|
|
|
|
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_details_expanded'); |
|
|
|
|
|
|
|
|
|
// wait for the form to be rendered and query editor to be mounted
|
|
|
|
|
await waitForElementToBeRemoved(() => screen.queryByText(/loading query editor/i)); |
|
|
|
|
|
|
|
|
|
// form elements should be readonly
|
|
|
|
|
const labelInput = screen.getByRole('textbox', { name: /label/i }); |
|
|
|
|
const labelInput = await screen.findByRole('textbox', { name: /label/i }); |
|
|
|
|
expect(labelInput).toBeInTheDocument(); |
|
|
|
|
expect(labelInput).toHaveAttribute('readonly'); |
|
|
|
|
|
|
|
|
|