mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-26 09:55:52 +00:00
playwright: migrate custom metric spec (#16690)
* playwright: migrate custom metric spec * fixed customMetric failure
This commit is contained in:
parent
8ef1ab1ff8
commit
f7a7529461
@ -1,341 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {
|
||||
interceptURL,
|
||||
toastNotification,
|
||||
verifyResponseStatusCode,
|
||||
} from '../../common/common';
|
||||
import { createEntityTable, hardDeleteService } from '../../common/EntityUtils';
|
||||
import { visitEntityDetailsPage } from '../../common/Utils/Entity';
|
||||
import { getToken } from '../../common/Utils/LocalStorage';
|
||||
import {
|
||||
INVALID_NAMES,
|
||||
NAME_MIN_MAX_LENGTH_VALIDATION_ERROR_1_128,
|
||||
NAME_VALIDATION_ERROR,
|
||||
uuid,
|
||||
} from '../../constants/constants';
|
||||
import { EntityType } from '../../constants/Entity.interface';
|
||||
import { DATABASE_SERVICE } from '../../constants/EntityConstant';
|
||||
import { SERVICE_CATEGORIES } from '../../constants/service.constants';
|
||||
|
||||
const TABLE_CUSTOM_METRIC = {
|
||||
name: `tableCustomMetric-${uuid()}`,
|
||||
expression: `SELECT * FROM ${DATABASE_SERVICE.entity.name}`,
|
||||
};
|
||||
const COLUMN_CUSTOM_METRIC = {
|
||||
name: `tableCustomMetric-${uuid()}`,
|
||||
column: DATABASE_SERVICE.entity.columns[0].name,
|
||||
expression: `SELECT * FROM ${DATABASE_SERVICE.entity.name}`,
|
||||
};
|
||||
|
||||
const validateForm = (isColumnMetric = false) => {
|
||||
// error messages
|
||||
cy.get('#name_help').scrollIntoView().should('contain', 'Name is required');
|
||||
|
||||
cy.get('#expression_help')
|
||||
.scrollIntoView()
|
||||
.should('contain', 'SQL Query is required');
|
||||
if (isColumnMetric) {
|
||||
cy.get('#columnName_help')
|
||||
.scrollIntoView()
|
||||
.should('contain', 'Column is required');
|
||||
}
|
||||
|
||||
// max length validation
|
||||
cy.get('#name').scrollIntoView().type(INVALID_NAMES.MAX_LENGTH);
|
||||
cy.get('#name_help').should(
|
||||
'contain',
|
||||
NAME_MIN_MAX_LENGTH_VALIDATION_ERROR_1_128
|
||||
);
|
||||
|
||||
// with special char validation
|
||||
cy.get('#name')
|
||||
.should('be.visible')
|
||||
.clear()
|
||||
.type(INVALID_NAMES.WITH_SPECIAL_CHARS);
|
||||
cy.get('#name_help').should('contain', NAME_VALIDATION_ERROR);
|
||||
cy.get('#name').clear();
|
||||
};
|
||||
|
||||
type CustomMetricDetails = {
|
||||
term: string;
|
||||
serviceName: string;
|
||||
entity: EntityType.Table;
|
||||
isColumnMetric?: boolean;
|
||||
metric: {
|
||||
name: string;
|
||||
column?: string;
|
||||
expression: string;
|
||||
};
|
||||
};
|
||||
|
||||
const createCustomMetric = ({
|
||||
term,
|
||||
serviceName,
|
||||
entity,
|
||||
isColumnMetric = false,
|
||||
metric,
|
||||
}: CustomMetricDetails) => {
|
||||
interceptURL('PUT', '/api/v1/tables/*/customMetric', 'createCustomMetric');
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/tables/name/*?fields=customMetrics%2Ccolumns&include=all',
|
||||
'getCustomMetric'
|
||||
);
|
||||
visitEntityDetailsPage({
|
||||
term,
|
||||
serviceName,
|
||||
entity,
|
||||
});
|
||||
// Click on create custom metric button
|
||||
cy.get('[data-testid="profiler"]').click();
|
||||
|
||||
verifyResponseStatusCode('@getCustomMetric', 200);
|
||||
cy.get('[data-testid="profiler-tab-left-panel"]')
|
||||
.contains(isColumnMetric ? 'Column Profile' : 'Table Profile')
|
||||
.click();
|
||||
|
||||
cy.get('[data-testid="profiler-add-table-test-btn"]').click();
|
||||
cy.get('[data-testid="custom-metric"]').click();
|
||||
|
||||
// validate redirection and cancel button
|
||||
cy.get('[data-testid="heading"]').first().should('be.visible');
|
||||
cy.get(
|
||||
`[data-testid=${
|
||||
isColumnMetric
|
||||
? 'profiler-tab-container'
|
||||
: 'table-profiler-chart-container'
|
||||
}]`
|
||||
).should('be.visible');
|
||||
cy.get('[data-testid="cancel-button"]').click();
|
||||
verifyResponseStatusCode('@getCustomMetric', 200);
|
||||
cy.url().should('include', 'profiler');
|
||||
cy.get('[data-testid="heading"]')
|
||||
.first()
|
||||
.invoke('text')
|
||||
.should('equal', isColumnMetric ? 'Column Profile' : 'Table Profile');
|
||||
|
||||
// Click on create custom metric button
|
||||
cy.get('[data-testid="profiler-add-table-test-btn"]').click();
|
||||
cy.get('[data-testid="custom-metric"]').click();
|
||||
cy.get('[data-testid="submit-button"]').click();
|
||||
|
||||
validateForm(isColumnMetric);
|
||||
|
||||
// fill form and submit
|
||||
cy.get('#name').type(metric.name);
|
||||
if (isColumnMetric) {
|
||||
cy.get('#columnName').click();
|
||||
cy.get(`[title="${metric.column}"]`).click();
|
||||
}
|
||||
metric.expression &&
|
||||
cy.get('.CodeMirror-scroll').click().type(metric.expression);
|
||||
cy.get('[data-testid="submit-button"]').click();
|
||||
verifyResponseStatusCode('@createCustomMetric', 200);
|
||||
toastNotification(`${metric.name} created successfully.`);
|
||||
verifyResponseStatusCode('@getCustomMetric', 200);
|
||||
|
||||
// verify the created custom metric
|
||||
cy.url().should('include', 'profiler');
|
||||
cy.get('[data-testid="heading"]')
|
||||
.first()
|
||||
.invoke('text')
|
||||
.should('equal', isColumnMetric ? 'Column Profile' : 'Table Profile');
|
||||
cy.get(`[data-testid="${metric.name}-custom-metrics"]`)
|
||||
.scrollIntoView()
|
||||
.should('be.visible');
|
||||
};
|
||||
|
||||
const editCustomMetric = ({
|
||||
term,
|
||||
serviceName,
|
||||
entity,
|
||||
isColumnMetric = false,
|
||||
metric,
|
||||
}: CustomMetricDetails) => {
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/tables/name/*?fields=customMetrics%2Ccolumns&include=all',
|
||||
'getCustomMetric'
|
||||
);
|
||||
interceptURL('PUT', '/api/v1/tables/*/customMetric', 'editCustomMetric');
|
||||
visitEntityDetailsPage({
|
||||
term,
|
||||
serviceName,
|
||||
entity,
|
||||
});
|
||||
cy.get('[data-testid="profiler"]').click();
|
||||
|
||||
verifyResponseStatusCode('@getCustomMetric', 200);
|
||||
cy.get('[data-testid="profiler-tab-left-panel"]')
|
||||
.contains(isColumnMetric ? 'Column Profile' : 'Table Profile')
|
||||
.click();
|
||||
if (isColumnMetric) {
|
||||
metric.column &&
|
||||
cy.get('[data-row-key="user_id"]').contains(metric.column).click();
|
||||
}
|
||||
cy.get(`[data-testid="${metric.name}-custom-metrics"]`)
|
||||
.scrollIntoView()
|
||||
.should('be.visible');
|
||||
cy.get(`[data-testid="${metric.name}-custom-metrics-menu"]`).click();
|
||||
cy.get(`[data-menu-id*="edit"]`).click();
|
||||
|
||||
// validate cancel button
|
||||
cy.get('.ant-modal-content').should('be.visible');
|
||||
cy.get('.ant-modal-footer').contains('Cancel').click();
|
||||
cy.get('.ant-modal-content').should('not.exist');
|
||||
|
||||
// edit expression and submit
|
||||
cy.get(`[data-testid="${metric.name}-custom-metrics-menu"]`).click();
|
||||
cy.get(`[data-menu-id*="edit"]`).click();
|
||||
cy.get('.CodeMirror-scroll').click().type('updated');
|
||||
cy.get('.ant-modal-footer').contains('Save').click();
|
||||
cy.wait('@editCustomMetric').then(({ request }) => {
|
||||
expect(request.body.expression).to.have.string('updated');
|
||||
});
|
||||
toastNotification(`${metric.name} updated successfully.`);
|
||||
};
|
||||
const deleteCustomMetric = ({
|
||||
term,
|
||||
serviceName,
|
||||
entity,
|
||||
metric,
|
||||
isColumnMetric = false,
|
||||
}: CustomMetricDetails) => {
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/tables/name/*?fields=customMetrics%2Ccolumns&include=all',
|
||||
'getCustomMetric'
|
||||
);
|
||||
interceptURL(
|
||||
'DELETE',
|
||||
isColumnMetric
|
||||
? `/api/v1/tables/*/customMetric/${metric.column}/${metric.name}*`
|
||||
: `/api/v1/tables/*/customMetric/${metric.name}*`,
|
||||
'deleteCustomMetric'
|
||||
);
|
||||
visitEntityDetailsPage({
|
||||
term,
|
||||
serviceName,
|
||||
entity,
|
||||
});
|
||||
cy.get('[data-testid="profiler"]').click();
|
||||
|
||||
verifyResponseStatusCode('@getCustomMetric', 200);
|
||||
cy.get('[data-testid="profiler-tab-left-panel"]')
|
||||
.contains(isColumnMetric ? 'Column Profile' : 'Table Profile')
|
||||
.click();
|
||||
if (isColumnMetric) {
|
||||
metric.column &&
|
||||
cy.get('[data-row-key="user_id"]').contains(metric.column).click();
|
||||
}
|
||||
cy.get(`[data-testid="${metric.name}-custom-metrics"]`)
|
||||
.scrollIntoView()
|
||||
.should('be.visible');
|
||||
cy.get(`[data-testid="${metric.name}-custom-metrics-menu"]`).click();
|
||||
cy.get(`[data-menu-id*="delete"]`).click();
|
||||
cy.get('.ant-modal-header').should('contain', metric.name);
|
||||
cy.get('[data-testid="confirmation-text-input"]').type('DELETE');
|
||||
cy.get('[data-testid="confirm-button"]').click();
|
||||
verifyResponseStatusCode('@deleteCustomMetric', 200);
|
||||
toastNotification(`"${metric.name}" deleted successfully!`);
|
||||
};
|
||||
|
||||
describe('Custom Metric', { tags: 'Observability' }, () => {
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.getAllLocalStorage().then((data) => {
|
||||
const token = getToken(data);
|
||||
|
||||
createEntityTable({
|
||||
token,
|
||||
...DATABASE_SERVICE,
|
||||
tables: [DATABASE_SERVICE.entity],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.login();
|
||||
cy.getAllLocalStorage().then((data) => {
|
||||
const token = getToken(data);
|
||||
|
||||
hardDeleteService({
|
||||
token,
|
||||
serviceFqn: DATABASE_SERVICE.service.name,
|
||||
serviceType: SERVICE_CATEGORIES.DATABASE_SERVICES,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('Create table custom metric', () => {
|
||||
createCustomMetric({
|
||||
term: DATABASE_SERVICE.entity.name,
|
||||
serviceName: DATABASE_SERVICE.service.name,
|
||||
entity: EntityType.Table,
|
||||
metric: TABLE_CUSTOM_METRIC,
|
||||
});
|
||||
});
|
||||
|
||||
it("Edit table custom metric's expression", () => {
|
||||
editCustomMetric({
|
||||
term: DATABASE_SERVICE.entity.name,
|
||||
serviceName: DATABASE_SERVICE.service.name,
|
||||
entity: EntityType.Table,
|
||||
metric: TABLE_CUSTOM_METRIC,
|
||||
});
|
||||
});
|
||||
|
||||
it('Delete table custom metric', () => {
|
||||
deleteCustomMetric({
|
||||
term: DATABASE_SERVICE.entity.name,
|
||||
serviceName: DATABASE_SERVICE.service.name,
|
||||
entity: EntityType.Table,
|
||||
metric: TABLE_CUSTOM_METRIC,
|
||||
});
|
||||
});
|
||||
|
||||
it('Create column custom metric', () => {
|
||||
createCustomMetric({
|
||||
term: DATABASE_SERVICE.entity.name,
|
||||
serviceName: DATABASE_SERVICE.service.name,
|
||||
entity: EntityType.Table,
|
||||
metric: COLUMN_CUSTOM_METRIC,
|
||||
isColumnMetric: true,
|
||||
});
|
||||
});
|
||||
|
||||
it("Edit column custom metric's expression", () => {
|
||||
editCustomMetric({
|
||||
term: DATABASE_SERVICE.entity.name,
|
||||
serviceName: DATABASE_SERVICE.service.name,
|
||||
entity: EntityType.Table,
|
||||
metric: COLUMN_CUSTOM_METRIC,
|
||||
isColumnMetric: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('Delete column custom metric', () => {
|
||||
deleteCustomMetric({
|
||||
term: DATABASE_SERVICE.entity.name,
|
||||
serviceName: DATABASE_SERVICE.service.name,
|
||||
entity: EntityType.Table,
|
||||
metric: COLUMN_CUSTOM_METRIC,
|
||||
isColumnMetric: true,
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export const TAG_INVALID_NAMES = {
|
||||
MIN_LENGTH: 'c',
|
||||
MAX_LENGTH: 'a87439625b1c2d3e4f5061728394a5b6c7d8e90a1b2c3d4e5f67890ab',
|
||||
WITH_SPECIAL_CHARS: '!@#$%^&*()',
|
||||
};
|
||||
|
||||
export const INVALID_NAMES = {
|
||||
MAX_LENGTH:
|
||||
'a87439625b1c2d3e4f5061728394a5b6c7d8e90a1b2c3d4e5f67890aba87439625b1c2d3e4f5061728394a5b6c7d8e90a1b2c3d4e5f67890abName can be a maximum of 128 characters',
|
||||
WITH_SPECIAL_CHARS: '::normalName::',
|
||||
};
|
||||
|
||||
export const NAME_VALIDATION_ERROR =
|
||||
'Name must contain only letters, numbers, underscores, hyphens, periods, parenthesis, and ampersands.';
|
||||
|
||||
export const NAME_MIN_MAX_LENGTH_VALIDATION_ERROR =
|
||||
'Name size must be between 2 and 64';
|
||||
|
||||
export const NAME_MAX_LENGTH_VALIDATION_ERROR =
|
||||
'Name size must be between 1 and 128';
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import test from '@playwright/test';
|
||||
import { TableClass } from '../../support/entity/TableClass';
|
||||
import { getApiContext, redirectToHomePage, uuid } from '../../utils/common';
|
||||
import {
|
||||
createCustomMetric,
|
||||
deleteCustomMetric,
|
||||
} from '../../utils/customMetric';
|
||||
|
||||
// use the admin user to login
|
||||
test.use({ storageState: 'playwright/.auth/admin.json' });
|
||||
|
||||
test('Table custom metric', async ({ page }) => {
|
||||
const table = new TableClass();
|
||||
await redirectToHomePage(page);
|
||||
const { afterAction, apiContext } = await getApiContext(page);
|
||||
await table.create(apiContext);
|
||||
|
||||
const TABLE_CUSTOM_METRIC = {
|
||||
name: `tableCustomMetric-${uuid()}`,
|
||||
expression: `SELECT * FROM ${table.entity.name}`,
|
||||
};
|
||||
|
||||
await test.step('Create', async () => {
|
||||
const profilerResponse = page.waitForResponse(
|
||||
`/api/v1/tables/${table.entityResponseData?.['fullyQualifiedName']}/tableProfile/latest`
|
||||
);
|
||||
await table.visitEntityPage(page);
|
||||
await page.click('[data-testid="profiler"]');
|
||||
await profilerResponse;
|
||||
await page.waitForTimeout(1000);
|
||||
await createCustomMetric({
|
||||
page,
|
||||
metric: TABLE_CUSTOM_METRIC,
|
||||
});
|
||||
});
|
||||
|
||||
await test.step('Delete', async () => {
|
||||
await deleteCustomMetric({
|
||||
page,
|
||||
metric: TABLE_CUSTOM_METRIC,
|
||||
});
|
||||
});
|
||||
|
||||
await table.delete(apiContext);
|
||||
await afterAction();
|
||||
});
|
||||
|
||||
test('Column custom metric', async ({ page }) => {
|
||||
const table = new TableClass();
|
||||
await redirectToHomePage(page);
|
||||
const { afterAction, apiContext } = await getApiContext(page);
|
||||
await table.create(apiContext);
|
||||
|
||||
const COLUMN_CUSTOM_METRIC = {
|
||||
name: `columnCustomMetric-${uuid()}`,
|
||||
column: table.entity.columns[0].name,
|
||||
expression: `SELECT * FROM ${table.entity.name}`,
|
||||
};
|
||||
|
||||
await test.step('Create', async () => {
|
||||
const profilerResponse = page.waitForResponse(
|
||||
`/api/v1/tables/${table.entityResponseData?.['fullyQualifiedName']}/tableProfile/latest`
|
||||
);
|
||||
await table.visitEntityPage(page);
|
||||
await page.click('[data-testid="profiler"]');
|
||||
await profilerResponse;
|
||||
await page.waitForTimeout(1000);
|
||||
await createCustomMetric({
|
||||
page,
|
||||
metric: COLUMN_CUSTOM_METRIC,
|
||||
isColumnMetric: true,
|
||||
});
|
||||
});
|
||||
|
||||
await test.step('Delete', async () => {
|
||||
await deleteCustomMetric({
|
||||
page,
|
||||
metric: COLUMN_CUSTOM_METRIC,
|
||||
isColumnMetric: true,
|
||||
});
|
||||
});
|
||||
|
||||
await table.delete(apiContext);
|
||||
await afterAction();
|
||||
});
|
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { expect, Page } from '@playwright/test';
|
||||
import {
|
||||
INVALID_NAMES,
|
||||
NAME_MAX_LENGTH_VALIDATION_ERROR,
|
||||
NAME_VALIDATION_ERROR,
|
||||
} from '../constant/common';
|
||||
|
||||
type CustomMetricDetails = {
|
||||
page: Page;
|
||||
isColumnMetric?: boolean;
|
||||
metric: {
|
||||
name: string;
|
||||
column?: string;
|
||||
expression: string;
|
||||
};
|
||||
};
|
||||
|
||||
const validateForm = async (page: Page, isColumnMetric = false) => {
|
||||
// error messages
|
||||
await expect(page.locator('#name_help')).toHaveText('Name is required');
|
||||
|
||||
await expect(page.locator('#expression_help')).toHaveText(
|
||||
'SQL Query is required.'
|
||||
);
|
||||
|
||||
if (isColumnMetric) {
|
||||
await expect(page.locator('#columnName_help')).toHaveText(
|
||||
'Column is required.'
|
||||
);
|
||||
}
|
||||
|
||||
// max length validation
|
||||
await page.locator('#name').fill(INVALID_NAMES.MAX_LENGTH);
|
||||
|
||||
await expect(page.locator('#name_help')).toHaveText(
|
||||
NAME_MAX_LENGTH_VALIDATION_ERROR
|
||||
);
|
||||
|
||||
// with special char validation
|
||||
await page.locator('#name').fill(INVALID_NAMES.WITH_SPECIAL_CHARS);
|
||||
|
||||
await expect(page.locator('#name_help')).toHaveText(NAME_VALIDATION_ERROR);
|
||||
|
||||
await page.locator('#name').clear();
|
||||
};
|
||||
|
||||
export const createCustomMetric = async ({
|
||||
page,
|
||||
isColumnMetric = false,
|
||||
metric,
|
||||
}: CustomMetricDetails) => {
|
||||
await page
|
||||
.getByRole('menuitem', {
|
||||
name: isColumnMetric ? 'Column Profile' : 'Table Profile',
|
||||
})
|
||||
.click();
|
||||
await page.locator('[data-testid="profiler-add-table-test-btn"]').click();
|
||||
await page.locator('[data-testid="custom-metric"]').click();
|
||||
|
||||
const customMetricResponse = page.waitForResponse(
|
||||
'/api/v1/tables/name/*?fields=customMetrics%2Ccolumns&include=all'
|
||||
);
|
||||
|
||||
// validate redirection and cancel button
|
||||
await expect(page.locator('[data-testid="heading"]')).toBeVisible();
|
||||
await expect(
|
||||
page.locator(
|
||||
`[data-testid="${
|
||||
isColumnMetric
|
||||
? 'profiler-tab-container'
|
||||
: 'table-profiler-chart-container'
|
||||
}"]`
|
||||
)
|
||||
).toBeVisible();
|
||||
|
||||
await page.locator('[data-testid="cancel-button"]').click();
|
||||
await customMetricResponse;
|
||||
|
||||
await expect(page).toHaveURL(/profiler/);
|
||||
await expect(
|
||||
page.getByRole('heading', {
|
||||
name: isColumnMetric ? 'Column Profile' : 'Table Profile',
|
||||
})
|
||||
).toBeVisible();
|
||||
|
||||
// Click on create custom metric button
|
||||
await page.click('[data-testid="profiler-add-table-test-btn"]');
|
||||
await page.click('[data-testid="custom-metric"]');
|
||||
await page.click('[data-testid="submit-button"]');
|
||||
|
||||
await validateForm(page, isColumnMetric);
|
||||
|
||||
// fill form and submit
|
||||
await page.fill('#name', metric.name);
|
||||
if (isColumnMetric) {
|
||||
await page.click('#columnName');
|
||||
await page.click(`[title="${metric.column}"]`);
|
||||
}
|
||||
if (metric.expression) {
|
||||
await page.click('.CodeMirror-scroll');
|
||||
await page.keyboard.type(metric.expression);
|
||||
}
|
||||
const createMetricResponse = page.waitForResponse(
|
||||
'/api/v1/tables/*/customMetric'
|
||||
);
|
||||
await page.click('[data-testid="submit-button"]');
|
||||
await createMetricResponse;
|
||||
|
||||
await expect(page.locator('.Toastify__toast-body')).toHaveText(
|
||||
new RegExp(`${metric.name} created successfully.`)
|
||||
);
|
||||
|
||||
await page.locator('.Toastify__close-button').click();
|
||||
|
||||
// verify the created custom metric
|
||||
await expect(page).toHaveURL(/profiler/);
|
||||
await expect(
|
||||
page.getByRole('heading', {
|
||||
name: isColumnMetric ? 'Column Profile' : 'Table Profile',
|
||||
})
|
||||
).toBeVisible();
|
||||
|
||||
await expect(
|
||||
page.locator(`[data-testid="${metric.name}-custom-metrics"]`)
|
||||
).toBeVisible();
|
||||
};
|
||||
|
||||
export const deleteCustomMetric = async ({
|
||||
page,
|
||||
metric,
|
||||
isColumnMetric = false,
|
||||
}) => {
|
||||
await page
|
||||
.locator(`[data-testid="${metric.name}-custom-metrics"]`)
|
||||
.scrollIntoViewIfNeeded();
|
||||
|
||||
await expect(
|
||||
page.locator(`[data-testid="${metric.name}-custom-metrics"]`)
|
||||
).toBeVisible();
|
||||
|
||||
await page.click(`[data-testid="${metric.name}-custom-metrics-menu"]`);
|
||||
await page.click(`[data-menu-id*="delete"]`);
|
||||
|
||||
await expect(page.locator('.ant-modal-header')).toContainText(metric.name);
|
||||
|
||||
await page.fill('[data-testid="confirmation-text-input"]', 'DELETE');
|
||||
const deleteMetricResponse = page.waitForResponse(
|
||||
isColumnMetric
|
||||
? `/api/v1/tables/*/customMetric/${metric.column}/${metric.name}*`
|
||||
: `/api/v1/tables/*/customMetric/${metric.name}*`
|
||||
);
|
||||
await page.click('[data-testid="confirm-button"]');
|
||||
await deleteMetricResponse;
|
||||
|
||||
// Verifying the deletion
|
||||
await expect(page.getByRole('alert').first()).toHaveText(
|
||||
`"${metric.name}" deleted successfully!`
|
||||
);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user