mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-11 22:09:05 +08:00
feat: added dashboard list and create tests (#3989)
* feat: added dashboard list and create tests * feat: added widget tests
This commit is contained in:
parent
2a55f3d680
commit
c4536f9069
@ -118,7 +118,11 @@ function GraphLayout({ onAddPanelHandler }: GraphLayoutProps): JSX.Element {
|
||||
)}
|
||||
|
||||
{addPanelPermission && (
|
||||
<Button onClick={onAddPanelHandler} icon={<PlusOutlined />}>
|
||||
<Button
|
||||
onClick={onAddPanelHandler}
|
||||
icon={<PlusOutlined />}
|
||||
data-testid="add-panel"
|
||||
>
|
||||
{t('dashboard:add_panel')}
|
||||
</Button>
|
||||
)}
|
||||
|
@ -203,7 +203,7 @@ function WidgetHeader({
|
||||
onClick={onClickHandler}
|
||||
>
|
||||
<HeaderContentContainer>
|
||||
<Typography.Text style={{ maxWidth: '80%' }} ellipsis>
|
||||
<Typography.Text style={{ maxWidth: '80%' }} ellipsis data-testid={title}>
|
||||
{title}
|
||||
</Typography.Text>
|
||||
<ArrowContainer hover={parentHover}>
|
||||
|
@ -328,6 +328,7 @@ function ListOfAllDashboard(): JSX.Element {
|
||||
<NewDashboardButton
|
||||
icon={<PlusOutlined />}
|
||||
type="primary"
|
||||
data-testid="create-new-dashboard"
|
||||
loading={newDashboardState.loading}
|
||||
danger={newDashboardState.error}
|
||||
>
|
||||
|
@ -18,7 +18,12 @@ function SettingsDrawer({ drawerTitle }: { drawerTitle: string }): JSX.Element {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button type="dashed" onClick={showDrawer} style={{ width: '100%' }}>
|
||||
<Button
|
||||
type="dashed"
|
||||
onClick={showDrawer}
|
||||
style={{ width: '100%' }}
|
||||
data-testid="show-drawer"
|
||||
>
|
||||
<SettingOutlined /> Configure
|
||||
</Button>
|
||||
<DrawerContainer
|
||||
|
@ -51,7 +51,11 @@ function DashboardDescription(): JSX.Element {
|
||||
<Card>
|
||||
<Row gutter={16}>
|
||||
<Col flex={1} span={12}>
|
||||
<Typography.Title level={4} style={{ padding: 0, margin: 0 }}>
|
||||
<Typography.Title
|
||||
level={4}
|
||||
style={{ padding: 0, margin: 0 }}
|
||||
data-testid="dashboard-landing-name"
|
||||
>
|
||||
{isDashboardLocked && (
|
||||
<Tooltip title="Dashboard Locked" placement="top">
|
||||
<LockFilled />
|
||||
@ -60,7 +64,12 @@ function DashboardDescription(): JSX.Element {
|
||||
{title}
|
||||
</Typography.Title>
|
||||
{description && (
|
||||
<Typography className="dashboard-description">{description}</Typography>
|
||||
<Typography
|
||||
className="dashboard-description"
|
||||
data-testid="dashboard-landing-desc"
|
||||
>
|
||||
{description}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
{tags && (
|
||||
|
@ -63,6 +63,7 @@ function GeneralDashboardSettings(): JSX.Element {
|
||||
<div>
|
||||
<Typography style={{ marginBottom: '0.5rem' }}>Name</Typography>
|
||||
<Input
|
||||
data-testid="dashboard-name"
|
||||
value={updatedTitle}
|
||||
onChange={(e): void => setUpdatedTitle(e.target.value)}
|
||||
/>
|
||||
@ -71,6 +72,7 @@ function GeneralDashboardSettings(): JSX.Element {
|
||||
<div>
|
||||
<Typography style={{ marginBottom: '0.5rem' }}>Description</Typography>
|
||||
<Input.TextArea
|
||||
data-testid="dashboard-desc"
|
||||
rows={5}
|
||||
value={updatedDescription}
|
||||
onChange={(e): void => setUpdatedDescription(e.target.value)}
|
||||
@ -88,6 +90,7 @@ function GeneralDashboardSettings(): JSX.Element {
|
||||
disabled={updateDashboardMutation.isLoading}
|
||||
loading={updateDashboardMutation.isLoading}
|
||||
icon={<SaveOutlined />}
|
||||
data-testid="save-dashboard-config"
|
||||
onClick={onSaveHandler}
|
||||
type="primary"
|
||||
>
|
||||
|
@ -181,6 +181,7 @@ function VariablesSetting(): JSX.Element {
|
||||
<>
|
||||
<Row style={{ flexDirection: 'row-reverse', padding: '0.5rem 0' }}>
|
||||
<Button
|
||||
data-testid="add-new-variable"
|
||||
type="primary"
|
||||
onClick={(): void =>
|
||||
onVariableViewModeEnter('ADD', {} as IDashboardVariable)
|
||||
|
@ -261,7 +261,12 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
||||
)}
|
||||
|
||||
{!isSaveDisabled && (
|
||||
<Button type="primary" disabled={isSaveDisabled} onClick={onSaveDashboard}>
|
||||
<Button
|
||||
type="primary"
|
||||
data-testid="new-widget-save"
|
||||
disabled={isSaveDisabled}
|
||||
onClick={onSaveDashboard}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
)}
|
||||
|
@ -33,9 +33,7 @@ if (container) {
|
||||
<Provider store={store}>
|
||||
<AppRoutes />
|
||||
</Provider>
|
||||
{process.env.NODE_ENV === 'development' && (
|
||||
<ReactQueryDevtools initialIsOpen />
|
||||
)}
|
||||
{process.env.NODE_ENV === 'development' && <ReactQueryDevtools />}
|
||||
</QueryClientProvider>
|
||||
</ThemeProvider>
|
||||
</HelmetProvider>
|
||||
|
143
frontend/tests/dashboards/index.spec.ts
Normal file
143
frontend/tests/dashboards/index.spec.ts
Normal file
@ -0,0 +1,143 @@
|
||||
import { Page, test, expect } from '@playwright/test';
|
||||
import { loginApi } from '../fixtures/common';
|
||||
import ROUTES from 'constants/routes';
|
||||
import dashboardsListEmptyResponse from '../fixtures/api/dashboard/getDashboardListEmpty200.json';
|
||||
import createNewDashboardPostResponse from '../fixtures/api/dashboard/createNewDashboardPost200.json';
|
||||
import queryRangeSuccessResponse from '../fixtures/api/traces/queryRange200.json';
|
||||
import getIndividualDashboardResponse from '../fixtures/api/dashboard/getIndividualDashboard200.json';
|
||||
import putNewDashboardResponse from '../fixtures/api/dashboard/putNewDashboardUpdate200.json';
|
||||
import putDashboardTimeSeriesResponse from '../fixtures/api/dashboard/putDashboardWithTimeSeries200.json';
|
||||
import dashboardGetCallWithTimeSeriesWidgetResponse from '../fixtures/api/dashboard/dashboardGetCallWithTimeSeriesWidget200.json';
|
||||
import {
|
||||
addPanelID,
|
||||
configureDashboardDescriptonID,
|
||||
configureDashboardNameID,
|
||||
configureDashboardSettings,
|
||||
dashboardDescription,
|
||||
dashboardHomePageDesc,
|
||||
dashboardHomePageTitle,
|
||||
dashboardName,
|
||||
dashboardsListAndCreate,
|
||||
getDashboardsListEndpoint,
|
||||
getIndividualDashboard,
|
||||
getIndividualDashboardsEndpoint,
|
||||
getTimeSeriesQueryData,
|
||||
newDashboardBtnID,
|
||||
saveConfigureDashboardID,
|
||||
timeSeriesGraphName,
|
||||
timeSeriesPanelID,
|
||||
} from './utils';
|
||||
|
||||
let page: Page;
|
||||
|
||||
test.describe('Dashboards Landing Page', () => {
|
||||
test.beforeEach(async ({ baseURL, browser }) => {
|
||||
const context = await browser.newContext({
|
||||
storageState: 'tests/auth.json',
|
||||
});
|
||||
const newPage = await context.newPage();
|
||||
|
||||
await loginApi(newPage);
|
||||
|
||||
await newPage.goto(`${baseURL}${ROUTES.APPLICATION}`);
|
||||
|
||||
page = newPage;
|
||||
});
|
||||
|
||||
test('Create a new dashboard and configure the name and description', async ({}) => {
|
||||
// render the dashboards list page with empty response
|
||||
await dashboardsListAndCreate(page, dashboardsListEmptyResponse);
|
||||
|
||||
// navigate to the dashboards landing page
|
||||
await page.locator(`li[data-menu-id*="/dashboard"]`).click();
|
||||
|
||||
await page.waitForRequest(`**/${getDashboardsListEndpoint}`);
|
||||
|
||||
// without data we should have no data rendering
|
||||
const noDataText = await page.getByText('No data');
|
||||
|
||||
await expect(noDataText).toBeVisible();
|
||||
|
||||
// create a new dashboard
|
||||
await page.locator(`data-testid=${newDashboardBtnID}`).click();
|
||||
|
||||
await dashboardsListAndCreate(page, createNewDashboardPostResponse);
|
||||
|
||||
await getIndividualDashboard(page, getIndividualDashboardResponse);
|
||||
|
||||
await page.locator(`li[data-menu-id*="Create"]`).click();
|
||||
|
||||
await page.waitForRequest(`**/${getIndividualDashboardsEndpoint}`);
|
||||
|
||||
await page.locator(`data-testid=${configureDashboardSettings}`).click();
|
||||
|
||||
const dashboardNameInput = await page.locator(
|
||||
`data-testid=${configureDashboardNameID}`,
|
||||
);
|
||||
|
||||
// edit the name of the dashboard
|
||||
await dashboardNameInput.fill('');
|
||||
|
||||
await dashboardNameInput.fill(`${dashboardName}`);
|
||||
|
||||
// edit the description of the dashboard
|
||||
const dashboardDescInput = await page.locator(
|
||||
`data-testid=${configureDashboardDescriptonID}`,
|
||||
);
|
||||
await dashboardDescInput.fill('');
|
||||
|
||||
await dashboardDescInput.fill(`${dashboardDescription}`);
|
||||
|
||||
await getIndividualDashboard(page, putNewDashboardResponse);
|
||||
|
||||
await page.locator(`data-testid=${saveConfigureDashboardID}`).click();
|
||||
|
||||
await page.locator(`svg[data-icon="close"]`).click();
|
||||
|
||||
// save the configs and check for updated values
|
||||
const dashboardTitle = await page
|
||||
.locator(`data-testid=${dashboardHomePageTitle}`)
|
||||
.textContent();
|
||||
|
||||
expect(dashboardTitle).toBe(`${dashboardName}`);
|
||||
|
||||
const dashboardDesc = await page
|
||||
.locator(`data-testid=${dashboardHomePageDesc}`)
|
||||
.textContent();
|
||||
|
||||
expect(dashboardDesc).toBe(`${dashboardDescription}`);
|
||||
|
||||
await page.locator(`data-testid=${addPanelID}`).click();
|
||||
|
||||
await getIndividualDashboard(page, putDashboardTimeSeriesResponse, true);
|
||||
|
||||
await getTimeSeriesQueryData(page, queryRangeSuccessResponse);
|
||||
|
||||
await page.locator(`id=${timeSeriesPanelID}`).click();
|
||||
|
||||
await page.waitForRequest(`**/${getIndividualDashboardsEndpoint}`);
|
||||
|
||||
const panelTitle = await page.getByText('Panel Title').isVisible();
|
||||
|
||||
await expect(panelTitle).toBeTruthy();
|
||||
|
||||
await page.getByPlaceholder('Title').type(`${timeSeriesGraphName}`);
|
||||
|
||||
await page.locator('data-testid=new-widget-save').click();
|
||||
|
||||
await getIndividualDashboard(
|
||||
page,
|
||||
dashboardGetCallWithTimeSeriesWidgetResponse,
|
||||
);
|
||||
|
||||
await page.locator('span:has-text("OK")').click();
|
||||
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
const timeSeriesWidget = await await page.locator(
|
||||
`data-testid=${timeSeriesGraphName}`,
|
||||
);
|
||||
|
||||
await expect(timeSeriesWidget).toBeTruthy();
|
||||
});
|
||||
});
|
180
frontend/tests/dashboards/utils.ts
Normal file
180
frontend/tests/dashboards/utils.ts
Normal file
@ -0,0 +1,180 @@
|
||||
import { Page } from '@playwright/test';
|
||||
import { JsonApplicationType } from '../fixtures/constant';
|
||||
|
||||
// API endpoints
|
||||
export const getDashboardsListEndpoint = 'v1/dashboards';
|
||||
|
||||
export const getIndividualDashboardsEndpoint = 'v1/dashboards/**';
|
||||
|
||||
export const queryRangeApiEndpoint = 'query_range';
|
||||
|
||||
// element's data-testid's
|
||||
export const newDashboardBtnID = 'create-new-dashboard';
|
||||
|
||||
export const configureDashboardSettings = 'show-drawer';
|
||||
|
||||
export const configureDashboardNameID = 'dashboard-name';
|
||||
|
||||
export const configureDashboardDescriptonID = 'dashboard-desc';
|
||||
|
||||
export const dashboardHomePageTitle = 'dashboard-landing-name';
|
||||
|
||||
export const dashboardHomePageDesc = 'dashboard-landing-desc';
|
||||
|
||||
export const saveConfigureDashboardID = 'save-dashboard-config';
|
||||
|
||||
export const addNewVariableID = 'add-new-variable';
|
||||
|
||||
export const dashboardName = 'Playwright Dashboard';
|
||||
|
||||
export const dashboardDescription = 'Playwright Dashboard Description';
|
||||
|
||||
export const addPanelID = 'add-panel';
|
||||
|
||||
export const timeSeriesPanelID = 'graph';
|
||||
|
||||
export const valuePanelID = 'value';
|
||||
|
||||
export const tablePanelID = 'table';
|
||||
|
||||
export const timeSeriesGraphName = 'Time1';
|
||||
|
||||
let widgetsId: string;
|
||||
|
||||
// mock API calls
|
||||
export const dashboardsListAndCreate = async (
|
||||
page: Page,
|
||||
response: any,
|
||||
): Promise<void> => {
|
||||
await page.route(`**/${getDashboardsListEndpoint}`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: JsonApplicationType,
|
||||
json: response,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
export const getIndividualDashboard = async (
|
||||
page: Page,
|
||||
response?: any,
|
||||
useRequestObject?: boolean,
|
||||
): Promise<void> => {
|
||||
await page.route(`**/${getIndividualDashboardsEndpoint}`, (route, request) => {
|
||||
if (useRequestObject && request.method() === 'PUT') {
|
||||
widgetsId = request.postDataJSON()?.widgets[0].id;
|
||||
}
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: JsonApplicationType,
|
||||
json: useRequestObject ? insertWidgetIdInResponse(widgetsId) : response,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const getTimeSeriesQueryData = async (
|
||||
page: Page,
|
||||
response: any,
|
||||
): Promise<void> => {
|
||||
await page.route(`**/${queryRangeApiEndpoint}`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: JsonApplicationType,
|
||||
json: response,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
export const insertWidgetIdInResponse = (widgetID: string) => {
|
||||
return {
|
||||
status: 'success',
|
||||
data: {
|
||||
id: 219,
|
||||
uuid: 'd697fddb-a771-4bb4-aa38-810f000ed96a',
|
||||
created_at: '2023-11-17T20:44:03.167646604Z',
|
||||
created_by: 'vikrant@signoz.io',
|
||||
updated_at: '2023-11-17T20:51:23.058536475Z',
|
||||
updated_by: 'vikrant@signoz.io',
|
||||
data: {
|
||||
description: 'Playwright Dashboard T',
|
||||
layout: [
|
||||
{
|
||||
h: 3,
|
||||
i: '9fbcf0db-1572-4572-bf6b-0a84dd10ed85',
|
||||
w: 6,
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
],
|
||||
name: '',
|
||||
tags: [],
|
||||
title: 'Playwright Dashboard',
|
||||
variables: {},
|
||||
widgets: [
|
||||
{
|
||||
description: '',
|
||||
id: widgetID,
|
||||
isStacked: false,
|
||||
nullZeroValues: '',
|
||||
opacity: '',
|
||||
panelTypes: 'graph',
|
||||
query: {
|
||||
builder: {
|
||||
queryData: [
|
||||
{
|
||||
aggregateAttribute: {
|
||||
dataType: '',
|
||||
id: '------',
|
||||
isColumn: false,
|
||||
isJSON: false,
|
||||
key: '',
|
||||
type: '',
|
||||
},
|
||||
aggregateOperator: 'count',
|
||||
dataSource: 'metrics',
|
||||
disabled: false,
|
||||
expression: 'A',
|
||||
filters: {
|
||||
items: [],
|
||||
op: 'AND',
|
||||
},
|
||||
groupBy: [],
|
||||
having: [],
|
||||
legend: '',
|
||||
limit: null,
|
||||
orderBy: [],
|
||||
queryName: 'A',
|
||||
reduceTo: 'sum',
|
||||
stepInterval: 60,
|
||||
},
|
||||
],
|
||||
queryFormulas: [],
|
||||
},
|
||||
clickhouse_sql: [
|
||||
{
|
||||
disabled: false,
|
||||
legend: '',
|
||||
name: 'A',
|
||||
query: '',
|
||||
},
|
||||
],
|
||||
id: '6b4011e4-bcea-497d-81a9-0ee7816b679d',
|
||||
promql: [
|
||||
{
|
||||
disabled: false,
|
||||
legend: '',
|
||||
name: 'A',
|
||||
query: '',
|
||||
},
|
||||
],
|
||||
queryType: 'builder',
|
||||
},
|
||||
timePreferance: 'GLOBAL_TIME',
|
||||
title: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
isLocked: 0,
|
||||
},
|
||||
};
|
||||
};
|
16
frontend/tests/fixtures/api/dashboard/createNewDashboardPost200.json
vendored
Normal file
16
frontend/tests/fixtures/api/dashboard/createNewDashboardPost200.json
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"id": 219,
|
||||
"uuid": "d697fddb-a771-4bb4-aa38-810f000ed96a",
|
||||
"created_at": "2023-11-17T18:36:36.185916891Z",
|
||||
"created_by": "vikrant@signoz.io",
|
||||
"updated_at": "2023-11-17T18:36:36.185916989Z",
|
||||
"updated_by": "vikrant@signoz.io",
|
||||
"data": {
|
||||
"title": "Sample Title",
|
||||
"uploadedGrafana": false
|
||||
},
|
||||
"isLocked": null
|
||||
}
|
||||
}
|
91
frontend/tests/fixtures/api/dashboard/dashboardGetCallWithTimeSeriesWidget200.json
vendored
Normal file
91
frontend/tests/fixtures/api/dashboard/dashboardGetCallWithTimeSeriesWidget200.json
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"id": 219,
|
||||
"uuid": "d697fddb-a771-4bb4-aa38-810f000ed96a",
|
||||
"created_at": "2023-11-17T20:44:03.167646604Z",
|
||||
"created_by": "vikrant@signoz.io",
|
||||
"updated_at": "2023-11-17T20:51:23.058536475Z",
|
||||
"updated_by": "vikrant@signoz.io",
|
||||
"data": {
|
||||
"description": "Playwright Dashboard T",
|
||||
"layout": [
|
||||
{
|
||||
"h": 3,
|
||||
"i": "9fbcf0db-1572-4572-bf6b-0a84dd10ed85",
|
||||
"w": 6,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
],
|
||||
"name": "",
|
||||
"tags": [],
|
||||
"title": "Playwright Dashboard",
|
||||
"variables": {},
|
||||
"widgets": [
|
||||
{
|
||||
"description": "",
|
||||
"id": "9fbcf0db-1572-4572-bf6b-0a84dd10ed85",
|
||||
"isStacked": false,
|
||||
"nullZeroValues": "",
|
||||
"opacity": "",
|
||||
"panelTypes": "graph",
|
||||
"query": {
|
||||
"builder": {
|
||||
"queryData": [
|
||||
{
|
||||
"aggregateAttribute": {
|
||||
"dataType": "",
|
||||
"id": "------",
|
||||
"isColumn": false,
|
||||
"isJSON": false,
|
||||
"key": "",
|
||||
"type": ""
|
||||
},
|
||||
"aggregateOperator": "count",
|
||||
"dataSource": "metrics",
|
||||
"disabled": false,
|
||||
"expression": "A",
|
||||
"filters": {
|
||||
"items": [],
|
||||
"op": "AND"
|
||||
},
|
||||
"groupBy": [],
|
||||
"having": [],
|
||||
"legend": "",
|
||||
"limit": null,
|
||||
"orderBy": [],
|
||||
"queryName": "A",
|
||||
"reduceTo": "sum",
|
||||
"stepInterval": 60
|
||||
}
|
||||
],
|
||||
"queryFormulas": []
|
||||
},
|
||||
"clickhouse_sql": [
|
||||
{
|
||||
"disabled": false,
|
||||
"legend": "",
|
||||
"name": "A",
|
||||
"query": ""
|
||||
}
|
||||
],
|
||||
"id": "6b4011e4-bcea-497d-81a9-0ee7816b679d",
|
||||
"promql": [
|
||||
{
|
||||
"disabled": false,
|
||||
"legend": "",
|
||||
"name": "A",
|
||||
"query": ""
|
||||
}
|
||||
],
|
||||
"queryType": "builder"
|
||||
},
|
||||
"timePreferance": "GLOBAL_TIME",
|
||||
"title": "Time1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"isLocked": 0
|
||||
}
|
||||
}
|
4
frontend/tests/fixtures/api/dashboard/getDashboardListEmpty200.json
vendored
Normal file
4
frontend/tests/fixtures/api/dashboard/getDashboardListEmpty200.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": []
|
||||
}
|
16
frontend/tests/fixtures/api/dashboard/getIndividualDashboard200.json
vendored
Normal file
16
frontend/tests/fixtures/api/dashboard/getIndividualDashboard200.json
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"id": 219,
|
||||
"uuid": "d697fddb-a771-4bb4-aa38-810f000ed96a",
|
||||
"created_at": "2023-11-17T18:36:36.185916891Z",
|
||||
"created_by": "vikrant@signoz.io",
|
||||
"updated_at": "2023-11-17T18:36:36.185916989Z",
|
||||
"updated_by": "vikrant@signoz.io",
|
||||
"data": {
|
||||
"title": "Sample Title",
|
||||
"uploadedGrafana": false
|
||||
},
|
||||
"isLocked": 0
|
||||
}
|
||||
}
|
91
frontend/tests/fixtures/api/dashboard/putDashboardWithTimeSeries200.json
vendored
Normal file
91
frontend/tests/fixtures/api/dashboard/putDashboardWithTimeSeries200.json
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"id": 219,
|
||||
"uuid": "d697fddb-a771-4bb4-aa38-810f000ed96a",
|
||||
"created_at": "2023-11-17T20:44:03.167646604Z",
|
||||
"created_by": "vikrant@signoz.io",
|
||||
"updated_at": "2023-11-17T20:51:23.058536475Z",
|
||||
"updated_by": "vikrant@signoz.io",
|
||||
"data": {
|
||||
"description": "Playwright Dashboard T",
|
||||
"layout": [
|
||||
{
|
||||
"h": 3,
|
||||
"i": "9fbcf0db-1572-4572-bf6b-0a84dd10ed85",
|
||||
"w": 6,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
],
|
||||
"name": "",
|
||||
"tags": [],
|
||||
"title": "Playwright Dashboard",
|
||||
"variables": {},
|
||||
"widgets": [
|
||||
{
|
||||
"description": "",
|
||||
"id": "9fbcf0db-1572-4572-bf6b-0a84dd10ed85",
|
||||
"isStacked": false,
|
||||
"nullZeroValues": "",
|
||||
"opacity": "",
|
||||
"panelTypes": "graph",
|
||||
"query": {
|
||||
"builder": {
|
||||
"queryData": [
|
||||
{
|
||||
"aggregateAttribute": {
|
||||
"dataType": "",
|
||||
"id": "------",
|
||||
"isColumn": false,
|
||||
"isJSON": false,
|
||||
"key": "",
|
||||
"type": ""
|
||||
},
|
||||
"aggregateOperator": "count",
|
||||
"dataSource": "metrics",
|
||||
"disabled": false,
|
||||
"expression": "A",
|
||||
"filters": {
|
||||
"items": [],
|
||||
"op": "AND"
|
||||
},
|
||||
"groupBy": [],
|
||||
"having": [],
|
||||
"legend": "",
|
||||
"limit": null,
|
||||
"orderBy": [],
|
||||
"queryName": "A",
|
||||
"reduceTo": "sum",
|
||||
"stepInterval": 60
|
||||
}
|
||||
],
|
||||
"queryFormulas": []
|
||||
},
|
||||
"clickhouse_sql": [
|
||||
{
|
||||
"disabled": false,
|
||||
"legend": "",
|
||||
"name": "A",
|
||||
"query": ""
|
||||
}
|
||||
],
|
||||
"id": "6b4011e4-bcea-497d-81a9-0ee7816b679d",
|
||||
"promql": [
|
||||
{
|
||||
"disabled": false,
|
||||
"legend": "",
|
||||
"name": "A",
|
||||
"query": ""
|
||||
}
|
||||
],
|
||||
"queryType": "builder"
|
||||
},
|
||||
"timePreferance": "GLOBAL_TIME",
|
||||
"title": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"isLocked": 0
|
||||
}
|
||||
}
|
18
frontend/tests/fixtures/api/dashboard/putNewDashboardUpdate200.json
vendored
Normal file
18
frontend/tests/fixtures/api/dashboard/putNewDashboardUpdate200.json
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"id": 219,
|
||||
"uuid": "d697fddb-a771-4bb4-aa38-810f000ed96a",
|
||||
"created_at": "2023-11-17T18:47:15.740385406Z",
|
||||
"created_by": "vikrant@signoz.io",
|
||||
"updated_at": "2023-11-17T19:11:25.052190048Z",
|
||||
"updated_by": "vikrant@signoz.io",
|
||||
"data": {
|
||||
"description": "Playwright Dashboard Description",
|
||||
"tags": [],
|
||||
"title": "Playwright Dashboard",
|
||||
"uploadedGrafana": false
|
||||
},
|
||||
"isLocked": 0
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user