mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-07-24 21:14:27 +08:00
chore: Added jest cases for logs explorer page (#4553)
* chore: base file for logs explorer jest test cases * chore: added base setup for logs explorer jest fixing the uplot/d3-interpolate/antd-config errors * chore: added test for rendering of logs explorer page without API calls * chore: added test for rendering of logs with API call * chore: used virutoso mock to render items on the screen * chore: used virutoso mock to render items on the screen * chore: update dummy data
This commit is contained in:
parent
bbf9787fb3
commit
b10f17de78
@ -173,7 +173,9 @@ function LogsExplorerList({
|
||||
|
||||
{!isLoading && !isError && logs.length > 0 && (
|
||||
<>
|
||||
<InfinityWrapperStyled>{renderContent}</InfinityWrapperStyled>
|
||||
<InfinityWrapperStyled data-testid="logs-list-virtuoso">
|
||||
{renderContent}
|
||||
</InfinityWrapperStyled>
|
||||
|
||||
<LogDetail
|
||||
selectedTab={VIEW_TYPES.OVERVIEW}
|
||||
|
@ -539,6 +539,7 @@ function LogsExplorerViews({
|
||||
(isMultipleQueries || isGroupByExist) && selectedView !== 'search'
|
||||
}
|
||||
onClick={(): void => handleModeChange(PANEL_TYPES.LIST)}
|
||||
data-testid="logs-list-view"
|
||||
>
|
||||
List view
|
||||
</Button>
|
||||
@ -551,6 +552,7 @@ function LogsExplorerViews({
|
||||
: 'tab'
|
||||
}
|
||||
onClick={(): void => handleModeChange(PANEL_TYPES.TIME_SERIES)}
|
||||
data-testid="time-series-view"
|
||||
>
|
||||
Time series
|
||||
</Button>
|
||||
@ -561,6 +563,7 @@ function LogsExplorerViews({
|
||||
selectedPanelType === PANEL_TYPES.TABLE ? 'selected_view tab' : 'tab'
|
||||
}
|
||||
onClick={(): void => handleModeChange(PANEL_TYPES.TABLE)}
|
||||
data-testid="table-view"
|
||||
>
|
||||
Table
|
||||
</Button>
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { SearchOutlined } from '@ant-design/icons';
|
||||
import { Input, Spin } from 'antd';
|
||||
import Typography from 'antd/es/typography/Typography';
|
||||
import { Input, Spin, Typography } from 'antd';
|
||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
@ -39,7 +39,7 @@ export default function LeftToolbarActions({
|
||||
)}
|
||||
onClick={(): void => onChangeSelectedView(SELECTED_VIEWS.SEARCH)}
|
||||
>
|
||||
<MousePointerSquare size={14} />
|
||||
<MousePointerSquare size={14} data-testid="search-view" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title="Query Builder">
|
||||
@ -52,7 +52,7 @@ export default function LeftToolbarActions({
|
||||
)}
|
||||
onClick={(): void => onChangeSelectedView(SELECTED_VIEWS.QUERY_BUILDER)}
|
||||
>
|
||||
<Atom size={14} />
|
||||
<Atom size={14} data-testid="query-builder-view" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
@ -66,7 +66,7 @@ export default function LeftToolbarActions({
|
||||
)}
|
||||
onClick={(): void => onChangeSelectedView(SELECTED_VIEWS.CLICKHOUSE)}
|
||||
>
|
||||
<Terminal size={14} />
|
||||
<Terminal size={14} data-testid="clickhouse-view" />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Tag } from 'antd';
|
||||
import { Tag, Typography } from 'antd';
|
||||
import { ColumnsType } from 'antd/es/table';
|
||||
import Typography from 'antd/es/typography/Typography';
|
||||
import ROUTES from 'constants/routes';
|
||||
import { getMs } from 'container/Trace/Filters/Panel/PanelBody/Duration/util';
|
||||
import { formUrlParams } from 'container/TraceDetail/utils';
|
||||
|
45
frontend/src/mocks-server/__mockdata__/logs_query_range.ts
Normal file
45
frontend/src/mocks-server/__mockdata__/logs_query_range.ts
Normal file
@ -0,0 +1,45 @@
|
||||
export const logsQueryRangeSuccessResponse = {
|
||||
status: 'success',
|
||||
data: {
|
||||
resultType: '',
|
||||
result: [
|
||||
{
|
||||
queryName: 'A',
|
||||
series: null,
|
||||
list: [
|
||||
{
|
||||
timestamp: '2024-02-15T21:20:22Z',
|
||||
data: {
|
||||
attributes_bool: {},
|
||||
attributes_float64: {},
|
||||
attributes_int64: {},
|
||||
attributes_string: {
|
||||
container_id: 'container_id',
|
||||
container_name: 'container_name',
|
||||
driver: 'driver',
|
||||
eta: '2m0s',
|
||||
location: 'frontend',
|
||||
log_level: 'INFO',
|
||||
message: 'Dispatch successful',
|
||||
service: 'frontend',
|
||||
span_id: 'span_id',
|
||||
trace_id: 'span_id',
|
||||
},
|
||||
body:
|
||||
'2024-02-15T21:20:22.035Z\tINFO\tfrontend\tDispatch successful\t{"service": "frontend", "trace_id": "span_id", "span_id": "span_id", "driver": "driver", "eta": "2m0s"}',
|
||||
id: 'id',
|
||||
resources_string: {
|
||||
'container.name': 'container_name',
|
||||
},
|
||||
severity_number: 0,
|
||||
severity_text: '',
|
||||
span_id: '',
|
||||
trace_flags: 0,
|
||||
trace_id: '',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
147
frontend/src/pages/LogsExplorer/__tests__/LogsExplorer.test.tsx
Normal file
147
frontend/src/pages/LogsExplorer/__tests__/LogsExplorer.test.tsx
Normal file
@ -0,0 +1,147 @@
|
||||
import { render, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { logsQueryRangeSuccessResponse } from 'mocks-server/__mockdata__/logs_query_range';
|
||||
import { server } from 'mocks-server/server';
|
||||
import { rest } from 'msw';
|
||||
import { QueryBuilderProvider } from 'providers/QueryBuilder';
|
||||
import MockQueryClientProvider from 'providers/test/MockQueryClientProvider';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
import { Provider } from 'react-redux';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
// https://virtuoso.dev/mocking-in-tests/
|
||||
import { VirtuosoMockContext } from 'react-virtuoso';
|
||||
import i18n from 'ReactI18';
|
||||
import store from 'store';
|
||||
|
||||
import LogsExplorer from '..';
|
||||
|
||||
const queryRangeURL = 'http://localhost/api/v3/query_range';
|
||||
// mocking the graph components in this test as this should be handled separately
|
||||
jest.mock(
|
||||
'container/TimeSeriesView/TimeSeriesView',
|
||||
() =>
|
||||
// eslint-disable-next-line func-names, @typescript-eslint/explicit-function-return-type, react/display-name
|
||||
function () {
|
||||
return <div>Time Series Chart</div>;
|
||||
},
|
||||
);
|
||||
jest.mock(
|
||||
'container/LogsExplorerChart',
|
||||
() =>
|
||||
// eslint-disable-next-line func-names, @typescript-eslint/explicit-function-return-type, react/display-name
|
||||
function () {
|
||||
return <div>Histogram Chart</div>;
|
||||
},
|
||||
);
|
||||
|
||||
jest.mock('constants/panelTypes', () => ({
|
||||
AVAILABLE_EXPORT_PANEL_TYPES: ['graph', 'table'],
|
||||
}));
|
||||
|
||||
jest.mock('d3-interpolate', () => ({
|
||||
interpolate: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('Logs Explorer Tests', () => {
|
||||
test('Logs Explorer default view test without data', async () => {
|
||||
const {
|
||||
getByText,
|
||||
getByRole,
|
||||
queryByText,
|
||||
getByTestId,
|
||||
queryByTestId,
|
||||
} = render(
|
||||
<MemoryRouter initialEntries={['/logs/logs-explorer']}>
|
||||
<Provider store={store}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<MockQueryClientProvider>
|
||||
<QueryBuilderProvider>
|
||||
<LogsExplorer />
|
||||
</QueryBuilderProvider>
|
||||
</MockQueryClientProvider>
|
||||
</I18nextProvider>
|
||||
</Provider>
|
||||
</MemoryRouter>,
|
||||
);
|
||||
|
||||
// check the presence of histogram chart
|
||||
expect(getByText('Histogram Chart')).toBeInTheDocument();
|
||||
|
||||
// toggle the chart and check it gets removed from the DOM
|
||||
const histogramToggle = getByRole('switch');
|
||||
await userEvent.click(histogramToggle);
|
||||
expect(queryByText('Histogram Chart')).not.toBeInTheDocument();
|
||||
|
||||
// check the presence of search bar and query builder and absence of clickhouse
|
||||
const searchView = getByTestId('search-view');
|
||||
expect(searchView).toBeInTheDocument();
|
||||
const queryBuilderView = getByTestId('query-builder-view');
|
||||
expect(queryBuilderView).toBeInTheDocument();
|
||||
const clickhouseView = queryByTestId('clickhouse-view');
|
||||
expect(clickhouseView).not.toBeInTheDocument();
|
||||
|
||||
// check the presence of List View / Time Series View / Table View
|
||||
const listView = getByTestId('logs-list-view');
|
||||
const timeSeriesView = getByTestId('time-series-view');
|
||||
const tableView = getByTestId('table-view');
|
||||
expect(listView).toBeInTheDocument();
|
||||
expect(timeSeriesView).toBeInTheDocument();
|
||||
expect(tableView).toBeInTheDocument();
|
||||
|
||||
// check the presence of old logs explorer CTA
|
||||
const oldLogsCTA = getByText('Switch to Old Logs Explorer');
|
||||
expect(oldLogsCTA).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('Logs Explorer Page should render with data', async () => {
|
||||
// mocking the query range API to return the logs
|
||||
server.use(
|
||||
rest.post(queryRangeURL, (req, res, ctx) =>
|
||||
res(ctx.status(200), ctx.json(logsQueryRangeSuccessResponse)),
|
||||
),
|
||||
);
|
||||
const { queryByText, queryByTestId } = render(
|
||||
<MemoryRouter initialEntries={['/logs/logs-explorer']}>
|
||||
<Provider store={store}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<MockQueryClientProvider>
|
||||
<QueryBuilderProvider>
|
||||
<VirtuosoMockContext.Provider
|
||||
value={{ viewportHeight: 300, itemHeight: 100 }}
|
||||
>
|
||||
<LogsExplorer />
|
||||
</VirtuosoMockContext.Provider>
|
||||
</QueryBuilderProvider>
|
||||
</MockQueryClientProvider>
|
||||
</I18nextProvider>
|
||||
</Provider>
|
||||
</MemoryRouter>,
|
||||
);
|
||||
|
||||
// check for loading state to be not present
|
||||
await waitFor(() =>
|
||||
expect(
|
||||
queryByText(
|
||||
`Just a bit of patience, just a little bit’s enough ⎯ we’re getting your logs!`,
|
||||
),
|
||||
).not.toBeInTheDocument(),
|
||||
);
|
||||
|
||||
// check for no data state to not be present
|
||||
await waitFor(() =>
|
||||
expect(queryByText('No logs yet.')).not.toBeInTheDocument(),
|
||||
);
|
||||
|
||||
// check for the data container loaded
|
||||
await waitFor(() =>
|
||||
expect(queryByTestId('logs-list-virtuoso')).toBeInTheDocument(),
|
||||
);
|
||||
|
||||
// check for data being present in the UI
|
||||
expect(
|
||||
queryByText(
|
||||
'2024-02-15T21:20:22.035Z INFO frontend Dispatch successful {"service": "frontend", "trace_id": "span_id", "span_id": "span_id", "driver": "driver", "eta": "2m0s"}',
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user