mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-01 19:18:05 +00:00
test: migrate recently viewed spec to playwright (#17741)
(cherry picked from commit 8568eaf65318a954cc34d471c3035d7f8bc6e7a6)
This commit is contained in:
parent
83079606e4
commit
cee82c86eb
@ -1,141 +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, verifyResponseStatusCode } from '../../common/common';
|
||||
import {
|
||||
createEntityTable,
|
||||
createSingleLevelEntity,
|
||||
hardDeleteService,
|
||||
} from '../../common/EntityUtils';
|
||||
import { visitEntityDetailsPage } from '../../common/Utils/Entity';
|
||||
import { getToken } from '../../common/Utils/LocalStorage';
|
||||
import {
|
||||
DATABASE_SERVICE,
|
||||
SINGLE_LEVEL_SERVICE,
|
||||
STORED_PROCEDURE_DETAILS,
|
||||
VISIT_ENTITIES_DATA,
|
||||
} from '../../constants/EntityConstant';
|
||||
import { SERVICE_CATEGORIES } from '../../constants/service.constants';
|
||||
|
||||
// Update list if we support this for other entities too
|
||||
const RECENTLY_VIEW_ENTITIES = [
|
||||
VISIT_ENTITIES_DATA.table,
|
||||
VISIT_ENTITIES_DATA.dashboard,
|
||||
VISIT_ENTITIES_DATA.topic,
|
||||
VISIT_ENTITIES_DATA.pipeline,
|
||||
VISIT_ENTITIES_DATA.mlmodel,
|
||||
// ES issue
|
||||
// VISIT_ENTITIES_DATA.storedProcedure,
|
||||
];
|
||||
|
||||
describe('Recently viwed data assets', { tags: 'DataAssets' }, () => {
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.getAllLocalStorage().then((data) => {
|
||||
const token = getToken(data);
|
||||
|
||||
createEntityTable({
|
||||
token,
|
||||
...DATABASE_SERVICE,
|
||||
tables: [DATABASE_SERVICE.entity],
|
||||
});
|
||||
SINGLE_LEVEL_SERVICE.forEach((data) => {
|
||||
createSingleLevelEntity({
|
||||
token,
|
||||
...data,
|
||||
entity: [data.entity],
|
||||
});
|
||||
});
|
||||
|
||||
// creating stored procedure
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `/api/v1/storedProcedures`,
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
body: STORED_PROCEDURE_DETAILS,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.login();
|
||||
cy.getAllLocalStorage().then((data) => {
|
||||
const token = getToken(data);
|
||||
|
||||
hardDeleteService({
|
||||
token,
|
||||
serviceFqn: DATABASE_SERVICE.service.name,
|
||||
serviceType: SERVICE_CATEGORIES.DATABASE_SERVICES,
|
||||
});
|
||||
SINGLE_LEVEL_SERVICE.forEach((data) => {
|
||||
hardDeleteService({
|
||||
token,
|
||||
serviceFqn: data.service.name,
|
||||
serviceType: data.serviceType,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('recently view section should be present', () => {
|
||||
cy.get('[data-testid="recently-viewed-widget"]')
|
||||
.scrollIntoView()
|
||||
.should('be.visible');
|
||||
|
||||
cy.get(
|
||||
`[data-testid="recently-viewed-widget"] .right-panel-list-item`
|
||||
).should('have.length', 0);
|
||||
});
|
||||
|
||||
it(`recently view section should have at max list of 5 entity`, () => {
|
||||
RECENTLY_VIEW_ENTITIES.map((entity, index) => {
|
||||
visitEntityDetailsPage({
|
||||
term: entity.term,
|
||||
serviceName: entity.serviceName,
|
||||
entity: entity.entity,
|
||||
});
|
||||
cy.get('[data-testid="entity-header-display-name"]').should(
|
||||
'contain',
|
||||
entity.term
|
||||
);
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/feed?type=Announcement&activeAnnouncement=true',
|
||||
'getAnnouncements'
|
||||
);
|
||||
|
||||
cy.clickOnLogo();
|
||||
verifyResponseStatusCode('@getAnnouncements', 200);
|
||||
|
||||
// need to add manual wait as we are dependant on local storage for recently view data
|
||||
cy.wait(500);
|
||||
cy.get('[data-testid="recently-viewed-widget"]')
|
||||
.scrollIntoView()
|
||||
.should('be.visible');
|
||||
cy.get(
|
||||
`[data-testid="recently-viewed-widget"] [title="${entity.displayName}"]`,
|
||||
{ timeout: 10000 }
|
||||
)
|
||||
.scrollIntoView()
|
||||
.should('be.visible');
|
||||
|
||||
// Checking count since we will only show max 5 not more than that
|
||||
cy.get(
|
||||
`[data-testid="recently-viewed-widget"] .right-panel-list-item`
|
||||
).should('have.length', index + 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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, test } from '@playwright/test';
|
||||
import { ApiEndpointClass } from '../../support/entity/ApiEndpointClass';
|
||||
import { ContainerClass } from '../../support/entity/ContainerClass';
|
||||
import { DashboardClass } from '../../support/entity/DashboardClass';
|
||||
import { DashboardDataModelClass } from '../../support/entity/DashboardDataModelClass';
|
||||
import { MlModelClass } from '../../support/entity/MlModelClass';
|
||||
import { PipelineClass } from '../../support/entity/PipelineClass';
|
||||
import { SearchIndexClass } from '../../support/entity/SearchIndexClass';
|
||||
import { StoredProcedureClass } from '../../support/entity/StoredProcedureClass';
|
||||
import { TableClass } from '../../support/entity/TableClass';
|
||||
import { TopicClass } from '../../support/entity/TopicClass';
|
||||
import { createNewPage, redirectToHomePage } from '../../utils/common';
|
||||
|
||||
const entities = [
|
||||
new ApiEndpointClass(),
|
||||
new TableClass(),
|
||||
new StoredProcedureClass(),
|
||||
new DashboardClass(),
|
||||
new PipelineClass(),
|
||||
new TopicClass(),
|
||||
new MlModelClass(),
|
||||
new ContainerClass(),
|
||||
new SearchIndexClass(),
|
||||
new DashboardDataModelClass(),
|
||||
] as const;
|
||||
|
||||
// use the admin user to login
|
||||
test.use({ storageState: 'playwright/.auth/admin.json' });
|
||||
|
||||
test.describe('Recently viewed data assets', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await redirectToHomePage(page);
|
||||
});
|
||||
|
||||
test.beforeAll(async ({ browser }) => {
|
||||
const { afterAction, apiContext } = await createNewPage(browser);
|
||||
for await (const entity of entities) {
|
||||
await entity.create(apiContext);
|
||||
}
|
||||
await afterAction();
|
||||
});
|
||||
|
||||
test.afterAll(async ({ browser }) => {
|
||||
const { afterAction, apiContext } = await createNewPage(browser);
|
||||
for await (const entity of entities) {
|
||||
await entity.delete(apiContext);
|
||||
}
|
||||
await afterAction();
|
||||
});
|
||||
|
||||
test('Recently viewed widget should be visible on the home page', async ({
|
||||
page,
|
||||
}) => {
|
||||
test.slow(true);
|
||||
|
||||
for await (const entity of entities) {
|
||||
await test.step(
|
||||
`Check ${entity.getType()} in recently viewed widget `,
|
||||
async () => {
|
||||
await entity.visitEntityPage(page);
|
||||
|
||||
await page.waitForSelector(`[data-testid="breadcrumb"]`);
|
||||
|
||||
await redirectToHomePage(page);
|
||||
|
||||
await page.waitForSelector(`[data-testid="recently-viewed-widget"]`);
|
||||
|
||||
const selector = `[data-testid="recently-viewed-widget"] [title="${entity.entity.name}"]`;
|
||||
|
||||
await expect(page.locator(selector)).toBeVisible();
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -19,6 +19,7 @@ import { EntityTypeEndpoint } from './Entity.interface';
|
||||
import { EntityClass } from './EntityClass';
|
||||
|
||||
export class ContainerClass extends EntityClass {
|
||||
private containerName = `pw-container-${uuid()}`;
|
||||
service = {
|
||||
name: `pw-storage-service-${uuid()}`,
|
||||
serviceType: 'S3',
|
||||
@ -36,8 +37,8 @@ export class ContainerClass extends EntityClass {
|
||||
},
|
||||
};
|
||||
entity = {
|
||||
name: `pw-container-${uuid()}`,
|
||||
displayName: `pw-container-${uuid()}`,
|
||||
name: this.containerName,
|
||||
displayName: this.containerName,
|
||||
service: this.service.name,
|
||||
};
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ import { EntityTypeEndpoint } from './Entity.interface';
|
||||
import { EntityClass } from './EntityClass';
|
||||
|
||||
export class DashboardClass extends EntityClass {
|
||||
private dashboardName = `pw-dashboard-${uuid()}`;
|
||||
service = {
|
||||
name: `pw-dashboard-service-${uuid()}`,
|
||||
serviceType: 'Superset',
|
||||
@ -41,8 +42,8 @@ export class DashboardClass extends EntityClass {
|
||||
service: this.service.name,
|
||||
};
|
||||
entity = {
|
||||
name: `pw-dashboard-${uuid()}`,
|
||||
displayName: `pw-dashboard-${uuid()}`,
|
||||
name: this.dashboardName,
|
||||
displayName: this.dashboardName,
|
||||
service: this.service.name,
|
||||
};
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ import { EntityTypeEndpoint } from './Entity.interface';
|
||||
import { EntityClass } from './EntityClass';
|
||||
|
||||
export class DashboardDataModelClass extends EntityClass {
|
||||
private dashboardDataModelName = `pw-dashboard-data-model-${uuid()}`;
|
||||
service = {
|
||||
name: `pw-dashboard-service-${uuid()}`,
|
||||
serviceType: 'Superset',
|
||||
@ -47,8 +48,8 @@ export class DashboardDataModelClass extends EntityClass {
|
||||
];
|
||||
|
||||
entity = {
|
||||
name: `pw-dashboard-data-model-${uuid()}`,
|
||||
displayName: `pw-dashboard-data-model-${uuid()}`,
|
||||
name: this.dashboardDataModelName,
|
||||
displayName: this.dashboardDataModelName,
|
||||
service: this.service.name,
|
||||
columns: this.children,
|
||||
dataModelType: 'SupersetDataModel',
|
||||
|
||||
@ -27,6 +27,7 @@ type ResponseDataType = {
|
||||
};
|
||||
|
||||
export class MlModelClass extends EntityClass {
|
||||
private mlModelName = `pw-mlmodel-${uuid()}`;
|
||||
service = {
|
||||
name: `pw-ml-model-service-${uuid()}`,
|
||||
serviceType: 'Mlflow',
|
||||
@ -49,8 +50,8 @@ export class MlModelClass extends EntityClass {
|
||||
];
|
||||
|
||||
entity = {
|
||||
name: `pw-mlmodel-${uuid()}`,
|
||||
displayName: `pw-mlmodel-${uuid()}`,
|
||||
name: this.mlModelName,
|
||||
displayName: this.mlModelName,
|
||||
service: this.service.name,
|
||||
algorithm: 'Time Series',
|
||||
mlFeatures: this.children,
|
||||
|
||||
@ -19,6 +19,7 @@ import { EntityTypeEndpoint } from './Entity.interface';
|
||||
import { EntityClass } from './EntityClass';
|
||||
|
||||
export class PipelineClass extends EntityClass {
|
||||
private pipelineName = `pw-pipeline-${uuid()}`;
|
||||
service = {
|
||||
name: `pw-pipeline-service-${uuid()}`,
|
||||
serviceType: 'Dagster',
|
||||
@ -36,8 +37,8 @@ export class PipelineClass extends EntityClass {
|
||||
children = [{ name: 'snowflake_task' }];
|
||||
|
||||
entity = {
|
||||
name: `pw-pipeline-${uuid()}`,
|
||||
displayName: `pw-pipeline-${uuid()}`,
|
||||
name: this.pipelineName,
|
||||
displayName: this.pipelineName,
|
||||
service: this.service.name,
|
||||
tasks: this.children,
|
||||
};
|
||||
|
||||
@ -85,7 +85,7 @@ export class SearchIndexClass extends EntityClass {
|
||||
|
||||
entity = {
|
||||
name: this.searchIndexName,
|
||||
displayName: `pw-search-index-${uuid()}`,
|
||||
displayName: this.searchIndexName,
|
||||
service: this.service.name,
|
||||
fields: this.children,
|
||||
};
|
||||
|
||||
@ -37,7 +37,7 @@ import {
|
||||
} from '../../context/PermissionProvider/PermissionProvider.interface';
|
||||
import { ClientErrors } from '../../enums/Axios.enum';
|
||||
import { ERROR_PLACEHOLDER_TYPE } from '../../enums/common.enum';
|
||||
import { TabSpecificField } from '../../enums/entity.enum';
|
||||
import { EntityType, TabSpecificField } from '../../enums/entity.enum';
|
||||
import { CreateThread } from '../../generated/api/feed/createThread';
|
||||
import { Tag } from '../../generated/entity/classification/tag';
|
||||
import { DashboardDataModel } from '../../generated/entity/data/dashboardDataModel';
|
||||
@ -53,10 +53,12 @@ import {
|
||||
} from '../../rest/dataModelsAPI';
|
||||
import { postThread } from '../../rest/feedsAPI';
|
||||
import {
|
||||
addToRecentViewed,
|
||||
getEntityMissingError,
|
||||
sortTagsCaseInsensitive,
|
||||
} from '../../utils/CommonUtils';
|
||||
import { getSortedDataModelColumnTags } from '../../utils/DataModelsUtils';
|
||||
import { getEntityName } from '../../utils/EntityUtils';
|
||||
import { DEFAULT_ENTITY_PERMISSION } from '../../utils/PermissionsUtils';
|
||||
import { getTierTags } from '../../utils/TableUtils';
|
||||
import { updateTierTag } from '../../utils/TagsUtils';
|
||||
@ -134,6 +136,15 @@ const DataModelsPage = () => {
|
||||
include: Include.All,
|
||||
});
|
||||
setDataModelData(response);
|
||||
|
||||
addToRecentViewed({
|
||||
displayName: getEntityName(response),
|
||||
entityType: EntityType.DASHBOARD_DATA_MODEL,
|
||||
fqn: response.fullyQualifiedName ?? '',
|
||||
serviceType: response.serviceType,
|
||||
timestamp: 0,
|
||||
id: response.id,
|
||||
});
|
||||
} catch (error) {
|
||||
showErrorToast(error as AxiosError);
|
||||
setHasError(true);
|
||||
|
||||
@ -125,6 +125,7 @@ jest.mock('../../rest/feedsAPI', () => ({
|
||||
}));
|
||||
|
||||
jest.mock('../../utils/CommonUtils', () => ({
|
||||
addToRecentViewed: jest.fn(),
|
||||
getEntityMissingError: jest.fn(() => ENTITY_MISSING_ERROR),
|
||||
sortTagsCaseInsensitive: jest.fn((tags) => tags),
|
||||
}));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user