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/node_modules/
|
||||||
e2e/test-results/
|
e2e/test-results/
|
||||||
e2e/playwright-report/
|
|
||||||
e2e/blob-report/
|
e2e/blob-report/
|
||||||
e2e/playwright/.cache/
|
|
||||||
e2e/.auth
|
e2e/.auth
|
||||||
|
|
||||||
# go
|
# go
|
||||||
|
@ -3,5 +3,4 @@ BUNDLE_ANALYSER="true"
|
|||||||
FRONTEND_API_ENDPOINT="http://localhost:8080/"
|
FRONTEND_API_ENDPOINT="http://localhost:8080/"
|
||||||
INTERCOM_APP_ID="intercom-app-id"
|
INTERCOM_APP_ID="intercom-app-id"
|
||||||
|
|
||||||
PLAYWRIGHT_TEST_BASE_URL="http://localhost:8080"
|
|
||||||
CI="1"
|
CI="1"
|
@ -30,11 +30,6 @@ const config: Config.InitialOptions = {
|
|||||||
testPathIgnorePatterns: ['/node_modules/', '/public/'],
|
testPathIgnorePatterns: ['/node_modules/', '/public/'],
|
||||||
moduleDirectories: ['node_modules', 'src'],
|
moduleDirectories: ['node_modules', 'src'],
|
||||||
testEnvironment: 'jest-environment-jsdom',
|
testEnvironment: 'jest-environment-jsdom',
|
||||||
testEnvironmentOptions: {
|
|
||||||
'jest-playwright': {
|
|
||||||
browsers: ['chromium', 'firefox', 'webkit'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
coverageThreshold: {
|
coverageThreshold: {
|
||||||
global: {
|
global: {
|
||||||
statements: 80,
|
statements: 80,
|
||||||
|
@ -15,10 +15,6 @@
|
|||||||
"jest:coverage": "jest --coverage",
|
"jest:coverage": "jest --coverage",
|
||||||
"jest:watch": "jest --watch",
|
"jest:watch": "jest --watch",
|
||||||
"postinstall": "yarn i18n:generate-hash && (is-ci || yarn husky:configure)",
|
"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/*",
|
"husky:configure": "cd .. && husky install frontend/.husky && cd frontend && chmod ug+x .husky/*",
|
||||||
"commitlint": "commitlint --edit $1",
|
"commitlint": "commitlint --edit $1",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
@ -164,7 +160,6 @@
|
|||||||
"@commitlint/config-conventional": "^16.2.4",
|
"@commitlint/config-conventional": "^16.2.4",
|
||||||
"@faker-js/faker": "9.3.0",
|
"@faker-js/faker": "9.3.0",
|
||||||
"@jest/globals": "^27.5.1",
|
"@jest/globals": "^27.5.1",
|
||||||
"@playwright/test": "^1.22.0",
|
|
||||||
"@testing-library/jest-dom": "5.16.5",
|
"@testing-library/jest-dom": "5.16.5",
|
||||||
"@testing-library/react": "13.4.0",
|
"@testing-library/react": "13.4.0",
|
||||||
"@testing-library/user-event": "14.4.3",
|
"@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
|
# create temporary tsconfig which includes only passed files
|
||||||
str="{
|
str="{
|
||||||
\"extends\": \"./tsconfig.json\",
|
\"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
|
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__",
|
"./__mocks__",
|
||||||
"./conf/default.conf",
|
"./conf/default.conf",
|
||||||
"./public",
|
"./public",
|
||||||
"./tests",
|
|
||||||
"./playwright.config.ts",
|
|
||||||
"./commitlint.config.ts",
|
"./commitlint.config.ts",
|
||||||
"./webpack.config.js",
|
"./webpack.config.js",
|
||||||
"./webpack.config.prod.js",
|
"./webpack.config.prod.js",
|
||||||
|
@ -3170,16 +3170,6 @@
|
|||||||
resolved "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.8.0.tgz"
|
resolved "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.8.0.tgz"
|
||||||
integrity sha512-AhVAm6SQ+zgxIiOzwVdUcDmKlu/qU39FiYD2UD6kQQaVenrn0dGZewIghWAENGQsvC+1avLCuT+T2/3Gsp/W3w==
|
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":
|
"@polka/url@^1.0.0-next.20":
|
||||||
version "1.0.0-next.21"
|
version "1.0.0-next.21"
|
||||||
resolved "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz"
|
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"
|
resolved "https://registry.yarnpkg.com/fscreen/-/fscreen-1.2.0.tgz#1a8c88e06bc16a07b473ad96196fb06d6657f59e"
|
||||||
integrity sha512-hlq4+BU0hlPmwsFjwGGzZ+OZ9N/wq9Ljg/sq3pX+2CD7hrJsX9tJgWWK/wiNTFM212CLHWhicOoqwXyZGGetJg==
|
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"
|
version "2.3.2"
|
||||||
resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz"
|
resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz"
|
||||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||||
@ -13839,11 +13829,6 @@ pkg-dir@^7.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
find-up "^6.3.0"
|
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:
|
pngquant-bin@^6.0.0:
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/pngquant-bin/-/pngquant-bin-6.0.1.tgz#2b5789ca219eeb4d8509ab1ae082092801b7f07e"
|
resolved "https://registry.yarnpkg.com/pngquant-bin/-/pngquant-bin-6.0.1.tgz#2b5789ca219eeb4d8509ab1ae082092801b7f07e"
|
||||||
|