chore(integration-test): remove the outdated-setup (#7887)
* chore(integration-test): remove the outdated-setup * chore(integration-test): remove the outdated-setup
2
.gitignore
vendored
@ -60,9 +60,7 @@ ee/query-service/db
|
||||
|
||||
e2e/node_modules/
|
||||
e2e/test-results/
|
||||
e2e/playwright-report/
|
||||
e2e/blob-report/
|
||||
e2e/playwright/.cache/
|
||||
e2e/.auth
|
||||
|
||||
# go
|
||||
|
@ -3,5 +3,4 @@ BUNDLE_ANALYSER="true"
|
||||
FRONTEND_API_ENDPOINT="http://localhost:8080/"
|
||||
INTERCOM_APP_ID="intercom-app-id"
|
||||
|
||||
PLAYWRIGHT_TEST_BASE_URL="http://localhost:8080"
|
||||
CI="1"
|
@ -30,11 +30,6 @@ const config: Config.InitialOptions = {
|
||||
testPathIgnorePatterns: ['/node_modules/', '/public/'],
|
||||
moduleDirectories: ['node_modules', 'src'],
|
||||
testEnvironment: 'jest-environment-jsdom',
|
||||
testEnvironmentOptions: {
|
||||
'jest-playwright': {
|
||||
browsers: ['chromium', 'firefox', 'webkit'],
|
||||
},
|
||||
},
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
statements: 80,
|
||||
|
@ -15,10 +15,6 @@
|
||||
"jest:coverage": "jest --coverage",
|
||||
"jest:watch": "jest --watch",
|
||||
"postinstall": "yarn i18n:generate-hash && (is-ci || yarn husky:configure)",
|
||||
"playwright": "NODE_ENV=testing playwright test --config=./playwright.config.ts",
|
||||
"playwright:local:debug": "PWDEBUG=console yarn playwright --headed --browser=chromium",
|
||||
"playwright:codegen:local": "playwright codegen http://localhost:3301",
|
||||
"playwright:codegen:local:auth": "yarn playwright:codegen:local --load-storage=tests/auth.json",
|
||||
"husky:configure": "cd .. && husky install frontend/.husky && cd frontend && chmod ug+x .husky/*",
|
||||
"commitlint": "commitlint --edit $1",
|
||||
"test": "jest",
|
||||
@ -164,7 +160,6 @@
|
||||
"@commitlint/config-conventional": "^16.2.4",
|
||||
"@faker-js/faker": "9.3.0",
|
||||
"@jest/globals": "^27.5.1",
|
||||
"@playwright/test": "^1.22.0",
|
||||
"@testing-library/jest-dom": "5.16.5",
|
||||
"@testing-library/react": "13.4.0",
|
||||
"@testing-library/user-event": "14.4.3",
|
||||
|
@ -1,23 +0,0 @@
|
||||
import { PlaywrightTestConfig } from '@playwright/test';
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
forbidOnly: !!process.env.CI,
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
preserveOutput: 'always',
|
||||
name: 'Signoz',
|
||||
testDir: './tests',
|
||||
use: {
|
||||
trace: 'retain-on-failure',
|
||||
baseURL: process.env.PLAYWRIGHT_TEST_BASE_URL || 'http://localhost:3301',
|
||||
},
|
||||
updateSnapshots: 'all',
|
||||
fullyParallel: !!process.env.CI,
|
||||
quiet: false,
|
||||
testMatch: ['**/*.spec.ts'],
|
||||
reporter: process.env.CI ? 'github' : 'list',
|
||||
};
|
||||
|
||||
export default config;
|
@ -9,7 +9,7 @@ done
|
||||
# create temporary tsconfig which includes only passed files
|
||||
str="{
|
||||
\"extends\": \"./tsconfig.json\",
|
||||
\"include\": [ \"src/typings/**/*.ts\",\"src/**/*.d.ts\", \"./babel.config.js\", \"./jest.config.ts\", \"./.eslintrc.js\",\"./__mocks__\",\"./conf/default.conf\",\"./public\",\"./tests\",\"./playwright.config.ts\",\"./commitlint.config.ts\",\"./webpack.config.js\",\"./webpack.config.prod.js\",\"./jest.setup.ts\",\"./**/*.d.ts\",$files]
|
||||
\"include\": [ \"src/typings/**/*.ts\",\"src/**/*.d.ts\", \"./babel.config.js\", \"./jest.config.ts\", \"./.eslintrc.js\",\"./__mocks__\",\"./public\",\"./tests\",\"./commitlint.config.ts\",\"./webpack.config.js\",\"./webpack.config.prod.js\",\"./jest.setup.ts\",\"./**/*.d.ts\",$files]
|
||||
}"
|
||||
echo $str > tsconfig.tmp
|
||||
|
||||
|
@ -1,34 +0,0 @@
|
||||
{
|
||||
"cookies": [],
|
||||
"origins": [
|
||||
{
|
||||
"origin": "http://localhost:3301",
|
||||
"localStorage": [
|
||||
{
|
||||
"name": "metricsTimeDurations",
|
||||
"value": "{}"
|
||||
},
|
||||
{
|
||||
"name": "i18nextLng",
|
||||
"value": "en-US"
|
||||
},
|
||||
{
|
||||
"name": "reactQueryDevtoolsSortFn",
|
||||
"value": "\"Status > Last Updated\""
|
||||
},
|
||||
{
|
||||
"name": "AUTH_TOKEN",
|
||||
"value": "authtoken"
|
||||
},
|
||||
{
|
||||
"name": "IS_LOGGED_IN",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"name": "REFRESH_AUTH_TOKEN",
|
||||
"value": "refreshJwt"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
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();
|
||||
});
|
||||
});
|
@ -1,181 +0,0 @@
|
||||
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;
|
||||
|
||||
export const insertWidgetIdInResponse = (widgetID: string): any => ({
|
||||
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,
|
||||
},
|
||||
],
|
||||
version: 'v3',
|
||||
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: 'avg',
|
||||
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,
|
||||
},
|
||||
});
|
||||
|
||||
// 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> => {
|
||||
// eslint-disable-next-line sonarjs/no-identical-functions
|
||||
await page.route(`**/${queryRangeApiEndpoint}`, (route): any =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: JsonApplicationType,
|
||||
json: response,
|
||||
}),
|
||||
);
|
||||
};
|
@ -1,101 +0,0 @@
|
||||
import { expect, Page, test } from '@playwright/test';
|
||||
import ROUTES from 'constants/routes';
|
||||
|
||||
import allErrorList from '../fixtures/api/allErrors/200.json';
|
||||
import errorDetailSuccess from '../fixtures/api/errorDetails/200.json';
|
||||
import errorDetailNotFound from '../fixtures/api/errorDetails/404.json';
|
||||
import nextPreviousSuccess from '../fixtures/api/getNextPrev/200.json';
|
||||
import { loginApi } from '../fixtures/common';
|
||||
import { JsonApplicationType } from '../fixtures/constant';
|
||||
|
||||
let page: Page;
|
||||
const timestamp = '1657794588955274000';
|
||||
|
||||
test.describe('Expections Details', async () => {
|
||||
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('Should have not found when api return 404', async () => {
|
||||
await Promise.all([
|
||||
page.route('**/errorFromGroupID**', (route) =>
|
||||
route.fulfill({
|
||||
status: 404,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify(errorDetailNotFound),
|
||||
}),
|
||||
),
|
||||
page.route('**/nextPrevErrorIDs**', (route) =>
|
||||
route.fulfill({
|
||||
status: 404,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify([]),
|
||||
}),
|
||||
),
|
||||
]);
|
||||
|
||||
await page.goto(
|
||||
`${ROUTES.ERROR_DETAIL}?groupId=${allErrorList[0].groupID}×tamp=${timestamp}`,
|
||||
{
|
||||
waitUntil: 'networkidle',
|
||||
},
|
||||
);
|
||||
|
||||
const NoDataLocator = page.locator('text=Not Found');
|
||||
const isVisible = await NoDataLocator.isVisible();
|
||||
const text = await NoDataLocator.textContent();
|
||||
|
||||
expect(isVisible).toBe(true);
|
||||
expect(text).toBe('Not Found');
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Render Success Data when 200 from details page', async () => {
|
||||
await Promise.all([
|
||||
page.route('**/errorFromGroupID**', (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify(errorDetailSuccess),
|
||||
}),
|
||||
),
|
||||
page.route('**/nextPrevErrorIDs**', (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify(nextPreviousSuccess),
|
||||
}),
|
||||
),
|
||||
]);
|
||||
|
||||
await page.goto(
|
||||
`${ROUTES.ERROR_DETAIL}?groupId=${allErrorList[0].groupID}×tamp=${timestamp}`,
|
||||
{
|
||||
waitUntil: 'networkidle',
|
||||
},
|
||||
);
|
||||
|
||||
const traceDetailButton = page.locator('text=See the error in trace graph');
|
||||
const olderButton = page.locator('text=Older');
|
||||
const newerButton = page.locator(`text=Newer`);
|
||||
|
||||
expect(await traceDetailButton.isVisible()).toBe(true);
|
||||
expect(await olderButton.isVisible()).toBe(true);
|
||||
expect(await newerButton.isVisible()).toBe(true);
|
||||
|
||||
expect(await traceDetailButton.textContent()).toBe(
|
||||
'See the error in trace graph',
|
||||
);
|
||||
expect(await olderButton.textContent()).toBe('Older');
|
||||
expect(await newerButton.textContent()).toBe('Newer');
|
||||
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
});
|
Before Width: | Height: | Size: 183 KiB |
Before Width: | Height: | Size: 39 KiB |
@ -1,148 +0,0 @@
|
||||
import { expect, Page, test } from '@playwright/test';
|
||||
import ROUTES from 'constants/routes';
|
||||
|
||||
import successAllErrors from '../fixtures/api/allErrors/200.json';
|
||||
import { loginApi } from '../fixtures/common';
|
||||
import { JsonApplicationType } from '../fixtures/constant';
|
||||
|
||||
const noDataTableData = async (page: Page): Promise<void> => {
|
||||
const text = page.locator('text=No Data');
|
||||
|
||||
expect(text).toBeVisible();
|
||||
expect(text).toHaveText('No Data');
|
||||
|
||||
const textType = [
|
||||
'Exception Type',
|
||||
'Error Message',
|
||||
'Last Seen',
|
||||
'First Seen',
|
||||
'Application',
|
||||
];
|
||||
|
||||
textType.forEach(async (text) => {
|
||||
const textLocator = page.locator(`text=${text}`);
|
||||
|
||||
const textContent = await textLocator.textContent();
|
||||
|
||||
expect(textContent).toBe(text);
|
||||
expect(textLocator).not.toBeNull();
|
||||
|
||||
expect(textLocator).toBeVisible();
|
||||
await expect(textLocator).toHaveText(`${text}`);
|
||||
});
|
||||
};
|
||||
|
||||
let page: Page;
|
||||
|
||||
test.describe('Expections page', async () => {
|
||||
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('Should have a valid route', async () => {
|
||||
await page.goto(ROUTES.ALL_ERROR);
|
||||
|
||||
await expect(page).toHaveURL(ROUTES.ALL_ERROR);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Should have a valid Breadcrumbs', async () => {
|
||||
await page.goto(ROUTES.ALL_ERROR, {
|
||||
waitUntil: 'networkidle',
|
||||
});
|
||||
|
||||
const expectionsLocator = page.locator('a:has-text("Exceptions")');
|
||||
|
||||
await expect(expectionsLocator).toBeVisible();
|
||||
await expect(expectionsLocator).toHaveText('Exceptions');
|
||||
await expect(expectionsLocator).toHaveAttribute('href', ROUTES.ALL_ERROR);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Should render the page with 404 status', async () => {
|
||||
await page.route('**listErrors', (route) =>
|
||||
route.fulfill({
|
||||
status: 404,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify([]),
|
||||
}),
|
||||
);
|
||||
|
||||
await page.goto(ROUTES.ALL_ERROR, {
|
||||
waitUntil: 'networkidle',
|
||||
});
|
||||
|
||||
await noDataTableData(page);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Should render the page with 500 status in antd notification with no data antd table', async () => {
|
||||
await page.route(`**/listErrors**`, (route) =>
|
||||
route.fulfill({
|
||||
status: 500,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify([]),
|
||||
}),
|
||||
);
|
||||
|
||||
await page.goto(ROUTES.ALL_ERROR, {
|
||||
waitUntil: 'networkidle',
|
||||
});
|
||||
|
||||
const text = 'Something went wrong';
|
||||
|
||||
const el = page.locator(`text=${text}`);
|
||||
|
||||
expect(el).toBeVisible();
|
||||
expect(el).toHaveText(`${text}`);
|
||||
expect(await el.getAttribute('disabled')).toBe(null);
|
||||
|
||||
await noDataTableData(page);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Should render data in antd table', async () => {
|
||||
await Promise.all([
|
||||
page.route(`**/listErrors**`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify(successAllErrors),
|
||||
}),
|
||||
),
|
||||
|
||||
page.route('**/countErrors**', (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify(200),
|
||||
}),
|
||||
),
|
||||
]);
|
||||
|
||||
await page.goto(ROUTES.ALL_ERROR, {
|
||||
waitUntil: 'networkidle',
|
||||
});
|
||||
|
||||
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
|
||||
|
||||
const expectionType = page.locator(
|
||||
`td:has-text("${successAllErrors[1].exceptionType}")`,
|
||||
);
|
||||
|
||||
expect(expectionType).toBeVisible();
|
||||
|
||||
const second = page.locator('li > a:has-text("2") >> nth=0');
|
||||
const isVisisble = await second.isVisible();
|
||||
|
||||
expect(isVisisble).toBe(true);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
});
|
Before Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 115 KiB |
Before Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 58 KiB |
92
frontend/tests/fixtures/api/allErrors/200.json
vendored
@ -1,92 +0,0 @@
|
||||
[
|
||||
{
|
||||
"exceptionType": "ConnectionError",
|
||||
"exceptionMessage": "HTTPSConnectionPool(host='run.mocekdy.io', port=443): Max retries exceeded with url: /v3/1cwb67153-a6ac-4aae-aca6-273ed68b5d9e (Caused by NewConnectionError('\u003curllib3.connection.HTTPSConnection object at 0x108ce9c10\u003e: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))",
|
||||
"exceptionCount": 2,
|
||||
"lastSeen": "2022-07-14T10:29:48.955274Z",
|
||||
"firstSeen": "2022-07-14T10:29:48.950721Z",
|
||||
"serviceName": "1rfflaskAp",
|
||||
"groupID": "e24d35bda98c5499a5c8df3ba61b0238"
|
||||
},
|
||||
{
|
||||
"exceptionType": "NameError",
|
||||
"exceptionMessage": "name 'listf' is not defined",
|
||||
"exceptionCount": 8,
|
||||
"lastSeen": "2022-07-14T10:30:42.411035Z",
|
||||
"firstSeen": "2022-07-14T10:29:45.426784Z",
|
||||
"serviceName": "1rfflaskAp",
|
||||
"groupID": "efc46adcd5e87b65f8f244cba683b265"
|
||||
},
|
||||
{
|
||||
"exceptionType": "ZeroDivisionError",
|
||||
"exceptionMessage": "division by zero",
|
||||
"exceptionCount": 1,
|
||||
"lastSeen": "2022-07-14T10:29:54.195996Z",
|
||||
"firstSeen": "2022-07-14T10:29:54.195996Z",
|
||||
"serviceName": "1rfflaskAp",
|
||||
"groupID": "a49058b540eef9aefe159d84f1a2b6df"
|
||||
},
|
||||
{
|
||||
"exceptionType": "MaxRetryError",
|
||||
"exceptionMessage": "HTTPSConnectionPool(host='rufn.fmoceky.io', port=443): Max retries exceeded with url: /v3/b851a5c6-ab54-495a-be04-69834ae0d2a7 (Caused by NewConnectionError('\u003curllib3.connection.HTTPSConnection object at 0x108ec2640\u003e: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))",
|
||||
"exceptionCount": 1,
|
||||
"lastSeen": "2022-07-14T10:29:49.471402Z",
|
||||
"firstSeen": "2022-07-14T10:29:49.471402Z",
|
||||
"serviceName": "1rfflaskAp",
|
||||
"groupID": "e59d39239f4d48842d83e3cc4cf53249"
|
||||
},
|
||||
{
|
||||
"exceptionType": "MaxRetryError",
|
||||
"exceptionMessage": "HTTPSConnectionPool(host='run.mocekdy.io', port=443): Max retries exceeded with url: /v3/1cwb67153-a6ac-4aae-aca6-273ed68b5d9e (Caused by NewConnectionError('\u003curllib3.connection.HTTPSConnection object at 0x108ce9c10\u003e: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))",
|
||||
"exceptionCount": 1,
|
||||
"lastSeen": "2022-07-14T10:29:48.947579Z",
|
||||
"firstSeen": "2022-07-14T10:29:48.947579Z",
|
||||
"serviceName": "1rfflaskAp",
|
||||
"groupID": "14d18a6fb1cd3f541de1566530e75486"
|
||||
},
|
||||
{
|
||||
"exceptionType": "ConnectionError",
|
||||
"exceptionMessage": "HTTPSConnectionPool(host='rufn.fmoceky.io', port=443): Max retries exceeded with url: /v3/b851a5c6-ab54-495a-be04-69834ae0d2a7 (Caused by NewConnectionError('\u003curllib3.connection.HTTPSConnection object at 0x108ec2640\u003e: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))",
|
||||
"exceptionCount": 2,
|
||||
"lastSeen": "2022-07-14T10:29:49.476718Z",
|
||||
"firstSeen": "2022-07-14T10:29:49.472271Z",
|
||||
"serviceName": "1rfflaskAp",
|
||||
"groupID": "bf6d88d10397ca3194b96a10f4719031"
|
||||
},
|
||||
{
|
||||
"exceptionType": "github.com/gin-gonic/gin.Error",
|
||||
"exceptionMessage": "Sample Error",
|
||||
"exceptionCount": 6,
|
||||
"lastSeen": "2022-07-15T18:55:32.3538096Z",
|
||||
"firstSeen": "2022-07-14T14:47:19.874387Z",
|
||||
"serviceName": "goApp",
|
||||
"groupID": "b4fd099280072d45318e1523d82aa9c1"
|
||||
},
|
||||
{
|
||||
"exceptionType": "MaxRetryError",
|
||||
"exceptionMessage": "HTTPSConnectionPool(host='rufn.fmoceky.io', port=443): Max retries exceeded with url: /v3/b851a5c6-ab54-495a-be04-69834ae0d2a7 (Caused by NewConnectionError('\u003curllib3.connection.HTTPSConnection object at 0x10801b490\u003e: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))",
|
||||
"exceptionCount": 1,
|
||||
"lastSeen": "2022-07-14T11:07:06.560593Z",
|
||||
"firstSeen": "2022-07-14T11:07:06.560593Z",
|
||||
"serviceName": "samplFlaskApp",
|
||||
"groupID": "1945671c945b10641e73b0fe28c4d486"
|
||||
},
|
||||
{
|
||||
"exceptionType": "ConnectionError",
|
||||
"exceptionMessage": "HTTPSConnectionPool(host='rufn.fmoceky.io', port=443): Max retries exceeded with url: /v3/b851a5c6-ab54-495a-be04-69834ae0d2a7 (Caused by NewConnectionError('\u003curllib3.connection.HTTPSConnection object at 0x10801b490\u003e: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))",
|
||||
"exceptionCount": 2,
|
||||
"lastSeen": "2022-07-14T11:07:06.56493Z",
|
||||
"firstSeen": "2022-07-14T11:07:06.561074Z",
|
||||
"serviceName": "samplFlaskApp",
|
||||
"groupID": "5bea5295cac187404005f9c96e71aa53"
|
||||
},
|
||||
{
|
||||
"exceptionType": "ConnectionError",
|
||||
"exceptionMessage": "HTTPSConnectionPool(host='rufn.fmoceky.io', port=443): Max retries exceeded with url: /v3/b851a5c6-ab54-495a-be04-69834ae0d2a7 (Caused by NewConnectionError('\u003curllib3.connection.HTTPSConnection object at 0x108031820\u003e: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))",
|
||||
"exceptionCount": 2,
|
||||
"lastSeen": "2022-07-14T11:07:06.363977Z",
|
||||
"firstSeen": "2022-07-14T11:07:06.361163Z",
|
||||
"serviceName": "samplFlaskApp",
|
||||
"groupID": "52a1fbe033453d806c0f24ba39168a78"
|
||||
}
|
||||
]
|
@ -1,16 +0,0 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
{
|
||||
"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": "avg",
|
||||
"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
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": []
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
{
|
||||
"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": "avg",
|
||||
"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
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"error": "Error/Exception not found",
|
||||
"errorType": "not_found",
|
||||
"status": "error"
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"nextErrorID": "",
|
||||
"nextTimestamp": "0001-01-01T00:00:00Z",
|
||||
"prevErrorID": "217133e5f7df429abd31b507859ea513",
|
||||
"prevTimestamp": "2022-07-14T10:29:48.950721Z",
|
||||
"groupID": "e24d35bda98c5499a5c8df3ba61b0238"
|
||||
}
|
7
frontend/tests/fixtures/api/login/200.json
vendored
@ -1,7 +0,0 @@
|
||||
{
|
||||
"accessJwt": "authtoken",
|
||||
"accessJwtExpiry": 1656609177,
|
||||
"refreshJwt": "refreshJwt",
|
||||
"refreshJwtExpiry": 1659199377,
|
||||
"userId": "34917776-514b-4b95-a4f5-1a5cc06e34b6"
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"data": "org updated successfully"
|
||||
}
|
@ -1 +0,0 @@
|
||||
{ "data": "user registered successfully" }
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"status": "error",
|
||||
"errorType": "unauthorized",
|
||||
"error": "You are not allowed to create an account. Please ask your admin to send an invite link"
|
||||
}
|
68
frontend/tests/fixtures/api/services/200.json
vendored
@ -1,68 +0,0 @@
|
||||
[
|
||||
{
|
||||
"serviceName": "redis",
|
||||
"p99": 35396180,
|
||||
"avgDuration": 15149389.806977473,
|
||||
"numCalls": 22329,
|
||||
"callRate": 12.615254237288136,
|
||||
"numErrors": 4135,
|
||||
"errorRate": 18.51851851851852,
|
||||
"num4XX": 0,
|
||||
"fourXXRate": 0
|
||||
},
|
||||
{
|
||||
"serviceName": "frontend",
|
||||
"p99": 1173509510.0000002,
|
||||
"avgDuration": 747007254.5344619,
|
||||
"numCalls": 1654,
|
||||
"callRate": 0.9344632768361582,
|
||||
"numErrors": 0,
|
||||
"errorRate": 0,
|
||||
"num4XX": 0,
|
||||
"fourXXRate": 0
|
||||
},
|
||||
{
|
||||
"serviceName": "mysql",
|
||||
"p99": 776834620,
|
||||
"avgDuration": 349280732.76904476,
|
||||
"numCalls": 1654,
|
||||
"callRate": 0.9344632768361582,
|
||||
"numErrors": 0,
|
||||
"errorRate": 0,
|
||||
"num4XX": 0,
|
||||
"fourXXRate": 0
|
||||
},
|
||||
{
|
||||
"serviceName": "customer",
|
||||
"p99": 776995390,
|
||||
"avgDuration": 349451783.5550181,
|
||||
"numCalls": 1654,
|
||||
"callRate": 0.9344632768361582,
|
||||
"numErrors": 0,
|
||||
"errorRate": 0,
|
||||
"num4XX": 0,
|
||||
"fourXXRate": 0
|
||||
},
|
||||
{
|
||||
"serviceName": "route",
|
||||
"p99": 79617600.00000001,
|
||||
"avgDuration": 50698870.85852479,
|
||||
"numCalls": 16540,
|
||||
"callRate": 9.344632768361581,
|
||||
"numErrors": 0,
|
||||
"errorRate": 0,
|
||||
"num4XX": 0,
|
||||
"fourXXRate": 0
|
||||
},
|
||||
{
|
||||
"serviceName": "driver",
|
||||
"p99": 241056990,
|
||||
"avgDuration": 204975300.48367593,
|
||||
"numCalls": 1654,
|
||||
"callRate": 0.9344632768361582,
|
||||
"numErrors": 0,
|
||||
"errorRate": 0,
|
||||
"num4XX": 0,
|
||||
"fourXXRate": 0
|
||||
}
|
||||
]
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"attributeKeys": [
|
||||
{
|
||||
"key": "serviceName",
|
||||
"dataType": "string",
|
||||
"type": "tag",
|
||||
"isColumn": true,
|
||||
"isJSON": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"attributeKeys": [
|
||||
{
|
||||
"key": "durationNano",
|
||||
"dataType": "float64",
|
||||
"type": "tag",
|
||||
"isColumn": true,
|
||||
"isJSON": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"attributeKeys": [
|
||||
{
|
||||
"key": "externalHttpMethod",
|
||||
"dataType": "string",
|
||||
"type": "tag",
|
||||
"isColumn": true,
|
||||
"isJSON": false
|
||||
},
|
||||
{
|
||||
"key": "httpMethod",
|
||||
"dataType": "string",
|
||||
"type": "tag",
|
||||
"isColumn": true,
|
||||
"isJSON": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"attributeKeys": [
|
||||
{
|
||||
"key": "dbName",
|
||||
"dataType": "string",
|
||||
"type": "tag",
|
||||
"isColumn": true,
|
||||
"isJSON": false
|
||||
},
|
||||
{
|
||||
"key": "host.name",
|
||||
"dataType": "string",
|
||||
"type": "resource",
|
||||
"isColumn": false,
|
||||
"isJSON": false
|
||||
},
|
||||
{
|
||||
"key": "process.runtime.name",
|
||||
"dataType": "string",
|
||||
"type": "resource",
|
||||
"isColumn": false,
|
||||
"isJSON": false
|
||||
},
|
||||
{
|
||||
"key": "service.name",
|
||||
"dataType": "string",
|
||||
"type": "resource",
|
||||
"isColumn": false,
|
||||
"isJSON": false
|
||||
},
|
||||
{
|
||||
"key": "serviceName",
|
||||
"dataType": "string",
|
||||
"type": "tag",
|
||||
"isColumn": true,
|
||||
"isJSON": false
|
||||
},
|
||||
{
|
||||
"key": "name",
|
||||
"dataType": "string",
|
||||
"type": "tag",
|
||||
"isColumn": true,
|
||||
"isJSON": false
|
||||
},
|
||||
{
|
||||
"key": "telemetry.sdk.name",
|
||||
"dataType": "string",
|
||||
"type": "resource",
|
||||
"isColumn": false,
|
||||
"isJSON": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"attributeKeys": [
|
||||
{
|
||||
"key": "responseStatusCode",
|
||||
"dataType": "string",
|
||||
"type": "tag",
|
||||
"isColumn": true,
|
||||
"isJSON": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"attributeKeys": [
|
||||
{
|
||||
"key": "serviceName",
|
||||
"dataType": "string",
|
||||
"type": "tag",
|
||||
"isColumn": true,
|
||||
"isJSON": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"resultType": "",
|
||||
"result": [
|
||||
{
|
||||
"queryName": "A",
|
||||
"series": null,
|
||||
"list": [
|
||||
{
|
||||
"timestamp": "2023-11-14T18:26:59.966905Z",
|
||||
"data": {
|
||||
"durationNano": 57896000,
|
||||
"httpMethod": "GET",
|
||||
"name": "HTTP GET /route",
|
||||
"responseStatusCode": "200",
|
||||
"serviceName": "route",
|
||||
"spanID": "0e5da5411ccc8ea5",
|
||||
"traceID": "00000000000000007008a05a3d9e5b97"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": "336368a4-dba7-4d65-9f91-142a355edb23"
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": [
|
||||
{
|
||||
"uuid": "8402eda3-2be3-4e07-930b-9ff69c3da34f",
|
||||
"name": "PlayWright",
|
||||
"category": "",
|
||||
"createdAt": "2023-11-16T19:24:49.875396768Z",
|
||||
"createdBy": "contributors@signoz.io",
|
||||
"updatedAt": "2023-11-16T19:24:49.875396872Z",
|
||||
"updatedBy": "contributors@signoz.io",
|
||||
"sourcePage": "traces",
|
||||
"tags": [""],
|
||||
"compositeQuery": {
|
||||
"builderQueries": {
|
||||
"A": {
|
||||
"queryName": "A",
|
||||
"stepInterval": 60,
|
||||
"dataSource": "traces",
|
||||
"aggregateOperator": "count",
|
||||
"aggregateAttribute": {
|
||||
"key": "",
|
||||
"dataType": "",
|
||||
"type": "",
|
||||
"isColumn": false,
|
||||
"isJSON": false
|
||||
},
|
||||
"filters": {
|
||||
"op": "AND",
|
||||
"items": []
|
||||
},
|
||||
"expression": "A",
|
||||
"disabled": false,
|
||||
"limit": 0,
|
||||
"offset": 0,
|
||||
"pageSize": 0,
|
||||
"orderBy": [
|
||||
{
|
||||
"columnName": "timestamp",
|
||||
"order": "desc"
|
||||
}
|
||||
],
|
||||
"reduceTo": "avg"
|
||||
}
|
||||
},
|
||||
"panelType": "table",
|
||||
"queryType": "builder"
|
||||
},
|
||||
"extraData": ""
|
||||
}
|
||||
]
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"resultType": "",
|
||||
"result": [
|
||||
{
|
||||
"queryName": "A",
|
||||
"series": null,
|
||||
"list": [
|
||||
{
|
||||
"timestamp": "0001-01-01T00:00:00Z",
|
||||
"data": {
|
||||
"span_count": 51,
|
||||
"subQuery.durationNano": 1533445000,
|
||||
"subQuery.name": "HTTP GET /dispatch",
|
||||
"subQuery.serviceName": "frontend",
|
||||
"traceID": "0000000000000000013e51e33c929173"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"resultType": "",
|
||||
"result": [
|
||||
{
|
||||
"queryName": "A",
|
||||
"series": [
|
||||
{
|
||||
"labels": {},
|
||||
"labelsArray": null,
|
||||
"values": [
|
||||
{
|
||||
"timestamp": 1700161420000,
|
||||
"value": "85784"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"list": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
11
frontend/tests/fixtures/api/userId/200.json
vendored
@ -1,11 +0,0 @@
|
||||
{
|
||||
"createdAt": 1651759141,
|
||||
"email": "prashant@signoz.io",
|
||||
"groupId": "36261238-3214-4ae9-9ef1-661a9f7be5d0",
|
||||
"id": "509fab4a-2578-4f24-8245-1b77b2d6d937",
|
||||
"name": "Prashant",
|
||||
"orgId": "72b4024a-3301-4d90-951e-ee071b96dba5",
|
||||
"organization": "Meta",
|
||||
"profilePictureURL": "",
|
||||
"role": "ADMIN"
|
||||
}
|
43
frontend/tests/fixtures/common.ts
vendored
@ -1,43 +0,0 @@
|
||||
import { Page } from '@playwright/test';
|
||||
import { getVersion } from 'constants/api';
|
||||
|
||||
import loginApiResponse from './api/login/200.json';
|
||||
import updateOrgResponse from './api/organisation/201.json';
|
||||
import successLoginResponse from './api/register/200.json';
|
||||
import userLoginResponse from './api/userId/200.json';
|
||||
import { version } from './constant';
|
||||
|
||||
export const waitForVersionApiSuccess = async (page: Page): Promise<void> => {
|
||||
await page.route(`**/${getVersion}`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
body: JSON.stringify({ version }),
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
export const loginApi = async (page: Page): Promise<void> => {
|
||||
await Promise.all([
|
||||
page.route(`**/register`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
body: JSON.stringify(successLoginResponse),
|
||||
}),
|
||||
),
|
||||
page.route(`**/user/${loginApiResponse.userId}`, (route) =>
|
||||
route.fulfill({ status: 200, body: JSON.stringify(userLoginResponse) }),
|
||||
),
|
||||
page.route('**/login', (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
body: JSON.stringify(loginApiResponse),
|
||||
}),
|
||||
),
|
||||
page.route(`**/orgs/me`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
body: JSON.stringify(updateOrgResponse),
|
||||
}),
|
||||
),
|
||||
]);
|
||||
};
|
10
frontend/tests/fixtures/constant.ts
vendored
@ -1,10 +0,0 @@
|
||||
export const version = 'v1.0.0';
|
||||
export const validemail = 'sample@signoz.io';
|
||||
export const validName = 'Palash';
|
||||
export const validCompanyName = 'Signoz';
|
||||
export const validPassword = 'SamplePassword98@@';
|
||||
|
||||
export const getStartedButtonSelector = 'button[data-attr="signup"]';
|
||||
export const confirmPasswordSelector = '#password-confirm-error';
|
||||
|
||||
export const JsonApplicationType = 'application/json';
|
@ -1,29 +0,0 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { getVersion } from 'constants/api';
|
||||
import ROUTES from 'constants/routes';
|
||||
|
||||
test.describe('Version API fail while loading login page', async () => {
|
||||
test('Something went wrong', async ({ page, baseURL }) => {
|
||||
const loginPage = `${baseURL}${ROUTES.LOGIN}`;
|
||||
|
||||
const text = 'Something went wrong';
|
||||
|
||||
await page.route(`**/${getVersion}`, (route) =>
|
||||
route.fulfill({
|
||||
status: 500,
|
||||
body: JSON.stringify({ error: text }),
|
||||
}),
|
||||
);
|
||||
|
||||
await page.goto(loginPage, {
|
||||
waitUntil: 'networkidle',
|
||||
});
|
||||
|
||||
const el = page.locator(`text=${text}`);
|
||||
|
||||
expect(el).toBeVisible();
|
||||
expect(el).toHaveText(`${text}`);
|
||||
expect(await el.getAttribute('disabled')).toBe(null);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
});
|
Before Width: | Height: | Size: 7.9 KiB |
@ -1,50 +0,0 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import ROUTES from 'constants/routes';
|
||||
|
||||
import { waitForVersionApiSuccess } from '../fixtures/common';
|
||||
import { version } from '../fixtures/constant';
|
||||
|
||||
test.describe('Login Page', () => {
|
||||
test.beforeEach(async ({ baseURL, page }) => {
|
||||
const loginPage = `${baseURL}${ROUTES.LOGIN}`;
|
||||
|
||||
await waitForVersionApiSuccess(page);
|
||||
|
||||
await Promise.all([page.goto(loginPage), page.waitForRequest('**/version')]);
|
||||
});
|
||||
|
||||
test('Login Page text should be visible', async ({ page }) => {
|
||||
const signup = 'Monitor your applications. Find what is causing issues.';
|
||||
|
||||
// Click text=Monitor your applications. Find what is causing issues.
|
||||
const el = page.locator(`text=${signup}`);
|
||||
|
||||
expect(el).toBeVisible();
|
||||
});
|
||||
|
||||
test('Create an account button should be present', async ({
|
||||
page,
|
||||
baseURL,
|
||||
}) => {
|
||||
const loginPage = `${baseURL}${ROUTES.LOGIN}`;
|
||||
|
||||
// find button which has text=Create an account
|
||||
const button = page.locator('text=Create an account');
|
||||
|
||||
expect(button).toBeVisible();
|
||||
expect(button).toHaveText('Create an account');
|
||||
expect(await button.getAttribute('disabled')).toBe(null);
|
||||
|
||||
expect(await button.isEnabled()).toBe(true);
|
||||
await expect(page).toHaveURL(loginPage);
|
||||
});
|
||||
|
||||
test('Version of the application when api returns 200', async ({ page }) => {
|
||||
// Click text=SigNoz ${version}
|
||||
const element = page.locator(`text=SigNoz ${version}`);
|
||||
element.isVisible();
|
||||
const text = await element.innerText();
|
||||
expect(text).toBe(`SigNoz ${version}`);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
});
|
Before Width: | Height: | Size: 46 KiB |
@ -1,32 +0,0 @@
|
||||
import { expect, Page, test } from '@playwright/test';
|
||||
import ROUTES from 'constants/routes';
|
||||
|
||||
import { loginApi } from '../fixtures/common';
|
||||
|
||||
let page: Page;
|
||||
|
||||
test.describe('Service 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('Serice Page is rendered', async ({ baseURL }) => {
|
||||
await expect(page).toHaveURL(`${baseURL}${ROUTES.APPLICATION}`);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Logged In must be true', async () => {
|
||||
const { app } = await page.evaluate(() => window.store.getState());
|
||||
|
||||
const { isLoggedIn } = app;
|
||||
|
||||
expect(isLoggedIn).toBe(true);
|
||||
});
|
||||
});
|
Before Width: | Height: | Size: 40 KiB |
@ -1,150 +0,0 @@
|
||||
import { expect, Page, test } from '@playwright/test';
|
||||
import ROUTES from 'constants/routes';
|
||||
|
||||
import servicesSuccessResponse from '../fixtures/api/services/200.json';
|
||||
import { loginApi } from '../fixtures/common';
|
||||
import { SERVICE_TABLE_HEADERS } from './utils';
|
||||
|
||||
let page: Page;
|
||||
|
||||
test.describe('Service flow', () => {
|
||||
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('Services empty page', async ({ baseURL }) => {
|
||||
// visit services page
|
||||
await page.goto(`${baseURL}${ROUTES.APPLICATION}`);
|
||||
|
||||
await page.route(`**/services`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
json: [],
|
||||
}),
|
||||
);
|
||||
|
||||
// expect noData to be present
|
||||
await expect(page.getByText('No data')).toBeVisible();
|
||||
});
|
||||
|
||||
test('Services table and service details page rendered with correct data', async ({
|
||||
baseURL,
|
||||
}) => {
|
||||
// visit services page
|
||||
await page.goto(`${baseURL}${ROUTES.APPLICATION}`);
|
||||
|
||||
// assert the URL of the services page
|
||||
await expect(page).toHaveURL(`${baseURL}${ROUTES.APPLICATION}`);
|
||||
|
||||
// mock the services list call to return non-empty data
|
||||
await page.route(`**/services`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
json: servicesSuccessResponse,
|
||||
}),
|
||||
);
|
||||
|
||||
// assert the presence of services breadcrumbs
|
||||
const breadcrumbServicesText = await page
|
||||
.locator('.ant-breadcrumb-link a[href="/services"]')
|
||||
.nth(1)
|
||||
.textContent();
|
||||
await expect(breadcrumbServicesText).toEqual('Services');
|
||||
|
||||
// expect the services headers to be loaded correctly
|
||||
const p99Latency = page.locator(
|
||||
`th:has-text("${SERVICE_TABLE_HEADERS.P99LATENCY}")`,
|
||||
);
|
||||
|
||||
await expect(p99Latency).toBeVisible();
|
||||
const errorRate = await page.locator(
|
||||
`th:has-text("${SERVICE_TABLE_HEADERS.ERROR_RATE}")`,
|
||||
);
|
||||
|
||||
await expect(errorRate).toBeVisible();
|
||||
const operationsPerSecond = await page.locator(
|
||||
`th:has-text("${SERVICE_TABLE_HEADERS.OPS_PER_SECOND}")`,
|
||||
);
|
||||
|
||||
await expect(operationsPerSecond).toBeVisible();
|
||||
|
||||
// expect services to be listed in the table
|
||||
const redisService = await page
|
||||
.locator('a[href="/services/redis"]')
|
||||
.isVisible();
|
||||
|
||||
expect(redisService).toBeTruthy();
|
||||
|
||||
// route to a service details page
|
||||
await page.locator('a[href="/services/redis"]').click();
|
||||
|
||||
// wait for the network calls to be settled
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// render the overview tab
|
||||
await page.getByRole('tab', { name: 'Overview' }).click();
|
||||
|
||||
// check the presence of different graphs on the overview tab
|
||||
const latencyGraph = await page
|
||||
.locator('[data-testid="service_latency"]')
|
||||
.isVisible();
|
||||
|
||||
expect(latencyGraph).toBeTruthy();
|
||||
|
||||
const rateOps = await page
|
||||
.locator('[data-testid="operations_per_sec"]')
|
||||
.isVisible();
|
||||
|
||||
expect(rateOps).toBeTruthy();
|
||||
|
||||
const errorPercentage = await page
|
||||
.locator('[data-testid="error_percentage_%"]')
|
||||
.isVisible();
|
||||
|
||||
expect(errorPercentage).toBeTruthy();
|
||||
|
||||
// navigate to the DB call metrics and validate the tables
|
||||
await page.getByRole('tab', { name: 'DB Call Metrics' }).click();
|
||||
|
||||
const databaseCallRps = await page
|
||||
.locator('[data-testid="database_call_rps"]')
|
||||
.isVisible();
|
||||
expect(databaseCallRps).toBeTruthy();
|
||||
|
||||
const databaseCallsAvgDuration = await page
|
||||
.locator('[data-testid="database_call_avg_duration"]')
|
||||
.isVisible();
|
||||
expect(databaseCallsAvgDuration).toBeTruthy();
|
||||
|
||||
// navigate to external metrics and validate the tables
|
||||
|
||||
await page.getByRole('tab', { name: 'External Metrics' }).click();
|
||||
|
||||
const externalCallErrorPerc = await page
|
||||
.locator('[data-testid="external_call_error_percentage"]')
|
||||
.isVisible();
|
||||
expect(externalCallErrorPerc).toBeTruthy();
|
||||
|
||||
const externalCallDuration = await page
|
||||
.locator('[data-testid="external_call_duration"]')
|
||||
.isVisible();
|
||||
expect(externalCallDuration).toBeTruthy();
|
||||
|
||||
const externalCallRps = await page
|
||||
.locator('[data-testid="external_call_rps_by_address"]')
|
||||
.isVisible();
|
||||
expect(externalCallRps).toBeTruthy();
|
||||
|
||||
const externalCallDurationByAddress = await page
|
||||
.locator('[data-testid="external_call_duration_by_address"]')
|
||||
.isVisible();
|
||||
expect(externalCallDurationByAddress).toBeTruthy();
|
||||
});
|
||||
});
|
@ -1,6 +0,0 @@
|
||||
export const SERVICE_TABLE_HEADERS = {
|
||||
APPLICATION: 'Applicaton',
|
||||
P99LATENCY: 'P99 latency (in ms)',
|
||||
ERROR_RATE: 'Error Rate (% of total)',
|
||||
OPS_PER_SECOND: 'Operations Per Second',
|
||||
};
|
@ -1,232 +0,0 @@
|
||||
import { expect, Page, PlaywrightTestOptions, test } from '@playwright/test';
|
||||
import ROUTES from 'constants/routes';
|
||||
|
||||
import { loginApi, waitForVersionApiSuccess } from '../fixtures/common';
|
||||
import {
|
||||
confirmPasswordSelector,
|
||||
getStartedButtonSelector,
|
||||
validCompanyName,
|
||||
validemail,
|
||||
validName,
|
||||
validPassword,
|
||||
} from '../fixtures/constant';
|
||||
|
||||
const waitForSignUpPageSuccess = async (
|
||||
baseURL: PlaywrightTestOptions['baseURL'],
|
||||
page: Page,
|
||||
): Promise<void> => {
|
||||
const signupPage = `${baseURL}${ROUTES.SIGN_UP}`;
|
||||
|
||||
await page.goto(signupPage);
|
||||
|
||||
await waitForVersionApiSuccess(page);
|
||||
};
|
||||
|
||||
interface FillDetailsInSignUpFormProps {
|
||||
page: Page;
|
||||
email: string;
|
||||
name: string;
|
||||
companyName: string;
|
||||
password: string;
|
||||
confirmPassword: string;
|
||||
}
|
||||
|
||||
const fillDetailsInSignUpForm = async ({
|
||||
page,
|
||||
email,
|
||||
name,
|
||||
companyName,
|
||||
password,
|
||||
confirmPassword,
|
||||
}: FillDetailsInSignUpFormProps): Promise<void> => {
|
||||
const emailplaceholder = '[placeholder="name\\@yourcompany\\.com"]';
|
||||
const nameplaceholder = '[placeholder="Your Name"]';
|
||||
const companyPlaceholder = '[placeholder="Your Company"]';
|
||||
const currentPasswordId = '#currentPassword';
|
||||
const confirmPasswordId = '#confirmPassword';
|
||||
|
||||
// Fill [placeholder="name\@yourcompany\.com"]
|
||||
await page.locator(emailplaceholder).fill(email);
|
||||
|
||||
// Fill [placeholder="Your Name"]
|
||||
await page.locator(nameplaceholder).fill(name);
|
||||
|
||||
// Fill [placeholder="Your Company"]
|
||||
await page.locator(companyPlaceholder).fill(companyName);
|
||||
|
||||
// Fill #currentPassword
|
||||
await page.locator(currentPasswordId).fill(password);
|
||||
|
||||
// Fill #confirmPasswordId
|
||||
await page.locator(confirmPasswordId).fill(confirmPassword);
|
||||
};
|
||||
|
||||
test.describe('Sign Up Page', () => {
|
||||
test('When User successfull signup and logged in, he should be redirected to dashboard', async ({
|
||||
page,
|
||||
baseURL,
|
||||
}) => {
|
||||
const loginPage = `${baseURL}${ROUTES.LOGIN}`;
|
||||
|
||||
await waitForVersionApiSuccess(page);
|
||||
|
||||
await Promise.all([page.goto(loginPage), page.waitForRequest('**/version')]);
|
||||
|
||||
const buttonSignupButton = page.locator('text=Create an account');
|
||||
|
||||
await buttonSignupButton.click();
|
||||
|
||||
expect(page).toHaveURL(`${baseURL}${ROUTES.SIGN_UP}`);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Invite link validation', async ({ baseURL, page }) => {
|
||||
await waitForSignUpPageSuccess(baseURL, page);
|
||||
const message =
|
||||
'This will create an admin account. If you are not an admin, please ask your admin for an invite link';
|
||||
|
||||
const messageText = await page.locator(`text=${message}`).innerText();
|
||||
|
||||
expect(messageText).toBe(message);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('User Sign up with valid details', async ({ baseURL, page, context }) => {
|
||||
await waitForSignUpPageSuccess(baseURL, page);
|
||||
|
||||
const gettingStartedButton = page.locator(getStartedButtonSelector);
|
||||
|
||||
expect(await gettingStartedButton.isDisabled()).toBe(true);
|
||||
|
||||
await fillDetailsInSignUpForm({
|
||||
companyName: validCompanyName,
|
||||
confirmPassword: validPassword,
|
||||
email: validemail,
|
||||
name: validName,
|
||||
page,
|
||||
password: validPassword,
|
||||
});
|
||||
|
||||
// password validation message is not present
|
||||
const locator = await page.locator(confirmPasswordSelector).isVisible();
|
||||
expect(locator).toBe(false);
|
||||
|
||||
const buttonText = await gettingStartedButton.evaluate((e) => e.innerHTML);
|
||||
|
||||
expect(buttonText).toMatch(/Get Started/i);
|
||||
|
||||
// Getting Started button is not disabled
|
||||
expect(await gettingStartedButton.isDisabled()).toBe(false);
|
||||
|
||||
await loginApi(page);
|
||||
|
||||
await gettingStartedButton.click();
|
||||
|
||||
await expect(page).toHaveURL(`${baseURL}${ROUTES.APPLICATION}`);
|
||||
|
||||
await context.storageState({
|
||||
path: 'tests/auth.json',
|
||||
});
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Empty name with valid details', async ({ baseURL, page }) => {
|
||||
await waitForSignUpPageSuccess(baseURL, page);
|
||||
|
||||
await fillDetailsInSignUpForm({
|
||||
companyName: validCompanyName,
|
||||
confirmPassword: validPassword,
|
||||
email: validemail,
|
||||
name: '',
|
||||
page,
|
||||
password: validPassword,
|
||||
});
|
||||
|
||||
const gettingStartedButton = page.locator(getStartedButtonSelector);
|
||||
|
||||
expect(await gettingStartedButton.isDisabled()).toBe(true);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Empty Company name with valid details', async ({ baseURL, page }) => {
|
||||
await waitForSignUpPageSuccess(baseURL, page);
|
||||
|
||||
await fillDetailsInSignUpForm({
|
||||
companyName: '',
|
||||
confirmPassword: validPassword,
|
||||
email: validemail,
|
||||
name: validName,
|
||||
page,
|
||||
password: validPassword,
|
||||
});
|
||||
|
||||
const gettingStartedButton = page.locator(getStartedButtonSelector);
|
||||
|
||||
expect(await gettingStartedButton.isDisabled()).toBe(true);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Empty Email with valid details', async ({ baseURL, page }) => {
|
||||
await waitForSignUpPageSuccess(baseURL, page);
|
||||
|
||||
await fillDetailsInSignUpForm({
|
||||
companyName: validCompanyName,
|
||||
confirmPassword: validPassword,
|
||||
email: '',
|
||||
name: validName,
|
||||
page,
|
||||
password: validPassword,
|
||||
});
|
||||
|
||||
const gettingStartedButton = page.locator(getStartedButtonSelector);
|
||||
|
||||
expect(await gettingStartedButton.isDisabled()).toBe(true);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Empty Password and confirm password with valid details', async ({
|
||||
baseURL,
|
||||
page,
|
||||
}) => {
|
||||
await waitForSignUpPageSuccess(baseURL, page);
|
||||
|
||||
await fillDetailsInSignUpForm({
|
||||
companyName: validCompanyName,
|
||||
confirmPassword: '',
|
||||
email: validemail,
|
||||
name: validName,
|
||||
page,
|
||||
password: '',
|
||||
});
|
||||
|
||||
const gettingStartedButton = page.locator(getStartedButtonSelector);
|
||||
|
||||
expect(await gettingStartedButton.isDisabled()).toBe(true);
|
||||
|
||||
// password validation message is not present
|
||||
const locator = await page.locator(confirmPasswordSelector).isVisible();
|
||||
expect(locator).toBe(false);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Miss Match Password and confirm password with valid details', async ({
|
||||
baseURL,
|
||||
page,
|
||||
}) => {
|
||||
await waitForSignUpPageSuccess(baseURL, page);
|
||||
|
||||
await fillDetailsInSignUpForm({
|
||||
companyName: validCompanyName,
|
||||
confirmPassword: validPassword,
|
||||
email: validemail,
|
||||
name: validName,
|
||||
page,
|
||||
password: '',
|
||||
});
|
||||
|
||||
// password validation message is not present
|
||||
const locator = await page.locator(confirmPasswordSelector).isVisible();
|
||||
expect(locator).toBe(true);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
});
|
Before Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 70 KiB |
@ -1,118 +0,0 @@
|
||||
import { Page, test, expect } from '@playwright/test';
|
||||
import { loginApi } from '../fixtures/common';
|
||||
import ROUTES from 'constants/routes';
|
||||
import queryRangeSuccessResponse from '../fixtures/api/traces/queryRange200.json';
|
||||
import tracesSuccessResponse from '../fixtures/api/traces/tracesRange200.json';
|
||||
import tracesTableSuccessResponse from '../fixtures/api/traces/tracesTableView200.json';
|
||||
import {
|
||||
defaultAttributeKeysData,
|
||||
httpMethodAttributeID,
|
||||
newExplorerCtaID,
|
||||
queryRangeApiEndpoint,
|
||||
saveNewViewID,
|
||||
saveNewViewWithNameID,
|
||||
serviceAttributeID,
|
||||
tableViewTabID,
|
||||
traceExplorerViewsGetEndpoint,
|
||||
traceExplorerViewsPostEndpoint,
|
||||
traceRowTraceTabID,
|
||||
traceTabID,
|
||||
tracesExplorerQueryData,
|
||||
tracesExplorerViewsData,
|
||||
tracesExplorerViewsPostData,
|
||||
} from './utils';
|
||||
|
||||
let page: Page;
|
||||
|
||||
test.describe('New Traces Explorer', () => {
|
||||
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('Traces Explorer Tests', async ({}) => {
|
||||
await page.locator(`li[data-menu-id*="/trace"]`).click();
|
||||
|
||||
await tracesExplorerQueryData(page, queryRangeSuccessResponse);
|
||||
|
||||
await defaultAttributeKeysData(page);
|
||||
|
||||
const queryRangeRequest = page.waitForRequest(`**/${queryRangeApiEndpoint}`);
|
||||
|
||||
await page.locator(`data-testid=${newExplorerCtaID}`).click();
|
||||
|
||||
await queryRangeRequest;
|
||||
|
||||
await page.getByText('List View').click();
|
||||
|
||||
const serviceName = await page
|
||||
.locator(`data-testid=${serviceAttributeID}`)
|
||||
.textContent();
|
||||
|
||||
expect(serviceName).toBe('route');
|
||||
|
||||
const httpMethod = await page
|
||||
.locator(`data-testid=${httpMethodAttributeID}`)
|
||||
.textContent();
|
||||
|
||||
expect(httpMethod).toBe('GET');
|
||||
|
||||
await tracesExplorerQueryData(page, tracesSuccessResponse);
|
||||
|
||||
await page.locator(`id=${traceTabID}`).click();
|
||||
|
||||
const traceID = await page
|
||||
.locator(`data-testid=${traceRowTraceTabID}`)
|
||||
.textContent();
|
||||
|
||||
expect(traceID).toBe(
|
||||
tracesSuccessResponse.data.result[0].list[0].data.traceID,
|
||||
);
|
||||
|
||||
await tracesExplorerQueryData(page, tracesTableSuccessResponse);
|
||||
|
||||
await page.locator(`id=${tableViewTabID}`).click();
|
||||
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
const count = await page.getByText('85784').isVisible();
|
||||
|
||||
await expect(count).toBeTruthy();
|
||||
|
||||
await page.locator(`data-testid=${saveNewViewID}`).click();
|
||||
|
||||
await page.locator('id=viewName').type('Playwright');
|
||||
|
||||
await tracesExplorerQueryData(page, queryRangeSuccessResponse);
|
||||
|
||||
await tracesExplorerViewsData(page);
|
||||
|
||||
await tracesExplorerViewsPostData(page);
|
||||
|
||||
const viewsSaveRequest = page.waitForRequest(
|
||||
`**/${traceExplorerViewsPostEndpoint}`,
|
||||
);
|
||||
|
||||
const viewsGetRequest = page.waitForRequest(
|
||||
`**/${traceExplorerViewsGetEndpoint}`,
|
||||
);
|
||||
|
||||
await page.locator(`data-testid=${saveNewViewWithNameID}`).click();
|
||||
|
||||
await viewsSaveRequest;
|
||||
|
||||
await viewsGetRequest;
|
||||
|
||||
const viewName = await page.getByText('Playwright').isVisible();
|
||||
|
||||
await expect(viewName).toBeTruthy();
|
||||
});
|
||||
});
|
@ -1,116 +0,0 @@
|
||||
import { Page } from '@playwright/test';
|
||||
|
||||
import attributeKeyDurationNanoSuccessResponse from '../fixtures/api/traces/attributeKeysDurationNano200.json';
|
||||
import attributeKeyHttpMethodSuccessResponse from '../fixtures/api/traces/attributeKeysHttpMethod200.json';
|
||||
import attributeKeyNameSuccessResponse from '../fixtures/api/traces/attributeKeysName200.json';
|
||||
import attributeKeyResponseStatusCodeSuccessResponse from '../fixtures/api/traces/attributeKeysResponseStatusCode200.json';
|
||||
import attributeKeyServiceNameSuccessResponse from '../fixtures/api/traces/attributeKeysServiceName200.json';
|
||||
import traceExplorerViewsPostSuccessResponse from '../fixtures/api/traces/traceExplorerViewPost200.json';
|
||||
import traceExplorerViewsSuccessResponse from '../fixtures/api/traces/traceExplorerViews200.json';
|
||||
import { JsonApplicationType } from '../fixtures/constant';
|
||||
|
||||
export const queryRangeApiEndpoint = 'query_range';
|
||||
export const attributeKeysApiEndpoint = 'autocomplete/attribute_keys';
|
||||
export const traceExplorerViewsGetEndpoint = 'explorer/views?sourcePage=traces';
|
||||
export const traceExplorerViewsPostEndpoint = 'explorer/views';
|
||||
|
||||
export const newExplorerCtaID = 'newExplorerCTA';
|
||||
export const serviceAttributeID = 'serviceName';
|
||||
export const httpMethodAttributeID = 'httpMethod';
|
||||
export const traceTabID = 'rc-tabs-0-tab-trace';
|
||||
export const traceRowTraceTabID = 'trace-id';
|
||||
export const tableViewTabID = 'rc-tabs-0-tab-table';
|
||||
export const saveNewViewID = 'traces-save-view-action';
|
||||
export const saveNewViewWithNameID = 'save-view-name-action-button';
|
||||
|
||||
const DefaultAttributesExplorerPage = [
|
||||
'serviceName',
|
||||
'name',
|
||||
'durationNano',
|
||||
'httpMethod',
|
||||
'responseStatusCode',
|
||||
];
|
||||
|
||||
export const tracesExplorerQueryData = async (
|
||||
page: Page,
|
||||
response: any,
|
||||
): Promise<void> => {
|
||||
await page.route(`**/${queryRangeApiEndpoint}`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: JsonApplicationType,
|
||||
json: response,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
export const tracesExplorerViewsData = async (page: Page): Promise<void> => {
|
||||
await page.route(`**/${traceExplorerViewsGetEndpoint}`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: JsonApplicationType,
|
||||
json: traceExplorerViewsSuccessResponse,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
export const tracesExplorerViewsPostData = async (
|
||||
page: Page,
|
||||
): Promise<void> => {
|
||||
await page.route(`**/${traceExplorerViewsPostEndpoint}`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: JsonApplicationType,
|
||||
json: traceExplorerViewsPostSuccessResponse,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
function getAttributeResponseBySearchTerm(
|
||||
searchTerm: string,
|
||||
): Record<string, unknown> {
|
||||
if (searchTerm) {
|
||||
switch (searchTerm) {
|
||||
case 'sericeName':
|
||||
return attributeKeyServiceNameSuccessResponse;
|
||||
|
||||
case 'name':
|
||||
return attributeKeyNameSuccessResponse;
|
||||
|
||||
case 'durationNano':
|
||||
return attributeKeyDurationNanoSuccessResponse;
|
||||
|
||||
case 'httpMethod':
|
||||
return attributeKeyResponseStatusCodeSuccessResponse;
|
||||
|
||||
case 'responseStatusCode':
|
||||
return attributeKeyHttpMethodSuccessResponse;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
export const getAttributeKeysData = async (
|
||||
page: Page,
|
||||
searchTerm: string,
|
||||
): Promise<void> => {
|
||||
await page.route(
|
||||
`**/${attributeKeysApiEndpoint}?**searchText=${searchTerm}**`,
|
||||
(route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
json: getAttributeResponseBySearchTerm(searchTerm),
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
export const defaultAttributeKeysData = async (page: Page): Promise<void> => {
|
||||
await Promise.all([
|
||||
...DefaultAttributesExplorerPage.map((att) =>
|
||||
getAttributeKeysData(page, att),
|
||||
),
|
||||
]);
|
||||
};
|
@ -42,8 +42,6 @@
|
||||
"./__mocks__",
|
||||
"./conf/default.conf",
|
||||
"./public",
|
||||
"./tests",
|
||||
"./playwright.config.ts",
|
||||
"./commitlint.config.ts",
|
||||
"./webpack.config.js",
|
||||
"./webpack.config.prod.js",
|
||||
|
@ -3170,16 +3170,6 @@
|
||||
resolved "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.8.0.tgz"
|
||||
integrity sha512-AhVAm6SQ+zgxIiOzwVdUcDmKlu/qU39FiYD2UD6kQQaVenrn0dGZewIghWAENGQsvC+1avLCuT+T2/3Gsp/W3w==
|
||||
|
||||
"@playwright/test@^1.22.0":
|
||||
version "1.33.0"
|
||||
resolved "https://registry.npmjs.org/@playwright/test/-/test-1.33.0.tgz"
|
||||
integrity sha512-YunBa2mE7Hq4CfPkGzQRK916a4tuZoVx/EpLjeWlTVOnD4S2+fdaQZE0LJkbfhN5FTSKNLdcl7MoT5XB37bTkg==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
playwright-core "1.33.0"
|
||||
optionalDependencies:
|
||||
fsevents "2.3.2"
|
||||
|
||||
"@polka/url@^1.0.0-next.20":
|
||||
version "1.0.0-next.21"
|
||||
resolved "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz"
|
||||
@ -9145,7 +9135,7 @@ fscreen@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/fscreen/-/fscreen-1.2.0.tgz#1a8c88e06bc16a07b473ad96196fb06d6657f59e"
|
||||
integrity sha512-hlq4+BU0hlPmwsFjwGGzZ+OZ9N/wq9Ljg/sq3pX+2CD7hrJsX9tJgWWK/wiNTFM212CLHWhicOoqwXyZGGetJg==
|
||||
|
||||
fsevents@2.3.2, fsevents@^2.3.2, fsevents@~2.3.2:
|
||||
fsevents@^2.3.2, fsevents@~2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz"
|
||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||
@ -13839,11 +13829,6 @@ pkg-dir@^7.0.0:
|
||||
dependencies:
|
||||
find-up "^6.3.0"
|
||||
|
||||
playwright-core@1.33.0:
|
||||
version "1.33.0"
|
||||
resolved "https://registry.npmjs.org/playwright-core/-/playwright-core-1.33.0.tgz"
|
||||
integrity sha512-aizyPE1Cj62vAECdph1iaMILpT0WUDCq3E6rW6I+dleSbBoGbktvJtzS6VHkZ4DKNEOG9qJpiom/ZxO+S15LAw==
|
||||
|
||||
pngquant-bin@^6.0.0:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/pngquant-bin/-/pngquant-bin-6.0.1.tgz#2b5789ca219eeb4d8509ab1ae082092801b7f07e"
|
||||
|