chore: added trace explorer test (#5531)

* feat: added trace filter test cases

* feat: added trace filter test cases - initial render

* feat: added test cases - query sync, filter section behaviour etc

* feat: deleted mock-data files

* feat: added test cases of undefined filters and items

* feat: deleted tsconfig

* feat: added clear and rest btn test cases for traces filters

* feat: added collapse and uncollapse test for traces filters

* chore: added trace explorer tests
This commit is contained in:
SagarRajput-7 2024-08-21 15:04:42 +05:30 committed by GitHub
parent ab4a8dfbea
commit a20794040a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 889 additions and 82 deletions

View File

@ -501,6 +501,7 @@ function ExplorerOptions({
shape="circle"
onClick={hideToolbar}
icon={<PanelBottomClose size={16} />}
data-testid="hide-toolbar"
/>
</Tooltip>
</div>
@ -530,6 +531,7 @@ function ExplorerOptions({
icon={<Check size={16} />}
onClick={onSaveHandler}
disabled={isSaveViewLoading}
data-testid="save-view-btn"
>
Save this view
</Button>,

View File

@ -65,6 +65,7 @@ function ExplorerOptionsHideArea({
// style={{ alignSelf: 'center', marginRight: 'calc(10% - 20px)' }}
className="explorer-show-btn"
onClick={handleShowExplorerOption}
data-testid="show-explorer-option"
>
<div className="menu-bar" />
</Button>

View File

@ -77,5 +77,67 @@ export const explorerView = {
},
extraData: '{"color":"#00ffd0"}',
},
{
uuid: '58b010b6-8be9-40d1-8d25-f73b5f7314ad',
name: 'success traces list view',
category: '',
createdAt: '2023-08-30T13:00:40.958011925Z',
createdBy: 'test-email',
updatedAt: '2024-04-29T13:09:06.175537361Z',
updatedBy: 'test-email',
sourcePage: 'traces',
tags: [''],
compositeQuery: {
builderQueries: {
A: {
queryName: 'A',
stepInterval: 60,
dataSource: 'traces',
aggregateOperator: 'noop',
aggregateAttribute: {
key: '',
dataType: '',
type: '',
isColumn: false,
isJSON: false,
},
filters: {
op: 'AND',
items: [
{
key: {
key: 'responseStatusCode',
dataType: 'string',
type: 'tag',
isColumn: true,
isJSON: false,
},
value: '200',
op: '=',
},
],
},
expression: 'A',
disabled: false,
limit: 0,
offset: 0,
pageSize: 0,
orderBy: [
{
columnName: 'timestamp',
order: 'desc',
},
],
reduceTo: 'sum',
timeAggregation: 'rate',
spaceAggregation: 'sum',
ShiftBy: 0,
},
},
panelType: 'list',
queryType: 'builder',
},
extraData: '{"color":"#bdff9d"}',
},
],
};

View File

@ -1,3 +1,4 @@
/* eslint-disable sonarjs/no-duplicate-string */
import { PANEL_TYPES } from 'constants/queryBuilder';
import { QueryRangePayload } from 'types/api/metrics/getQueryRange';
import { EQueryType } from 'types/common/dashboard';
@ -77,3 +78,245 @@ export const queryRangeSuccessResponse: QueryRangePayload = {
start: 0,
step: 0,
};
export const queryRangeForTimeSeries = {
status: 'success',
data: {
resultType: '',
result: [
{
queryName: 'A',
series: [
{
labels: {},
labelsArray: null,
values: [
{
timestamp: 1721378340000,
value: '3074',
},
{
timestamp: 1721378100000,
value: '2983',
},
{
timestamp: 1721378040000,
value: '2978',
},
{
timestamp: 1721378160000,
value: '2940',
},
{
timestamp: 1721377980000,
value: '2904',
},
{
timestamp: 1721378280000,
value: '2874',
},
{
timestamp: 1721378220000,
value: '2667',
},
],
},
],
},
],
},
};
export const queryRangeForListView = {
status: 'success',
data: {
resultType: '',
result: [
{
queryName: 'A',
list: [
{
timestamp: '2024-07-19T08:39:59.949129915Z',
data: {
dbName: '',
durationNano: 790949390,
httpMethod: '',
name: 'authenticate_check_db',
responseStatusCode: '',
serviceName: 'demo-app',
spanID: '5704353737b6778e',
statusCode: 0,
traceID: 'a364a8e15af3e9a8c866e0528db8b637',
},
},
{
timestamp: '2024-07-19T08:39:59.506524482Z',
data: {
dbName: '',
durationNano: 1375203118,
httpMethod: '',
name: 'check cart in cache',
responseStatusCode: '',
serviceName: 'demo-app',
spanID: '2134bb1165c928aa',
statusCode: 0,
traceID: '7b565bc351bac2a12c004d92d3a809b1',
},
},
{
timestamp: '2024-07-19T08:39:58.735245Z',
data: {
dbName: '',
durationNano: 55306000,
httpMethod: 'GET',
name: 'HTTP GET',
responseStatusCode: '200',
serviceName: 'frontend',
spanID: '772c4d29dd9076ac',
statusCode: 0,
traceID: '0000000000000000344ded1387b08a7e',
},
},
],
},
],
},
};
export const queryRangeForTableView = {
status: 'success',
data: {
resultType: '',
result: [
{
queryName: 'A',
series: [
{
labels: {},
labelsArray: null,
values: [
{
timestamp: 1721583834000,
value: '87798',
},
],
},
],
},
],
},
};
export const queryRangeForTraceView = {
status: 'success',
data: {
resultType: '',
result: [
{
queryName: 'A',
list: [
{
timestamp: '0001-01-01T00:00:00Z',
data: {
span_count: 8,
'subQuery.durationNano': 7245231266,
'subQuery.name': 'home',
'subQuery.serviceName': 'demo-app',
traceID: '5765b60ba7cc4ddafe8bdaa9c1b4b246',
},
},
{
timestamp: '0001-01-01T00:00:00Z',
data: {
span_count: 8,
'subQuery.durationNano': 7218609120,
'subQuery.name': 'home',
'subQuery.serviceName': 'demo-app',
traceID: '1593c896d96cc6b2478bb95dcc01e3f5',
},
},
{
timestamp: '0001-01-01T00:00:00Z',
data: {
span_count: 8,
'subQuery.durationNano': 7217156051,
'subQuery.name': 'home',
'subQuery.serviceName': 'demo-app',
traceID: 'dcd145ed13937795c5e2ee8618ec7e32',
},
},
{
timestamp: '0001-01-01T00:00:00Z',
data: {
span_count: 8,
'subQuery.durationNano': 7054152134,
'subQuery.name': 'home',
'subQuery.serviceName': 'demo-app',
traceID: 'd9ceed0a6b23ed4b3bff664e2b303382',
},
},
{
timestamp: '0001-01-01T00:00:00Z',
data: {
span_count: 8,
'subQuery.durationNano': 7052324178,
'subQuery.name': 'home',
'subQuery.serviceName': 'demo-app',
traceID: 'f76f1acc10a9149121c2bf715d1f92c5',
},
},
{
timestamp: '0001-01-01T00:00:00Z',
data: {
span_count: 8,
'subQuery.durationNano': 6998186102,
'subQuery.name': 'home',
'subQuery.serviceName': 'demo-app',
traceID: '1e3acf6649147117836cfdde66e2bde5',
},
},
{
timestamp: '0001-01-01T00:00:00Z',
data: {
span_count: 8,
'subQuery.durationNano': 6898849195,
'subQuery.name': 'home',
'subQuery.serviceName': 'demo-app',
traceID: '035b210595493adcef4c7f297a427bb0',
},
},
{
timestamp: '0001-01-01T00:00:00Z',
data: {
span_count: 8,
'subQuery.durationNano': 6829435795,
'subQuery.name': 'home',
'subQuery.serviceName': 'demo-app',
traceID: '4ae4d4d082fc6d7a20d90ae0b1d0fff1',
},
},
{
timestamp: '0001-01-01T00:00:00Z',
data: {
span_count: 8,
'subQuery.durationNano': 6790765891,
'subQuery.name': 'home',
'subQuery.serviceName': 'demo-app',
traceID: '7975c032b430ac63479e5d578c1f0edd',
},
},
{
timestamp: '0001-01-01T00:00:00Z',
data: {
span_count: 8,
'subQuery.durationNano': 6786616927,
'subQuery.name': 'home',
'subQuery.serviceName': 'demo-app',
traceID: 'ce9d3e5d66dbdd41d46d519b615cce52',
},
},
],
},
],
},
};

View File

@ -210,6 +210,16 @@ export const handlers = [
res(ctx.status(200), ctx.json(explorerView)),
),
rest.post('http://localhost/api/v1/explorer/views', (req, res, ctx) =>
res(
ctx.status(200),
ctx.json({
status: 'success',
data: '7731ece1-3fa3-4ed4-8b1c-58b4c28723b2',
}),
),
),
rest.post('http://localhost/api/v1/event', (req, res, ctx) =>
res(
ctx.status(200),

View File

@ -1,27 +1,56 @@
/* eslint-disable sonarjs/no-duplicate-string */
/* eslint-disable no-restricted-syntax */
/* eslint-disable no-await-in-loop */
import userEvent from '@testing-library/user-event';
import {
initialQueriesMap,
initialQueryBuilderFormValues,
PANEL_TYPES,
} from 'constants/queryBuilder';
import ROUTES from 'constants/routes';
import * as compositeQueryHook from 'hooks/queryBuilder/useGetCompositeQueryParam';
import {
queryRangeForListView,
queryRangeForTableView,
queryRangeForTimeSeries,
queryRangeForTraceView,
} from 'mocks-server/__mockdata__/query_range';
import { server } from 'mocks-server/server';
import { rest } from 'msw';
import { QueryBuilderContext } from 'providers/QueryBuilder';
import { fireEvent, render, screen, waitFor, within } from 'tests/test-utils';
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
import { Query } from 'types/api/queryBuilder/queryBuilderData';
import {
act,
fireEvent,
render,
screen,
waitFor,
within,
} from 'tests/test-utils';
import TracesExplorer from '..';
import { Filter } from '../Filter/Filter';
import { AllTraceFilterKeyValue } from '../Filter/filterUtils';
import {
checkForSectionContent,
checkIfSectionIsNotOpen,
checkIfSectionIsOpen,
compositeQuery,
defaultClosedSections,
defaultOpenSections,
optionMenuReturn,
qbProviderValue,
redirectWithQueryBuilderData,
} from './testUtils';
const historyPush = jest.fn();
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useLocation: (): { pathname: string } => ({
pathname: `${process.env.FRONTEND_API_ENDPOINT}${ROUTES.TRACES_EXPLORER}/`,
}),
useHistory: (): any => ({
...jest.requireActual('react-router-dom').useHistory(),
push: historyPush,
}),
}));
jest.mock('uplot', () => {
@ -40,6 +69,25 @@ jest.mock('uplot', () => {
};
});
jest.mock(
'components/Uplot/Uplot',
() =>
function MockUplot(): JSX.Element {
return <div>MockUplot</div>;
},
);
const successNotification = jest.fn();
jest.mock('hooks/useNotifications', () => ({
__esModule: true,
useNotifications: jest.fn(() => ({
notifications: {
success: successNotification,
error: jest.fn(),
},
})),
}));
jest.mock(
'container/TopNav/DateTimeSelectionV2/index.tsx',
() =>
@ -48,84 +96,12 @@ jest.mock(
},
);
function checkIfSectionIsOpen(
getByTestId: (testId: string) => HTMLElement,
panelName: string,
): void {
const section = getByTestId(`collapse-${panelName}`);
expect(section.querySelector('.ant-collapse-item-active')).not.toBeNull();
}
jest.mock('container/OptionsMenu/useOptionsMenu', () => ({
__esModule: true,
default: (): any => optionMenuReturn,
}));
function checkIfSectionIsNotOpen(
getByTestId: (testId: string) => HTMLElement,
panelName: string,
): void {
const section = getByTestId(`collapse-${panelName}`);
expect(section.querySelector('.ant-collapse-item-active')).toBeNull();
}
const defaultOpenSections = ['hasError', 'durationNano', 'serviceName'];
const defaultClosedSections = Object.keys(AllTraceFilterKeyValue).filter(
(section) =>
![...defaultOpenSections, 'durationNanoMin', 'durationNanoMax'].includes(
section,
),
);
async function checkForSectionContent(values: string[]): Promise<void> {
for (const val of values) {
const sectionContent = await screen.findByText(val);
await waitFor(() => expect(sectionContent).toBeInTheDocument());
}
}
const redirectWithQueryBuilderData = jest.fn();
const compositeQuery: Query = {
...initialQueriesMap.traces,
builder: {
...initialQueriesMap.traces.builder,
queryData: [
{
...initialQueryBuilderFormValues,
filters: {
items: [
{
id: '95564eb1',
key: {
key: 'name',
dataType: DataTypes.String,
type: 'tag',
isColumn: true,
isJSON: false,
id: 'name--string--tag--true',
},
op: 'in',
value: ['HTTP GET /customer'],
},
{
id: '3337951c',
key: {
key: 'serviceName',
dataType: DataTypes.String,
type: 'tag',
isColumn: true,
isJSON: false,
id: 'serviceName--string--tag--true',
},
op: 'in',
value: ['demo-app'],
},
],
op: 'AND',
},
},
],
},
};
describe('TracesExplorer - ', () => {
describe('TracesExplorer - Filters', () => {
// Initial filter panel rendering
// Test the initial state like which filters section are opened, default state of duration slider, etc.
it('should render the Trace filter', async () => {
@ -457,3 +433,255 @@ describe('TracesExplorer - ', () => {
).toBeInTheDocument();
});
});
const handleExplorerTabChangeTest = jest.fn();
jest.mock('hooks/useHandleExplorerTabChange', () => ({
useHandleExplorerTabChange: jest.fn(() => ({
handleExplorerTabChange: handleExplorerTabChangeTest,
})),
}));
describe('TracesExplorer - ', () => {
it('should render the traces explorer page', async () => {
server.use(
rest.post('http://localhost/api/v3/query_range', (req, res, ctx) =>
res(ctx.status(200), ctx.json(queryRangeForTimeSeries)),
),
);
const { findByText, getByText } = render(<TracesExplorer />);
// assert mocked date time selection
expect(await findByText('MockDateTimeSelection')).toBeInTheDocument();
// assert stage&Btn
expect(getByText('Stage & Run Query')).toBeInTheDocument();
// assert QB - will not write tests for QB as that would be covererd in QB tests separately
expect(
getByText(
'Search Filter : select options from suggested values, for IN/NOT IN operators - press "Enter" after selecting options',
),
).toBeInTheDocument();
expect(getByText('AGGREGATION INTERVAL')).toBeInTheDocument();
expect(getByText('Metrics name')).toBeInTheDocument();
expect(getByText('WHERE')).toBeInTheDocument();
expect(getByText('Legend Format')).toBeInTheDocument();
// assert timeseries chart mock
expect(await screen.findByText('MockUplot')).toBeInTheDocument();
});
it('check tab navigation', async () => {
const { getByText } = render(<TracesExplorer />);
// switch to list view
const listViewBtn = getByText('List View');
expect(listViewBtn).toBeInTheDocument();
fireEvent.click(listViewBtn);
expect(handleExplorerTabChangeTest).toBeCalledWith(PANEL_TYPES.LIST);
// switch to traces view
const tracesBtn = getByText('Traces');
expect(tracesBtn).toBeInTheDocument();
fireEvent.click(tracesBtn);
expect(handleExplorerTabChangeTest).toBeCalledWith(PANEL_TYPES.TRACE);
// switch to Table view
const TableBtn = getByText('Table View');
expect(TableBtn).toBeInTheDocument();
fireEvent.click(TableBtn);
expect(handleExplorerTabChangeTest).toBeCalledWith(PANEL_TYPES.TABLE);
});
it('trace explorer - list view', async () => {
server.use(
rest.post('http://localhost/api/v3/query_range', (req, res, ctx) =>
res(ctx.status(200), ctx.json(queryRangeForListView)),
),
);
const { getByText } = render(
<QueryBuilderContext.Provider value={{ ...qbProviderValue }}>
<TracesExplorer />
</QueryBuilderContext.Provider>,
);
expect(await screen.findByText('Timestamp')).toBeInTheDocument();
expect(getByText('options_menu.options')).toBeInTheDocument();
// test if pagination is there
expect(getByText('Previous')).toBeInTheDocument();
expect(getByText('Next')).toBeInTheDocument();
// column interaction is covered in E2E tests as its a complex interaction
});
it('trace explorer - table view', async () => {
server.use(
rest.post('http://localhost/api/v3/query_range', (req, res, ctx) =>
res(ctx.status(200), ctx.json(queryRangeForTableView)),
),
);
render(
<QueryBuilderContext.Provider
value={{ ...qbProviderValue, panelType: PANEL_TYPES.TABLE }}
>
<TracesExplorer />
</QueryBuilderContext.Provider>,
);
expect(await screen.findByText('count')).toBeInTheDocument();
expect(screen.getByText('87798.00')).toBeInTheDocument();
});
it('trace explorer - trace view', async () => {
server.use(
rest.post('http://localhost/api/v3/query_range', (req, res, ctx) =>
res(ctx.status(200), ctx.json(queryRangeForTraceView)),
),
);
const { getByText, getAllByText } = render(
<QueryBuilderContext.Provider
value={{ ...qbProviderValue, panelType: PANEL_TYPES.TRACE }}
>
<TracesExplorer />
</QueryBuilderContext.Provider>,
);
expect(await screen.findByText('Root Service Name')).toBeInTheDocument();
// assert table headers
expect(getByText('Root Operation Name')).toBeInTheDocument();
expect(getByText('Root Duration (in ms)')).toBeInTheDocument();
expect(getByText('TraceID')).toBeInTheDocument();
expect(getByText('No of Spans')).toBeInTheDocument();
// assert row values
['demo-app', 'home', '8'].forEach((val) =>
expect(getAllByText(val)[0]).toBeInTheDocument(),
);
expect(getByText('7245.23ms')).toBeInTheDocument();
// assert traceId and redirection to trace details
const traceId = getByText('5765b60ba7cc4ddafe8bdaa9c1b4b246');
fireEvent.click(traceId);
// assert redirection - should go to /trace/:traceId
expect(window.location.href).toEqual(
'http://localhost/trace/5765b60ba7cc4ddafe8bdaa9c1b4b246',
);
});
it('test for explorer options', async () => {
const { getByText, getByTestId } = render(<TracesExplorer />);
// assert explorer options - action btns
[
'Save this view',
'Create an Alert',
'Add to Dashboard',
'Select a view',
].forEach((val) => expect(getByText(val)).toBeInTheDocument());
const hideExplorerOption = getByTestId('hide-toolbar');
expect(hideExplorerOption).toBeInTheDocument();
fireEvent.click(hideExplorerOption);
// explorer options should hide and show btn should be present
expect(await screen.findByTestId('show-explorer-option')).toBeInTheDocument();
expect(screen.queryByTestId('hide-toolbar')).toBeNull();
// show explorer options
const showExplorerOption = screen.getByTestId('show-explorer-option');
expect(showExplorerOption).toBeInTheDocument();
fireEvent.click(showExplorerOption);
// explorer options should show and hide btn should be present
expect(await screen.findByTestId('hide-toolbar')).toBeInTheDocument();
});
it('select a view options - assert and save this view', async () => {
const { container } = render(<TracesExplorer />);
await act(async () => {
fireEvent.mouseDown(
container.querySelector(
'.view-options .ant-select-selection-search-input',
) as HTMLElement,
);
});
const viewListOptions = await screen.findByRole('listbox');
expect(viewListOptions).toBeInTheDocument();
expect(
within(viewListOptions).getByText('success traces list view'),
).toBeInTheDocument();
expect(within(viewListOptions).getByText('Table View')).toBeInTheDocument();
// save this view
fireEvent.click(screen.getByText('Save this view'));
const saveViewModalInput = await screen.findByPlaceholderText(
'e.g. External http method view',
);
expect(saveViewModalInput).toBeInTheDocument();
const saveViewModal = document.querySelector(
'.ant-modal-content',
) as HTMLElement;
expect(saveViewModal).toBeInTheDocument();
await act(async () =>
fireEvent.change(saveViewModalInput, { target: { value: 'test view' } }),
);
expect(saveViewModalInput).toHaveValue('test view');
await act(async () => {
fireEvent.click(within(saveViewModal).getByTestId('save-view-btn'));
});
expect(successNotification).toHaveBeenCalledWith({
message: 'View Saved Successfully',
});
});
it('create a dashboard btn assert', async () => {
const { getByText } = render(<TracesExplorer />);
const createDashboardBtn = getByText('Add to Dashboard');
expect(createDashboardBtn).toBeInTheDocument();
fireEvent.click(createDashboardBtn);
expect(await screen.findByText('Export Panel')).toBeInTheDocument();
const createDashboardModal = document.querySelector(
'.ant-modal-content',
) as HTMLElement;
expect(createDashboardModal).toBeInTheDocument();
// assert modal content
expect(
within(createDashboardModal).getByText('Select Dashboard'),
).toBeInTheDocument();
expect(
within(createDashboardModal).getByText('New Dashboard'),
).toBeInTheDocument();
});
it('create an alert btn assert', async () => {
const { getByText } = render(<TracesExplorer />);
const createAlertBtn = getByText('Create an Alert');
expect(createAlertBtn).toBeInTheDocument();
fireEvent.click(createAlertBtn);
expect(historyPush).toHaveBeenCalledWith(
expect.stringContaining(`${ROUTES.ALERTS_NEW}`),
);
});
});

View File

@ -0,0 +1,261 @@
/* eslint-disable sonarjs/no-duplicate-string */
/* eslint-disable no-restricted-syntax */
/* eslint-disable no-await-in-loop */
import {
initialQueriesMap,
initialQueryBuilderFormValues,
PANEL_TYPES,
} from 'constants/queryBuilder';
import { noop } from 'lodash-es';
import { screen, waitFor } from 'tests/test-utils';
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
import { Query } from 'types/api/queryBuilder/queryBuilderData';
import { AllTraceFilterKeyValue } from '../Filter/filterUtils';
export const optionMenuReturn = {
options: {
selectColumns: [
{
key: 'serviceName',
dataType: 'string',
type: 'tag',
isColumn: true,
isJSON: false,
id: 'serviceName--string--tag--true',
},
{
key: 'name',
dataType: 'string',
type: 'tag',
isColumn: true,
isJSON: false,
id: 'name--string--tag--true',
},
{
key: 'durationNano',
dataType: 'float64',
type: 'tag',
isColumn: true,
isJSON: false,
id: 'durationNano--float64--tag--true',
},
{
key: 'httpMethod',
dataType: 'string',
type: 'tag',
isColumn: true,
isJSON: false,
id: 'httpMethod--string--tag--true',
},
{
key: 'responseStatusCode',
dataType: 'string',
type: 'tag',
isColumn: true,
isJSON: false,
id: 'responseStatusCode--string--tag--true',
},
{
key: 'statusCode',
dataType: 'float64',
type: 'tag',
isColumn: true,
isJSON: false,
id: 'statusCode--float64--tag--true',
},
{
key: 'dbName',
dataType: 'string',
type: 'tag',
isColumn: true,
isJSON: false,
id: 'dbName--string--tag--true',
},
],
maxLines: 2,
format: 'list',
},
handleOptionsChange: jest.fn(),
config: {
addColumn: {
isFetching: false,
value: [
{
key: 'serviceName',
dataType: 'string',
type: 'tag',
isColumn: true,
isJSON: false,
id: 'serviceName--string--tag--true',
},
{
key: 'name',
dataType: 'string',
type: 'tag',
isColumn: true,
isJSON: false,
id: 'name--string--tag--true',
},
{
key: 'durationNano',
dataType: 'float64',
type: 'tag',
isColumn: true,
isJSON: false,
id: 'durationNano--float64--tag--true',
},
{
key: 'httpMethod',
dataType: 'string',
type: 'tag',
isColumn: true,
isJSON: false,
id: 'httpMethod--string--tag--true',
},
{
key: 'responseStatusCode',
dataType: 'string',
type: 'tag',
isColumn: true,
isJSON: false,
id: 'responseStatusCode--string--tag--true',
},
{
key: 'statusCode',
dataType: 'float64',
type: 'tag',
isColumn: true,
isJSON: false,
id: 'statusCode--float64--tag--true',
},
{
key: 'dbName',
dataType: 'string',
type: 'tag',
isColumn: true,
isJSON: false,
id: 'dbName--string--tag--true',
},
],
options: [],
},
format: {
value: 'list',
},
maxLines: {
value: 2,
},
},
};
export const compositeQuery: Query = {
...initialQueriesMap.traces,
builder: {
...initialQueriesMap.traces.builder,
queryData: [
{
...initialQueryBuilderFormValues,
filters: {
items: [
{
id: '95564eb1',
key: {
key: 'name',
dataType: DataTypes.String,
type: 'tag',
isColumn: true,
isJSON: false,
id: 'name--string--tag--true',
},
op: 'in',
value: ['HTTP GET /customer'],
},
{
id: '3337951c',
key: {
key: 'serviceName',
dataType: DataTypes.String,
type: 'tag',
isColumn: true,
isJSON: false,
id: 'serviceName--string--tag--true',
},
op: 'in',
value: ['demo-app'],
},
],
op: 'AND',
},
},
],
},
};
export const redirectWithQueryBuilderData = jest.fn();
export const qbProviderValue = {
currentQuery: {
...initialQueriesMap.traces,
builder: {
...initialQueriesMap.traces.builder,
queryData: [initialQueryBuilderFormValues],
},
},
redirectWithQueryBuilderData,
panelType: PANEL_TYPES.LIST,
setSupersetQuery: jest.fn(),
supersetQuery: initialQueriesMap.traces,
stagedQuery: initialQueriesMap.traces,
initialDataSource: null,
isEnabledQuery: false,
handleSetQueryData: noop,
handleSetFormulaData: noop,
handleSetQueryItemData: noop,
handleSetConfig: noop,
removeQueryBuilderEntityByIndex: noop,
removeQueryTypeItemByIndex: noop,
addNewBuilderQuery: noop,
cloneQuery: noop,
addNewFormula: noop,
addNewQueryItem: noop,
handleRunQuery: noop,
resetQuery: noop,
updateAllQueriesOperators: (): Query => initialQueriesMap.traces,
updateQueriesData: (): Query => initialQueriesMap.traces,
initQueryBuilderData: noop,
handleOnUnitsChange: noop,
isStagedQueryUpdated: (): boolean => false,
} as any;
export function checkIfSectionIsOpen(
getByTestId: (testId: string) => HTMLElement,
panelName: string,
): void {
const section = getByTestId(`collapse-${panelName}`);
expect(section.querySelector('.ant-collapse-item-active')).not.toBeNull();
}
export function checkIfSectionIsNotOpen(
getByTestId: (testId: string) => HTMLElement,
panelName: string,
): void {
const section = getByTestId(`collapse-${panelName}`);
expect(section.querySelector('.ant-collapse-item-active')).toBeNull();
}
export const defaultOpenSections = ['hasError', 'durationNano', 'serviceName'];
export const defaultClosedSections = Object.keys(AllTraceFilterKeyValue).filter(
(section) =>
![...defaultOpenSections, 'durationNanoMin', 'durationNanoMax'].includes(
section,
),
);
export async function checkForSectionContent(values: string[]): Promise<void> {
for (const val of values) {
const sectionContent = await screen.findByText(val);
await waitFor(() => expect(sectionContent).toBeInTheDocument());
}
}